AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,可以实现在不修改源代码的情况下给程序动态同意添加功能的一种技术。作为面向对象编程的一种补充,专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在 Java EE 应用中,常常通过 AOP 来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等。AOP 实现的关键就在于 AOP 框架自动创建的 AOP 代理,AOP 代理主要分为静态代理和动态代理两大类,静态代理以 AspectJ 为代表;而动态代理则以 Spring AOP 为代表。

Spring AOP 是通过Java动态代理的方式实现,而Java动态代理有JDK动态代理和CGLib动态代理两种方式。Spring AOP会根据情况选择使用哪一种动态代理方式,或者由用户强制指定。

  • 使用JDK动态代理实现Spring AOP

一旦我们给一个Bean定义了Aop, 使用Spring容器的getBean方法获得的对象就是Jdk动态代理生成的代理类的对象。如下类图,Spring实现了自己的拦截器JdkDynamicAopProxy,并覆盖了invoke方法,在invoke方法会调用相应的Advisor处理程序,当然最终会调用到目标对象的方法。我们可以看到在JdkDynamicAopProxy中聚合了AdvisedSupport类,在AdvisedSupport类中可以看到有targetObject属性,这个是目标对象;还有一个advisorChainFactory, 这个是advisor链的工厂类,通过这个类可以获得advisor链。AOP-JDK-Proxy_thumb2

  • 使用CGLib动态代理实现Spring AOP

一旦我们给一个Bean定义了Aop,使用Spring容器的getBean方法获得的对象就是CGLib动态代理生成的代理类。如下类图,Spring定义自己的拦截器Cglib2AopProxy$DynamicAdvisedInterceptor。和Jdk动态代理类似,在拦截器中聚合了AdvisedSupport类。

CGLib-Proxy-AOP_thumb2

  • Spring AOP选择动态代理方式的策略

—先尝试使用JDK 动态代理(Bean的类必须实现了接口)

Spring AOP这个策略是可以理解的,因为使用JDK动态代理,就不需要依赖第三方库,所以优先选择Jdk动态代理。

—如果Bean的类没有实现接口,则默认使用CGLib Proxies

–可以通过设置proxy-target-class强制使用CGLib Proxies

<aop:config proxy-target-class="true">

<!-- other beans defined here... -->

</aop:config>

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