今天是:
带着程序的旅程,每一行代码都是你前进的一步,每个错误都是你成长的机会,最终,你将抵达你的目的地。
title

动态代理

1.什么是动态代理

首先,代理的主要目的是控制对目标对象的访问,而不是增强目标对象的功能。访问控制包括同步、认证、远程访问(RPC)、延迟实例化(Hibernate、Mybatis)、AOP(事务)等。

动态代理就是,在程序运行期,创建目标对象的代理对象,并可以对目标对象中的方法进行功能性增强的一种技术。在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。可以理解为运行期间,对象中方法的动态拦截,在拦截方法的前后执行功能操作。

代理类在程序运行期间,创建的代理对象称之为动态代理对象。这种情况下,创建的代理对象,并不是事先在Java代码中定义好的。而是在运行期间,根据我们在动态代理对象中的“指示”,动态生成的。也就是说,你想获取哪个对象的代理,动态代理就会为你动态的生成这个对象的代理对象。动态代理可以对被代理对象的方法进行功能增强。有了动态代理的技术,那么就可以在不修改方法源码的情况下,增强被代理对象的方法的功能,在方法执行前后做任何你想做的事情。

2.JDK动态代理

jdk动态代理主要通过InvocationHandler接口来实现

  • 目标接口Target
    public interface Target {
    	public void doSomething();
    }
  • 具体目标ConcreteTarget,目标类的基本实现
    public class ConcreteTarget implements Target {
    
    	@Override
    	public void doSomething() {
    		System.out.println("Dynamic Proxy Test");
    	}
    
    }
  • 实现InvocationHandler的处理处理器ProxyHandler,下面只是简单的打印了被代理对象方法执行前后的信息。
    public class ProxyHandler implements InvocationHandler{
    
    	Object concreteTarget;
    	public  ProxyHandler(Object obj) {
    		this.concreteTarget=obj;
    	}
    	@Override
    	public Object invoke(Object proxy, Method method, Object[] args)
    			throws Throwable {
    			System.out.println("proxy:"+proxy.getClass().getName());
    	        System.out.println("method:"+method.getName());
    	        //System.out.println("args:"+args[0].getClass().getName());
    	        System.out.println("Before invoke method...");
    	        Object object=method.invoke(concreteTarget, args);//普通的Java反射代码,通过反射执行某个类的某方法
    	        System.out.println("After invoke method...");
    	        return object;
    	}
    
    }
  • 生成代理对象并执行
    	public static void main(String[] args) {
    		 ConcreteTarget c=new ConcreteTarget();//元对象(被代理对象)
             InvocationHandler ih=new ProxyHandler(c);//代理实例的调用处理程序。
             //创建一个实现业务接口的代理类,用于访问业务类(见代理模式)。
             //返回一个指定接口的代理类实例,该接口可以将方法调用指派到指定的调用处理程序,如ProxyHandler。
             Target target=(Target)Proxy.newProxyInstance(c.getClass().getClassLoader(),c.getClass().getInterfaces(),ih);
             //调用代理类方法,Java执行InvocationHandler接口的方法.
            target.doSomething();
    
    	}

     

 

分享到:

专栏

类型标签

网站访问总量