今日知识

1. AOP
2. AspectJ
3. JdbcTemplate

AOP

1. AOP :Aspect Oriented Programming,意为面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
1. 好处
* 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
* AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码
* 经典应用:事务管理,性能监视,安全检查,缓存,日志。
* SpringAOP使用纯的java实现,不需要专门的编译过程和类加载器,在运行期通过代理方式向目标类织入增强代码
* AspectJ是一个基于Java语言的AOP框架,Spring2.0开始,Spring AOP引入对Aspect的支持,AspectJ扩展了Java语言,提供了一个专门的编译器,在编译时提供横向代码的织入
2. AOP实现原理
1. AOP底层将采用代理机制进行实现
2. 接口+实现类:Spring采用jdk的动态代理Proxy
3. 实现类:Spring采用cglib字节码增强
3. AOP术语
1. target:目标类,需要被代理的类。例如:UserService
2. Joinpoint(连接点):所谓连接点是指那些可能被拦截到的方法。例如:所有的方法
3. PointCut 切入点:已经被增强的连接点。例如:addUser()
4. advice 通知/增强,增强代码。例如:after、before
5. Weaving(织入):是指把增强advice应用到目标对象target来创建新的代理对象proxy的过程.
6. proxy 代理类
7. Aspect(切面): 是切入点pointcut和通知advice的结合
一个线是一个特殊的面。
一个切入点和一个通知,组成成一个特殊的面。
4. 手动代理
1. JDK动态代理
* 和原来的方法一样
2. cglib增强字节码
1. 导入jar包:
2. 没有接口,只有实现类。
//cglib代理
@Test
public void test2(){
final UserService1 userService=new UserService1(); UserService1 proxy = (UserService1) Enhancer.create(UserService1.class, new InvocationHandler() {
public Object invoke(Object o, Method method, Object[] objects) throws Throwable { System.out.println("开启事务");
Object invoke = method.invoke(userService, objects);
System.out.println("提交事务");
return invoke;
}
}); proxy.addUser();
}
5. Spring编写代理半自动
1. jar
2. 目标类
* public class UserService1 {
public void addUser() {
System.out.println("添加用户");
}
}
3. 切面类
* public class MyAspect2 implements MethodInterceptor{
public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("开启事务");
Object invoke = mi.proceed();
System.out.println("提交事务");
return invoke;
}
}
4. spring配置
* <!--业务类-->
<bean id="userService" class="com.rqy.service.UserService1"/>
<!--切面类-->
<bean id="myAspect" class="com.rqy.aspect.MyAspect2"/>
<!--使用工厂bean创建代理-->
<bean id="proxyService" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="target" ref="userService"/>
<property name="interceptorNames" value="myAspect"/> </bean>
5. test
* @Autowired
@Qualifier("proxyService")
UserService1 userService;
@Test
public void test3(){
userService.addUser();
}
6. Spring编写代理半自动升级版(通过配置类方式,同时注解注入)
1. jar
2. 目标类
@Component("userService")
* public class UserService1 {
public void addUser() {
System.out.println("添加用户");
}
}
3. 切面类
* //注解注入
* @Component("mymethod")
* public class MyAspect2 implements MethodInterceptor{
public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("开启事务");
Object invoke = mi.proceed();
System.out.println("提交事务");
return invoke;
}
}
4. 配置类
* //告诉spring这是一个配置类
@Configuration
public class SpringConfig {
//在配置中注册组件
//注册第三方或者已经编译过得类
//如果bean里面不写,默认方法名当做bean的id
@Bean("proxyFactoryBean")
public ProxyFactoryBean proxyFactoryBean(@Qualifier("userService") UserService userService){ ProxyFactoryBean proxyFactoryBean = new ProxyFactoryBean();
proxyFactoryBean.setTarget(userService);
proxyFactoryBean.setInterceptorNames("mymethod");
return proxyFactoryBean;
}
}
5. spring配置
*<!--注解开关-->
<context:component-scan base-package="com.rqy"/>
5. test
* @RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:application.xml")
public class MyTest { @Autowired
@Qualifier("proxyFactoryBean")
UserService userService;
@Test
public void test(){
userService.addUser();
}
}

AspectJ全自动编程

