一、背景
在使用AOP创建代理时,需要通过bean中的类来找到相应的代理项;
在AOP代理poxy配置时,有poxy-target-class来控制-值为false为JDK代理,为true为CGlib代理
在Spring中,常用的代理类一是使用GDK代理,二是使用CGlib代理,下面讲述两种代理的不同
二、代理区分
(1)JDK代理
JDK代理的原理是为实现目标类的接口,其本质上是实现类,所以在执行以下代码时会找不到代理类
package club.shaoyu.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import club.shaoyu.userinfo.service.IUserInfoService;
import club.shaoyu.userinfo.service.UserInfoService;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("app.xml");
IUserInfoService infoService= classPathXmlApplicationContext.getBean(UserInfoService.class);
Class clazz=infoService.getClass();
System.out.println(clazz.getName());
classPathXmlApplicationContext.close();
}
}
此时通过其目标类找不到代理方法
报错:No qualifying bean of type 'club.shaoyu.userinfo.service.UserInfoService' availab
通过接口就可以找到相应的代理方法:
执行结果:com.sun.proxy.$Proxy8 明显的代理类
(2)CGlib代理方法
代理原理是通过继承目标类从而获得代理对象
我们将poxy-target-class值改为true后看到输出的代理类的名称为:
club.shaoyu.userinfo.service.UserInfoService$$EnhancerBySpringCGLIB$$7bd954f0
三、反射探究:
(1)JDK
package club.shaoyu.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import club.shaoyu.userinfo.service.IUserInfoService;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("app.xml");
IUserInfoService infoService= classPathXmlApplicationContext.getBean(IUserInfoService.class);
Class clazz=infoService.getClass();
for (Class s : clazz.getInterfaces()) {
System.out.println(s.getName());
}
classPathXmlApplicationContext.close();
}
}
输出结果:
club.shaoyu.userinfo.service.IUserInfoService
org.springframework.aop.SpringProxy
org.springframework.aop.framework.Advised
org.springframework.core.DecoratingProxy
(2)CGlib
package club.shaoyu.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import club.shaoyu.userinfo.service.IUserInfoService;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext classPathXmlApplicationContext=new ClassPathXmlApplicationContext("app.xml");
IUserInfoService infoService= classPathXmlApplicationContext.getBean(IUserInfoService.class);
Class clazz=infoService.getClass();
System.out.println(clazz.getSuperclass().getName());
classPathXmlApplicationContext.close();
}
}
执行结果:club.shaoyu.userinfo.service.UserInfoService
四、总结