如何实现在已有代码之后添加逻辑之java动态代理
在上篇博客中讨论到java的静态代理, 就是通过组合的方法,前提是委托类需要实现一个接口,代理类也实现这个这个 接口,从何组合两个类,让代理类给委托类添加功能!
知道java的静态代理,我们又遇到一个问题,我们又遇到一个问题,是不是每个类要添加功能,都得重新写个类呢!怎么才能实现同样的代码,可以在其他类都能起作用!
这就是java动态代理的内容,在java中通Proxy类好AnnotationHandler接口来实现动态代理,我先尝试自己写一个自己的动态代理!
一.实现简单的自定义动态代(没考虑参数,接口) 只能称之为 伪java动态代理
1、接口:
public interface ICommonInterface { //nothing public void addUser(); public void delete(); }
2、需要代理的类(委托类)
/* * 自定义java动态代理 * 这是一个委托类 */ public class DelegationClass implements ICommonInterface { public void addUser() { System.out.println("add user success"); } public void delete() { System.out.println("delete user success"); } }
3.代理类
import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; public class ProxyClass { //定义委托类对象(组合对象) private Object target=null; public ProxyClass(Object target) { this.target=target; //构造方法初始化委托对象实例 } public void invokeFunction(Method m) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { System.out.println("before start....."); m.invoke(target); } }
4.测试类
import java.lang.reflect.InvocationTargetException; public class Test { public static void main(String [] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { //获取委托对象 DelegationClass target=new DelegationClass(); //获取代理对象 ProxyClass pro=new ProxyClass(target); //传递委托对象调用方法,调用代理对象对应的方法实现 pro.invokeFunction(target.getClass().getMethod("addUser")); pro.invokeFunction(target.getClass().getMethod("delete")); } } 结果: before start..... add user success before start..... delete user success
我们可以看到实现的简单代理类,代理类没有涉及到接口,也没涉及到参数传递.....这些条件导致这个代理很好实现,现实中,我们得考虑接口,考虑参数 !
我们来看看java怎么实现动态代理的:
java中有两个类:InvocationHandler 和Proxy 其中Proxy类主要用来获取动态代理对象,InvocationHandler接口用来约束调用者实现
我们来看看实例:
业务接口:
public interface ICommonInterface { //nothing public void addUser(); public void delete(); }
业务接口实现:
public class DelegationClass implements ICommonInterface { public void addUser() { System.out.println("add user success"); } public void delete() { System.out.println("delete user success"); } }
InvocationHandler实现,需要在接口方法调用前加入一部分其他逻辑
import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class Interceptor implements InvocationHandler { //声明一个委托类的对象 private Object target=null; public Interceptor(Object target) { this.target=target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // TODO Auto-generated method stub doBefore(); method.invoke(target, args); return null; } public void doBefore() { System.out.println("start ..............."); } }
测试类:
public class Test { public static void main(String [] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, NoSuchMethodException, SecurityException { //获取委托对象 DelegationClass target=new DelegationClass(); //获取InvocationHanlder的实例对象 Interceptor inter=new Interceptor(target); //获取代理对象(实际上Proxy根据target的类加载器,接口和InvocationHandle生成一个类,再生成一个对象) ICommonInterface de= (ICommonInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), inter); //测试这个对象 System.out.println(de.getClass().getInterfaces()[0].getName()); de.addUser(); de.delete(); } }
结果:
com.test.proxy.javaproxy.ICommonInterface
start ...............
add user success
start ...............
delete user success