##spring-aop笔记整理
1, 动态代理(由于aop底层是java的动态代理,先简单介绍动态代理)
特点:字节码随用随创建,随用随加载
作用:不修改源码基础上对方法增强
分类:
基于接口的动态代理
基于子类的动态代理
1,基于子类的动态代理
涉及的类:Enhancer
提供者:第三方cglib库
如何创建代理对象:
使用Enhancer类中的create方法
创建代理对象的要求:
被代理 类不能是最终类
create方法的参数:
class:字节码(如:producers.getClass())
他是用于加载代理对象字节码
Callback,用于提供增强的代码
他是让我们写如何代理,我们一般都是些一个接口的实现类,通常情况下都是匿名内部类,但不是必须的
此接口的实现类都是谁用谁写
我们一般写的是该接口的子接口的实现类,MethodInterceptor
2,基于接口的动态代理
涉及的类:Proxy
提供者:jdk官方
如何创建代理对象:
使用Proxy类中的newProxyInstance方法
创建代理对象的要求:
被代理 类最少实现一个接口,如果没有,则不能使用
newProxyInstance方法的参数:
ClassLoader:类加载器(如:producers.getClass().getClassLoader(),)
他是用于加载代理对象字节码的,和被代理对象使用相同的类加载器,固定写法
Class[],字节码数组(如:producers.getClass().getInterfaces(),)
他是用于让代理对象和被代理对象有相同的方法,固定写法
InvocationHandler,用于提供增强的代码
他是让我们写如何代理,我们一般都是些一个接口的实现类,通常情况下都是匿名内部类,但不是必须的
此接口的实现类都是谁用谁写
2,spring-aop
1,概述:
aop即面向切面编程,通俗讲就是
把我们程序重复代码抽取出来,在需要执行的时候,运用动态代理技术,在不修改源码的情况下,对已有方法进行增强
优势:减少重复代码,提高开发效率,维护方便
2,xml的配置使用
spring中基于IOC的配置步骤
1,把通知bean也交给spring来管理
2,使用aop:config标签开始aop的配置
3,使用aop:aspect标签表明配置切面
id属性:给切面提供唯一表识
ref属性:时指定通知类的bean的id(通知是该类中的方法)
4,在aop:aspect标签内部使用对应标签来配置通知类型
(注:让printLog方法在切入点方法执行之前,所以是前置通知)
aop:before:表示配置前置通知(如前置通知的配置:<aop:before method=“printLog” pointcut="execution( *
….
(…))"></aop:before>)
method属性,用于指定Logger类中那个方法是前置通知(
注此处的前置通知只是示例,通知一共有前置通知、后置通知、异常通知、最终通知以及环绕通知)
pointcut属性:用于指定切入点表达式,该表达式的含义指的是对业务层中哪些方法增强(注:
此标签写在aop:aspect内部只能当前切面使用,它还可以写在aop:aspect外面,此时就变成了所有切面可用,
当切面通知需要使用时,只需配置
pointcut-ref属性)
切入点表达式的写法:
关键字:execution(表达式)
表达式:
访问修饰符 返回值 报名.包名.报名…类名.方法名(参数列表)
标准的表达式写法:
public void com.itheima.service.impl.AccountServiceImpl.saveAccount()
访问修饰符可以省略
void com.itheima.service.impl.AccountServiceImpl.saveAccount()
返回值可以使用通配符,并表示任意返回
com.itheima.service.impl.AccountServiceImpl.saveAccount()
报名也可以使用通配符,但是有几级包就写几个*.
*
..
..AccountServiceImpl.saveAccount()
包名可以使用…表示当前包及其子包
*
…AccountServiceImpl.saveAccount()
类名和方法名都可以使用来实现通配
*
….
()
参数列表:
可以直接写的数据类型:
基本类型直接写名称 int
引用类型写包名.类名的方式 java.lang.String
可以使用通配符来表示任意类型,但是必须有参数
可以使用…来表示有无参数均可,有参数可以是任意类型
全通配的方式:
….
(…)
实际开发中切入点表达式的通常写法:
切到业务层实现类下的所有方法
com.itheima.service.impl.
.(…)
注:环绕通知的使用和动态代理类似,也是spring提供一种可以在代码中手动控制增强方法何时执行的方式
3,注解的配置使用(
注:使用aop注解时,需要在配置文件中添加context:component-scan 以及aop:aspectj-autoproxy,第二个用来开启aop注解支持
)
1, @Pointcut(“execution(* com.itheima.service.impl.
.(…))”)--------》该注解常配置在一个方法体为空的方法上,方法名为该切入点的id(如:
@Pointcut(“execution(* com.itheima.service.impl..(…))”)
private void ptl(){}
)
2,@Before---------》前置通知,其属性需配置切入点的id
3, @AfterReturning---------》后置通知,其属性需配置切入点的id
4,@AfterThrowing---------》异常通知,其属性需配置切入点的id
5,@After---------》最终通知,其属性需配置切入点的id
6, @Around---------》环绕通知,其属性需配置切入点的id
以上注解的使用和xml配置上通知的使用类似