InvocationHandler动态代理 与 面向切面编程
2019-12-19 本文已影响0人
瑜小贤
先看一个常规案例
接口类:
public interface MyInterface {
int add(int a, int b);
}
实现类:
public class MyInterfaceImpl implements MyInterface {
@Override
public int add(int a, int b) {
System.out.println("calculating...");
return a + b;
}
}
使用InvocationHandler
public class MyHandler implements InvocationHandler {
private MyInterface myInterface;
public MyHandler(MyInterface interface) {
this.myInterface = interface;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before...");
Object invoke = method.invoke(myInterface, args);
System.out.println("after...");
return invoke;
}
public MyInterface getProxy() {
return (MyInterface) Proxy.newProxyInstance(myInterface.getClass().getClassLoader(),
myInterface.getClass().getInterfaces(), this);
}
}
public class Test {
public static void main(String[] args) {
//要代理的真实对象
MyInterface addInterface = new MyInterfaceImpl();
//代理对象的调用处理程序,我们将要代理的真实对象传入代理对象的调用处理的构造函数中,最终代理对象的调用处理程序会调用真实对象的方法
InvocationHandler handler = new MyHandler(addInterface);
/**
* 通过Proxy类的newProxyInstance方法创建代理对象,我们来看下方法中的参数
* 第一个参数:addInterface.getClass().getClassLoader(),使用handler对象的classloader对象来加载我们的代理对象
* 第二个参数:addInterface.getClass().getInterfaces(),这里为代理类提供的接口是真实对象实现的接口,这样代理对象就能像真实对象一样调用接口中的所有方法
* 第三个参数:handler,我们将代理对象关联到上面的InvocationHandler对象上
*/
MyInterface proxy = (MyInterface)Proxy.newProxyInstance(handler.getClass().getClassLoader(), addInterface.getClass().getInterfaces(), handler);
System.out.println(proxy.add(1, 2).toString());
}
}
before...
calculating...
after...
3
注意:
- 在InvocationHandler接口中只有一个方法 invoke,在这个方法中反射调用 Object invoke = method.invoke(myInterface, args); 就是myInterface接口中方法的实现,在这个方法调用前后,可以加入别的操作,这个操作视具体业务而定(例如:保存数据,判断登录等等),而这个操作就被视为面向切面编程中的切面。
- 可以定义getProxy方法,在方法中里面调用Proxy.newProxyInstance 获取一个代理对象,
如果不加这个方法,需要在对应类中使用
(MyInterface)Proxy.newProxyInstance(MyInterface.class.getClassLoader(),
new class[]{MyInterface.class}, new MyHandler(this));
来获取一个MyInterface对象
- 上面我们只讲解了Proxy中的newProxyInstance(生成代理类的方法),但是它还有其它的几个方法,我们下面就介绍一下:
- getInvocationHandler:返回指定代理实例的调用处理程序
- getProxyClass:给定类加载器和接口数组的代理类的java.lang.Class对象。
- isProxyClass:当且仅当使用getProxyClass方法或newProxyInstance方法将指定的类动态生成为代理类时,才返回true。
- newProxyInstance:返回指定接口的代理类的实例,该接口将方法调用分派给指定的调用处理程序。