Spring-JDK动态代理

4 篇文章 0 订阅
3 篇文章 0 订阅
目标对象target
method1
TargetInterface
public void method1
代理对象
Proxy.newProxyIntanse括号TarInterface括号冒号
method1小括号小括号中括号
中括号
interface TargetInterface{
	//目标类接口
	public void method1();
	public String method2();
}
class Target implements TargetInterface{
	//实现目标类
	@Override
	public void method1(){
		System.out.println("目标对象方法method1");
	}
	
	@Override
	public String method2(){
		System.out.println("目标对象方法method2");
		return "method2";
	}
}
class ProxyTest{
	@Test
	public void test1(){
		//获得动态代理对象-----在运行时 在内存中动态的为Target创建一个虚拟的代理对象
		//objProxy是代理对象 根据参数确定到底是谁的代理对象
		TargetInterface objProxy = 	(TargetInterface)Proxy.newProxyInstance(
			Target.class.getClassLoader(),//与目标对象的类加载器
			new Class[]{TargetInterface.class},
			new InvocationHander(){
				//invoke 代表的是执行代理对象的方法
				@Override
				//method:代表目标对象的方法字节码对象
				//args:代表目标对象的响应的方法参数
				public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
					System.out.println("执行目标对象方法前的逻辑代码")
					//这个invoke不同上面的,只是名字刚好相同,
					//此是执行目标对象的方法
					//具体Object invoke(Object obj, Object[] args) 
					//obj为要执行此方法的对象(需要被代理的对象),args方法里的参数
					Object arg = method.invoke(new Target(), args);
					System.out.println("执行目标对象方法后的逻辑代码")
					return arg;					
				}
			}
		);
		
		objProxy.method1();//实质调用invoke 
		String method = objProxy.method2();
		System.out.println(method);
	}
}

写InterfaceTarget接口的目的是因为生成代理对象需要用到

Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)//返回值是Object类型
  1. 参数1:loader,类加载器,动态代理类运行时创建,任何类都需要类加载器将其加载到内存。一般情况:
  • 当前类.class.getClassLoader();
  • 目标类实例.getClass().getClassLoader();
  1. 参数2:interfaces 代理类需要实现的所有接口
  • 方式一:目标类实例.getClass().getInterfaces();!注意,只能获得自己接口,不能获得父元素接口
  • 方式二:new Class[]{目标类.class}
    例如:jdbc驱动–>DriverManger 获得接口Connection
  1. 参数3:InvocationHandler 处理类,接口必须进行实现类,一般采用匿名内部
  • 提供invoke方法,代理类的每一个方法执行时,都将调用一次invoke
Proxy.newProxyInstance(target.getClass().getClassLoader(),
					   target.getClass().getInterfaces(), 
					   new InvocationHander(){
					   @Override
					   //执行几次?----->看代理对象调用方法几次
					   //代理对象调用接口相应方法都是调用invoke方法
				       public Object invoke(Object proxy,Method method,Object[] args) throws Throwable{
					   return null;					
					   }
					  }
					 );

参数1:Object proxy:代理对象
参数2: Method method:代理对象当前执行的方法的描述对象(反射)

  • 执行方法名:method.getName()
  • 执行方法:method.invoke(对象,实际参数)
    参数3:Object[] args:方法实际参数
Object invoke(Object proxy,
              Method method,
              Object[] args)
              throws Throwable

注意:JDK的Proxy方式实现的动态代理 目标对象必须有接口 没有接口不能实现jdk版的动态代理

个人理解:Proxy类里面通过Proxy.newProxyInstance(ClassLoader loader,Class<?>[] interfaces, InvocationHandler h)方法通过传入参数interfaces实现了全部的接口并且额外实现了InvocationHandler ,此接口有invoke方法,里面通过传入目标对象、目标对象的方法对象、和参数对接口里的方法实现动态代理。(invoke方法本质是目标对像.相应方法()+ 其他逻辑代码,此逻辑代码就写在重写的invoke里面)

参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值