package proxy;
public class RealSubject implements ISubject{
public void eat() {
System.out.println("hello");
}
}
package proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class MyInvocationHandler implements InvocationHandler {
private Object target;
MyInvocationHandler() {
super();
}
MyInvocationHandler(Object target) {
super();
this.target = target;
}
public Object newProxyInstance(Object target) {
this.target = target;
// 该方法用于为指定类装载器、一组接口及调用处理器生成动态代理类实例
// 第一个参数指定产生代理对象的类加载器,需要将其指定为和目标对象同一个类加载器
// 第二个参数要实现和目标对象一样的接口,所以只需要拿到目标对象的实现接口
// 第三个参数表明这些被拦截的方法在被拦截时需要执行哪个InvocationHandler的invoke方法
// 根据传入的目标返回一个
代理对象
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
}
public Object invoke(Object o, Method method, Object[] args) throws Throwable {
before();
Object result = method.invoke(target, args);
after();
return result;
}
public void before() {
System.out.println("before");
}
public void after() {
System.out.println("after");
}
}
public class Client {
public static void main(String[] args) {
ISubject obj=new RealSubject();
MyInvocationHandler handler=new MyInvocationHandler(obj);
ISubject aa=(ISubject)handler.newProxyInstance(obj);
aa.eat();
}
}
运行结果:
before
hello
after
引出两个问题:
1、$Proxy0是哪里来的?debug状态可以看到的
2、MyInvocationHandler.invoke方法是谁调用的?
$procy0是 (ISubject)handler.newProxyInstance(obj);是这句语句生成的对象,如果把它村下来反编译,可以看$proxy里有一个say()方法,它调用了invoke方法。
java动态代理的作用:
可以在某些不能修改的代码里通过java动态代理增强某些功能,例如原来在业务逻辑操作时没有写日志,但之前的程序已经封版不要进行修改,现在可以用java动态代理的方式在业务逻辑之前和之后作一下操作。这种模式满足对修改封闭,对扩展开放的原则。