Spring: proxy-target-class 决定 用 CGlib 还是 JDK AOP 来生成代理

package salesdepart.service.app;
import org.springframework.context.*;
import org.springframework.context.support.*;


import java.util.*;
public class BeanTest { 
public static void main(String[] args) {
ApplicationContext ctx = new
ClassPathXmlApplicationContext("employee.xml");
employee p=(employee)ctx.getBean("SalesEmployee");

System.out.println("Hello: employee proxy class is "+p.getClass());
p.displayInfo();
}

}


employee.xml 

==================


<?xml version="1.0" encoding="GBK"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 指定自动搜索Bean组件、自动搜索切面类 -->
<context:component-scan base-package="salesdepart.service.app">
<context:include-filter type="annotation"
expression="org.aspectj.lang.annotation.Aspect"/>
</context:component-scan>
<!-- 启动@AspectJ支持 -->
<aop:aspectj-autoproxy proxy-target-class="false"/>
</beans>



如果在employee.xml 中设置 <aop:aspectj-autoproxy proxy-target-class="false"/> 或者 if <aop:aspectj-autoproxy/>
则输出: Hello: employee proxy class is class com.sun.proxy.$Proxy12

 
如果在employee.xml 中设置 <aop:aspectj-autoproxy proxy-target-class="true"/>
则输出:  Hello: employee proxy class is class salesdepart.service.app.SalesDepartEmployee$$EnhancerBySpringCGLIB $ $ 397e3c56

说明 proxy-target-class="true",则强制JAVA走cglib来生成动态代理,反之则是用JDK AOP来生成代理


二者有如下的区别:


Aspect默认情况下不用实现接口,但对于目标对象(UserManagerImpl.java),在默认情况下必须实现接口
如果没有实现接口必须引入CGLIB库,我们可以通过Advice中添加一个JoinPoint参数,

这个值会由spring自动传入,从JoinPoint中可以取得参数值、方法名等等

1、如果目标对象实现了接口,默认情况下会采用JDK的动态代理实现AOP
2、如果目标对象实现了接口,可以强制使用CGLIB实现AOP
3、如果目标对象没有实现了接口,必须采用CGLIB库,spring会自动在JDK动态代理和CGLIB之间转换


如何强制使用CGLIB实现AOP?
 * 添加CGLIB库,SPRING_HOME/cglib/*.jar
 * 在spring配置文件中加入<aop:aspectj-autoproxy proxy-target-class="true"/>
 
JDK动态代理和CGLIB字节码生成的区别?
 * JDK动态代理只能对实现了接口的类生成代理,而不能针对类
 * CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法
   因为是继承,所以该类或方法最好不要声明成final 




你可能感兴趣的:(java,spring,AOP)