1. 导包
* dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.13</version>
</dependency>
2. 切面类
public class MyAspect implements MethodInterceptor{ public Object invoke(MethodInvocation mi) throws Throwable { System.out.println("开启事务");
Object invoke = mi.proceed();
System.out.println("提交事务");
return invoke;
}
}
Spring的AOP配置
* <!--切面类-->
<bean id="myAspect" class="com.rqy.aspect.MyAspect"/>
<!--
AOp编程步骤
1. 导入命名空间
2. proxy-target-class="true" 默认使用cglib代理
3. aop:pointcut
切入点表达式:execution(* com.rqy.*.*(..))
选择方法 包 类名任意 方法名任意 参数任意
切入面:advice-ref:通知
pointcut-ref:切入点的引入
-->
<aop:config proxy-target-class="true">
<aop:pointcut id="myPointCut" expression="execution(* com.rqy.service.*.*(..))"/>
<aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"/>
</aop:config>
3. 测试
* @Autowired
@Qualifier("userService")
UserService userService;
@Test
public void test(){
userService.addUser(); }

AspectJ

1. AspectJ简介
* AspectJ是一个基于Java语言的AOP框架
* Spring2.0以后新增了AspectJ切点表达式的支持
* @AspectJ 是AspectJ1.5新增功能,通过JDK5注解技术,允许直接在Bean类中定义切面
* 新版本Spring框架,建议使用AspectJ方式来开发AOP
* 主要用途:自定义开发
2. Aspect案例讲解
1. 导包
* AOP联盟规范:aopalliance
* AOP实现:spring-aop
* 规范:aspectjweaver
* aspectj实现:spring-aspects
2. 实现类:和上面一样
3. 切面类:
* public class MyAspect2 {
public void myBefore(JoinPoint jp){
System.out.println("前置通知"+jp.getSignature().getName());//连接点的方法名
}
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知 前");
//获取切入点方法名
String name = joinPoint.getSignature().getName();
System.out.println(name);
Object proceed = joinPoint.proceed();
System.out.println("环绕通知 后");
return proceed;
}
public void myAfterReturnning(JoinPoint jp,Object e){
System.out.println("后置通知:"+e);
}
public void myAfterThrowing(JoinPoint jp,Throwable e){
System.out.println("异常通知:"+e.getMessage());
}
public void myAfter(){
System.out.println("最终通知");
}
}
4. spring配置
* <!--业务类-->
<bean id="userService" class="com.rqy.service.UserService"/>
<!--切面类-->
<bean id="myAspect" class="com.rqy.aspect.MyAspect2"/>
<!--
AOp编程步骤
1. 导入命名空间
2. proxy-target-class="true" 默认使用cglib代理
3. aop:pointcut
切入点表达式:execution(* com.rqy.*.*(..))
选择方法 包 类名任意 方法名任意 参数任意
切入面:advice-ref:通知
pointcut-ref:切入点的引入
-->
<!-- <aop:config proxy-target-class="true">
<aop:pointcut id="myPointCut" expression="execution(* com.rqy.service.*.*(..))"/>
<aop:advisor advice-ref="myAspect" pointcut-ref="myPointCut"/>
</aop:config>-->
<aop:config>
<aop:aspect ref="myAspect">
<aop:pointcut id="myPoinrCut" expression="execution(* com.rqy.service.*.*(..))"/>
<!--前置通知-->
<aop:before method="myBefore" pointcut-ref="myPoinrCut"></aop:before>
<!--环绕通知-->
<aop:around method="myAround" pointcut-ref="myPoinrCut"></aop:around>
<!--异常通知-->
<aop:after-throwing method="myAfterThrowing" pointcut-ref="myPoinrCut" throwing="e"></aop:after-throwing>
<!--后置通知,用于获取返回值-->
<aop:after-returning method="myAfterReturnning" pointcut-ref="myPoinrCut" returning="e"></aop:after-returning>
<!--最终通知 有没有异常都会走最终通知-->
<aop:after method="myAfter" pointcut-ref="myPoinrCut"></aop:after>
</aop:aspect>
</aop:config>
3. AspectJ基于xml的讲解
1. 上面的案例
4. AspectJ注解的讲解
1. @Aspect 声明切面,修饰切面类,从而获得 通知。
2. @Before 前置
3. @AfterReturning 后置
4. @Around 环绕
5. @AfterThrowing 抛出异常
6. @After 最终
7. 切入点 ,@PointCut ,修饰方法 private void xxx(){} 之后通过“方法名”获得切入点引用
8. xml需要开启 <!--aop注解生效-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
9. 案例
@Component
@Aspect
public class MyAspect3 {
//声明共用切入点
@Pointcut("execution(* com.rqy.service.*.*(..))")
public void myPointCut(){ }
@Before(value = "myPointCut()")
public void myBefore(JoinPoint jp){
System.out.println("前置通知"+jp.getSignature().getName());//连接点的方法名
} @Around(value = "myPointCut()")
public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
System.out.println("环绕通知 前");
//获取切入点方法名
String name = joinPoint.getSignature().getName();
System.out.println(name);
Object proceed = joinPoint.proceed();
System.out.println("环绕通知 后");
return proceed;
}
@AfterReturning(value = "myPointCut()",returning = "e")
public void myAfterReturnning(JoinPoint jp,Object e){
System.out.println("后置通知:"+e);
}
@AfterThrowing(value = "myPointCut()",throwing = "e")
public void myAfterThrowing(JoinPoint jp,Throwable e){
System.out.println("异常通知:"+e.getMessage());
}
@After(value = "myPointCut()")
public void myAfter(){
System.out.println("最终通知");
}
}

