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();
}
分享到: