AOP(Aspect Orient Programming),面向切面编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理、日志、缓存等等。
AOP实现的关键在于AOP框架自动创建的AOP代理,AOP代理主要分为静态代理和动态代理:
- 静态代理的代表为,AspectJ
- 动态代理,则以Spring AOP为代表
静态代理,在编译期实现,动态代理是运行期实现。
- 静态代理,是编译阶段生成AOP代理类,也就是说生成的字节码就已织入了增强后的AOP对象;
- 动态代理,不会修改字节码,而是在内存中临时生成一个AOP对象,该AOP对象包含了目标对象的全部方法,并且在特定的切点做了增强处理,并回调原对象的方法
本文主要介绍Spring AOP的两种代理实现方式:JDK动态搭理和CGLIB动态代理
-
JDK动态搭理,通过反射来接收被代理的类,并且要求被代理的类必须实现一个接口。JDK动态代理的核心是InvocationHandler接口和Proxy类
-
如果目标类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB,是一个代码生成的类库,可以在运行时动态的生成某个类的子类。注意,CGLIB通过继承的方式实现动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的,诸如private的方法也是不可以作为切面的。
直接使用Spring AOP
- xml配置文件中需开启**<aop:aspectj-autoproxy />**
- 定义基于注解的Advice:@Aspect,@Component,@Pointcut,@Before,@Around,@After。。。
- 配置文件开启AOP注解
<aop:aspectj-autoproxy />
- 基于注解的Advice
@Aspect
@Component
public class MonitorAdvice {
@Pointcut("execution(* com.demo.modul.user.service.Speakable.*(..))")
public void pointcut() {}
@Around("pointcut()")
public void around(ProceedingJoinPoint jp) throws Throwable {
MonitorSession.begin(jp.getSignature().getName());
jp.proceed();
MonitorSession.end();
}
}
- 测试:
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring-annotation-aop.xml");
/*AnnotationBusiness business = (AnnotationBusiness) context.getBean("annotationBusiness");
business.delete("JACK"); */
Speakable business = (Speakable) context.getBean("personSpring");
business.sayBye();
}