切入点表达式

1. 语法:execution(修饰符  返回值  包.类.方法名(参数) throws异常)
2. 修饰符,一般省略
public 公共方法
* 任意
返回值,不能省略
void 返回没有值
String 返回值字符串
* 任意
包,[省略]
com.gyf.crm 固定包
com.gyf.crm.*.service crm包下面子包任意 (例如:com.gyf.crm.staff.service)
com.gyf.crm.. crm包下面的所有子包(含自己)
com.gyf.crm.*.service.. crm包下面任意子包,固定目录service,service目录任意包
类,[省略]
UserServiceImpl 指定类
*Impl 以Impl结尾
User* 以User开头
* 任意
方法名,不能省略
addUser 固定方法
add* 以add开头
*Do 以Do结尾
* 任意
(参数)
() 无参
(int) 一个整型
(int ,int) 两个
(..) 参数任意
throws ,可省略,一般不写。
3. 案例1:
execution(* com.gyf.crm.*.service..*.*(..)) 案例2:或
<aop:pointcut expression="execution(* com.gyf.crm.service.*.*(..)) ||
execution(* com.gyf.*Do.*(..))" id="myPointCut"/>

JdbcTemplate

1. 导包
1. 数据库驱动包
2. Spring对数据库支持的两个包
* spring-jdbc-4.2.4.RELEASE
* spring-tx-4.2.4.RELEASE
3. +1连接池 c3p0 一个 (或者JDBC 两个)
* c3p0一个包
* 或者 dbcp包+pool包
2. @Test
public void test(){
//1.创建数据源
BasicDataSource dataSource=new BasicDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/spring_day04?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("123456"); //创建模板
JdbcTemplate jdbcTemplate=new JdbcTemplate(dataSource);
String sql="insert into t_user values (null,?,?)";
jdbcTemplate.update(sql,"tom","123"); }
3. xml配置的方式(DBCP)
* <!--dbcp数据源-->
<bean id="dataSource" class="org.apache.tomcat.dbcp.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/spring_day04?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="userDao" class="com.rqy.dao.impl.UserDaoImpl">
<property name="jdbcTemplate" ref="jdbcTemplate"/>
</bean>
4. xml配置的方式(C3P0)
* <!--c3p0数据源
参数不太一样
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_day04?serverTimezone=UTC"/>
<property name="user" value="root"/>
<property name="password" value="123456"/>
</bean>
5. UserDaoImpl类
* public class UserDaoImpl implements UserDao {
JdbcTemplate jdbcTemplate; public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
} public void addUser(User user) {
String sql="insert into t_user values (null,?,?)";
jdbcTemplate.update(sql,user.getUsername(),user.getPassword());
}
}
6. 使用JdbcDaoSupport(优化Bean配置)
1. 每个DAO都需要声明template 而且要写set方法。所以让DAO继承与该类,不用写这部分代码了
2. dao层变化
* public class UserDaoImpl extends JdbcDaoSupport implements UserDao {
public void addUser(User user) {
String sql="insert into t_user values (null,?,?)";
this.getJdbcTemplate().update(sql,user.getUsername(),user.getPassword());
}
}
3. xml配置的方式
* <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_day04?serverTimezone=UTC"/>
<property name="user" value="root"/>
<property name="password" value="123456"/>
</bean>
<bean id="userDao" class="com.rqy.dao.impl.UserDaoImpl">
<property name="dataSource" ref="dataSource"/>
</bean>

