在静态代理中,我们在调用target类的时候,都是先拿到proxy类。由于proxy类中将target类作为了成员变量,而且跟target类继承了一样的接口,具有同样的方法,所以,在proxy类中。通过调用target类的方法来对目标类方法的运行前后插入特殊操作。
可是静态代理有俩缺点:1,代理类特别多,每添加一个target类。就要写一个代理。2,在proxy类中,可能我们须要插入的操作时同样的。这就造成了代码的反复。
所以。通过引入反射,能够实现动态代理,以对静态代理进行改进。
/** * @ClassName: LogHandler * @Description: 用于创建代理类 * @author 水田 * @date 2015年12月8日 上午11:17:51 */ public class LogHandler implements InvocationHandler { private Object targetObject; public Object newProxyInstance(Object targetObj) { this.targetObject = targetObj; /* * 1,拿到类的classLoader * 2,得到创建的类的接口 * 3,传入回调invoke方法所在类 * */ return Proxy.newProxyInstance(targetObj.getClass().getClassLoader(), targetObj.getClass().getInterfaces(), this); } /* * (非 Javadoc) <p>Title: invoke</p> <p>Description: </p> * * @param proxy * * @param 调用方法信息 * * @param args:方法的參数数组 * * @return * * @throws Throwable * * @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 { for (int i = 0; i < args.length; i++) { System.out.println(args[i]); } try { // 调用目标类的方法,返回一个object,假设方法没有返回值,则返回null method.invoke(targetObject, args); } catch (Exception e) { e.printStackTrace(); throw e; } System.out.println("start----->>>" + method.getName()); return method.getName(); } }
使用演示样例:
/* 动态代理演示样例 */ LogHandler logHandler = new LogHandler(); UserManager userManager = (UserManager) logHandler .newProxyInstance(new UserManagerImpl()); userManager.addUser("2343254", "lhc");
我们将target类中被调用方法运行前后要插入的操作放在回调函数invoke方法中,当使用代理类调用相应方法的时候。会直接进入invoke方法这里。使用method,和invoke第三个參数能够拿到被调用方法的信息。
添加了动态代理之后。明显去掉了静态代理的两个小缺点。
时间: 2024-10-21 09:05:53