代理创建的两种方式

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");
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值