- jdk动态代理,委托类需要实现接口,因为代理类继承了Proxy类,而java不允许多继承
- cglib通过动态生成委托类的子类的方式生成代理类,委托类不需要实现接口,但也无法代理委托类的final方法,委托类是final类时也无法生成代理,因为final类不可被继承,final方法不可被重写
- spring aop生成的代理类,如果委托类实现了接口,那么采用的是jdk动态代理;否则使用的是cglib代理
- spring在启动容器生成bean的时候,会扫描某bean是否配置了切面,如果有则生成的是该类的代理类而不是原bean,注入的时候也是注入的代理类。所以,如果为service层配置了切面(包括@Transactional注解),则spring容器会为该service类生成代理类,@Autowired的时候也是注入的代理类。再所以,如果为该service类写了接口,该service类是接口的实现类,那么@Autowired的时候声明应该是接口而不是实现类,因为使用了jdk动态代理
- spring配置aop时,可以设置属性proxy-target-class="true"强制全部使用cglib代理
方法一 手动配置
<aop:config proxy-target-class="true"><!-- 设置proxy-target-class="true"强制使用cglib代理 -->
<aop:pointcut id="pointcut" expression="execution(* org.example.spring.aop.*.*(..))"/>
<aop:aspect ref="transactionForSpringAop">
<aop:before method="beginTransaction" pointcut-ref="pointcut"/>
<aop:after method="commit" pointcut-ref="pointcut"/>
</aop:aspect>
</aop:config>
方法二 注解配置
<!-- 设置proxy-target-class="true"强制使用CGLIB实现AOP -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
详细参考这篇博客
jdk动态代理和cglib动态代理性能比较