05-Spring02-AOP的更多相关文章

  1. 第05章 AOP细节

    第05章 AOP细节 1.切入点表达式 1.1 作用 通过表达式的方式定位一个或多个具体的连接点. 1.2 语法细节 ①切入点表达式的语法格式 execution([权限修饰符] [返回值类型] [简 ...

  2. Spring AOP学习笔记05:AOP失效的罪因

    前面的文章中我们介绍了Spring AOP的简单使用,并从源码的角度学习了其底层的实现原理,有了这些基础之后,本文来讨论一下Spring AOP失效的问题,这个问题可能我们在平时工作中或多或少也会碰到 ...

  3. Spring事务Transaction配置的五种注入方式详解

    Spring事务Transaction配置的五种注入方式详解 前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学 ...

  4. Spring框架简单介绍

    原文地址:  http://my.oschina.net/myriads/blog/37922 1.使用框架的意义与Spring的主要内容 随着软件结构的日益庞大,软件模块化趋势出现,软件开发也须要多 ...

  5. JAVAEE——spring02:使用注解配置spring、sts插件、junit整合测试和aop演示

    一.使用注解配置spring 1.步骤 1.1 导包4+2+spring-aop 1.2 为主配置文件引入新的命名空间(约束) 1.3 开启使用注解代替配置文件 1.4 在类中使用注解完成配置 2.将 ...

  6. Spring框架学习05——AOP相关术语详解

    1.Spring AOP 的基本概述 AOP(Aspect Oriented Programing)面向切面编程,AOP采取横向抽取机制,取代了传统纵向继承体系重复性代码(性能监视.事务管理.安全检查 ...

  7. spring-02

    spring-02 1.谈谈你对 Spring 的理解 Spring 是一个开源框架,为简化企业级应用开发而生.Spring 可以是使简单的 JavaBean 实现以前只有 EJB 才能实现的功能.S ...

  8. 面向切面编程AOP

    本文的主要内容(AOP): 1.AOP面向切面编程的相关概念(思想.原理.相关术语) 2.AOP编程底层实现机制(动态代理机制:JDK代理.Cglib代理) 3.Spring的传统AOP编程的案例(计 ...

  9. PostSharp AOP

    使用PostSharp 在.NET 平台上实现 AOP   摘要 本文首先介绍AOP(面向方面编程)的相关概念及理论,然后介绍如何使用PostSharp框架在.NET平台上实现AOP,最后对PostS ...

  10. Spring aop——前置增强和后置增强 使用注解Aspect和非侵入式配置

    AspectJ是一个面向切面的框架,它扩展了java语言,定义了AOP语法,能够在编译期提供代码的织入,所以它有一个专门的编译器用来生成遵守字节码字节编码规范的Class文件 确保使用jdk为5.0以 ...

随机推荐

  1. 微信授权流程和JSSDK调用流程

    概念理解 业务域名:当前业务使用的是哪个网站,好处:设置业务域名后,在微信内访问该域名下页面时,不会被重新排版.不出现“防欺诈盗号,请误支付或输入qq密码”的提示,微信认为该域名是安全的,客户也不觉得 ...

  2. 通过例子进阶学习C++(七)CMake项目通过模板库实现约瑟夫环

    本文是通过例子学习C++的第七篇,通过这个例子可以快速入门c++相关的语法. 1.问题描述 回顾一下约瑟夫环问题:n 个人围坐在一个圆桌周围,现在从第 s 个人开始报数,数到第 m 个人,让他出局:然 ...

  3. floyd + 最大流 (奶牛分配问题)

    FJ has moved his K (1 <= K <= 30) milking machines out into the cow pastures among the C (1 &l ...

  4. 2次方的期望dp

    某一天WJMZBMR在打osu~~~但是他太弱逼了,有些地方完全靠运气:(    我们来简化一下这个游戏的规则    有n次点击要做,成功了就是o,失败了就是x,分数是按comb计算的,连续a个com ...

  5. 缓存读写策略 - Cache Aside.md

    场景描述 比如一条数据同时存在数据库.缓存,现在你要更新此数据,你会怎么更新? 先更新数据库?还是先更新缓存? 其实这两种方式都有问题. (1)先更新数据库,后更新缓存 这样会造成数据不一致. A 先 ...

  6. Java入门 - 面向对象 - 07.包(package)

    原文地址:http://www.work100.net/training/java-package.html 更多教程:光束云 - 免费课程 包(package) 序号 文内章节 视频 1 概述 2 ...

  7. lisp学习总结(一)

    lisp太简单 lisp核心太简单了只有几个简单的逻辑定理,简单到你会认为他啥事都做不了. lisp语法太简单了,只有符号,参数,以及括号,组成一种万能的表达式. 由于上述lisp的简单,所以对于初学 ...

  8. 造轮子-toast组件的实现(下)

    1.解决 toast 中传入 html 的问题,通过假的 slot 来实现 // plugins.js toast.$slots.default = [message] // toast.vue &l ...

  9. python 抓一下 循环的访问也可以

    #!/usr/bin/python # -*- coding: utf-8 -*- #encoding=utf-8 #Filename:urllib2-header.py import urllib2 ...

  10. 简单实现Android手机“全局可调试”(ro.debuggable = 1)的方法【锤子坚果3】

    在Android真机上调试程序有一个前提,就是这个apk包必须有 debuggable=true 的属性才行.而除了自己开发的apk能够控制打包属性之外,其他的程序发行之后显然不会设这个值为 true ...