静态代理
用法
创建一个接口,然后创建被代理的类实现该接口并且实现该接口中的抽象方法。之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法。
接口:
public interface HelloInerface {
void sayHello();
}
被代理类:
public class Hello implements HelloInerface{
public void sayHello(){
System.out.println("Hello!");
}
}
代理类:
public class HelloProxy implements HelloInerface{
private HelloInerface HelloP = new Hello();
public void sayHello(){
System.out.println("before");
HelloP.sayHello();
System.out.println("after");
}
}
代理类调用:
被代理类被传递给了代理类HelloProxy,代理类在执行具体方法时通过所持用的被代理类完成调用。
public class main {
public static void main(String[] args) {
HelloProxy hellop = new HelloProxy();
hellop.sayHello();
}
}
输出:
before
Hello!
after
使用静态代理很容易就完成了对一个类的代理操作。但是静态代理的缺点也暴露了出来:由于代理只能为一个类服务,如果需要代理的类很多,那么就需要编写大量的代理类,比较繁琐。
动态代理
接口、被代理类不变,我们先构建一个实现InvocationHandler接口的类。
public class ProxyHandler implements InvocationHandler {
private Object object;
public ProxyHandler(Object object){
this.object=object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws InvocationTargetException, IllegalAccessException {
System.out.println("before");
method.invoke(object,args);
System.out.println("after");
return null;
}
}
执行
public static void main(String[] args) {
System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
HelloInerface hello = new Hello();//被代理类
InvocationHandler handler = new ProxyHandler(hello);
HelloInerface hellop = (HelloInerface) Proxy.newProxyInstance(hello.getClass().getClassLoader(),hello.getClass().getInterfaces(),handler);
hellop.sayHello();
}
简单来说 proxy代理实例都有一个关联的调用处理程序InvocationHandler,而invoke方法就是代理对象调用方法时的调用处理程序
区别于上面的静态代理,当我们再添加一个被代理类时
//接口
public interface AAAInterface {
void AAA();
}
//被代理类
public class AA implements AAAInterface {
@Override
public void sayAAA() {
System.out.println("A!");
}
}
那么代理过程就变成
public static void main(String[] args) {
System.getProperties().setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
HelloInterface hello = new Hello();
AAAInterface a = new AA();
InvocationHandler handler = new ProxyHandler(hello);
InvocationHandler handler1 = new ProxyHandler(a);
HelloInterface proxyHello = (HelloInterface) Proxy.newProxyInstance(hello.getClass().getClassLoader(), hello.getClass().getInterfaces(), handler);
AAAInterface proxyAAA = (AAAInterface) Proxy.newProxyInstance(a.getClass().getClassLoader(), a.getClass().getInterfaces(), handler1);
proxyHello.sayHello();
proxyAAA.sayAAA();
}
参考 https://www.jianshu.com/p/9bcac608c714