Spring有两种创建代理的方式
1、 如果目标对象实现一个或多个接口暴露的方法,spring将使用JDK的java.lang.reflect.Proxy类创建代理。此类动态产生一个新类,该类实现了所需的接口,织入通知并代理对目标对象的所有请求
2、 若目标对象未实现任何接口,spring使用CGLIB库生成目标对象的子类;在创建该子类时,织入通知并将目标对象的调用委托给该子类。此种代理方式需注意:
1) 对接口创建代理优于对类创建代理
2) 标记为final的方法不能被通知
两种创建代理方式的案例
1、 使用JDK创建
首先创建一个抽象的主题角色---------公共的接口
public interface personService {
//找房子
public void findHouse();
//找好房子
public void findHouse(String address,String name);
}
创建一个真实的主题角色--------实体类
public class PersonServiceBean implements personService{
@Override
public void findHouse() {
// TODO Auto-generated method stub
System.out.println("------------------方法执行啦------------------------");
}
@Override
public void findHouse(String address, String name) {
// TODO Auto-generated method stub
System.out.println("========================找好房子的方法===============");
}
}
创建一个代理主题角色-----第二个实体类
public class ProxyPersonServiceBean implements personService{
//真实主题引入的操作
private PersonServiceBean personServiceBean=new PersonServiceBean();
@Override
public void findHouse() {
System.out.println("处理一些操作");
personServiceBean.findHouse();
System.out.println("处理一些操作");
}
@Override
public void findHouse(String address, String name) {
// TODO Auto-generated method stub
}
}
注意:使用JDK方式创建代理对象一定要记得让两个实体类继承统一接口
创建代理----------实现了InvocationHandler接口的实体类
public class JDKProxy implements InvocationHandler{
//代理的目标对象 真实主题角色
private Object targetObject;
//根据目标对象创建代理对象
public Object createProxyInstrance(PersonServiceBean personServiceBean){
this.targetObject=personServiceBean;
//返回目标代理对象
//第一个参数设置代码使用的类加载器,一般采用跟目标相同的类加载器
return Proxy.newProxyInstance(personServiceBean.getClass().getClassLoader(), personServiceBean.getClass().getInterfaces(),this);
}
/*
* proxy:代理对象
* method:代理方法
* args:代理方法的参数
* (non-Javadoc)
* @see java.lang.reflect.InvocationHandler#invoke(java.lang.Object, java.lang.reflect.Method, java.lang.Object[])
*/
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("代理类的名称"+proxy.getClass().getName());
System.out.println("方法的名称"+method.getName());
if(args!=null && args.length>0 ){
System.out.println("第一个参数是"+args[0].toString());
}
//执行目标方法
//第一个参数代表目标类
Object result=method.invoke(this.targetObject, args);
return result;
}
}
测试方法:
@Test
public void test() {
//处理操作 真实主题 角色
PersonServiceBean personServiceBean=new PersonServiceBean();
//代理
JDKProxy jdkProxy=new JDKProxy();
//创建代理对象
Object proxyObject=jdkProxy.createProxyInstrance(personServiceBean);
//返回的是一个接口对象
personService p=(personService) proxyObject;
p.findHouse();
p.findHouse("aaaaaaaaaaaaa", "ccccc");
}
2、 使用CGLIB创建
PersonServiceBean类
public class PersonServiceBean {
public void findHouse() {
// TODO Auto-generated method stub
System.out.println("------------------方法执行啦------------------------");
}
public void findHouse(String address, String name) {
// TODO Auto-generated method stub
System.out.println("========================找好房子的方法===============");
}
}
CglibPersonServiceBean类
public class CglibPersonServiceBean implements MethodInterceptor{
//代理目标对象 真实主题 角色
private Object targetObject;
//根据目标对象创建代理对象
public Object createProxyInstrance(Object targetObject){
this.targetObject=targetObject;
Enhancer enhancer=new Enhancer();
enhancer.setSuperclass(this.targetObject.getClass());
enhancer.setCallback(this);
return enhancer.create();//创建代理对象
}
@Override
public Object intercept(Object object, Method method, Object[] args,
MethodProxy arg3) throws Throwable {
System.out.println("代理类的名称"+object.getClass().getName());
System.out.println("方法的名称"+method.getName());
if(args!=null && args.length>0 ){
System.out.println("第一个参数是"+args[0].toString());
}
//执行目标对象的方法
Object result=arg3.invoke(this.targetObject, args);
return result;
}
}
测试:
public static void main(String[] args) {
//处理操作 真实主题 角色
PersonServiceBean personServiceBean=new PersonServiceBean();
//cglib代理
CglibPersonServiceBean cProxy = new CglibPersonServiceBean();
//创建代理对象
Object proxyObject=cProxy.createProxyInstrance(personServiceBean);
//赋值给真的主题 类的对象
personService p=(personService) proxyObject;
p.findHouse();
p.findHouse("aaaaaaaaaaaaa", "ccccc");
}
代理创建的两种方式
最新推荐文章于 2021-02-04 16:22:32 发布