java静态代理和动态代理
代理的优点
职责清晰
真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
高扩展性,可以在代理方法前后增加额外的处理逻辑。
被代理的对象
一个接口
public interface Subject {
void doSomething();
}
它的实现类
public class SubjectImpl implements Subject {
@Override
public void doSomething() {
System.out.println( "call doSomething()" );
}
}
静态代理
静态代理是由程序员创建或工具生成代理类的源码,再编译代理类。也就是在程序运行前就已经存在代理类的字节码文件,代理类和委托类的关系在运行前就确定了。缺点是被代理对象和代理紧耦合在一起。而且代理类都是针对被代理类创建的。
public class SubjectProxy implements Subject {
Subject subject = new SubjectImpl();
@Override
public void doSomething() {
System.out.println("before"); //调用目标对象之前可以做相关操作
subject.doSomething();
System.out.println("after");//调用目标对象之后可以做相关操作
}
}
动态代理
动态代理在运行阶段才指定被代理的对象,通过实现InvocationHandler接口,调用具体的方法。
public class ProxyHandler implements InvocationHandler {
private Object tar;
public Object bind(Object tar) {
this.tar = tar;
return Proxy.newProxyInstance(tar.getClass().getClassLoader(), tar.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object result = null;
System.out.println("before"); //调用目标对象之前可以做相关操作
result = method.invoke(tar, args);
System.out.println("after");//调用目标对象之后可以做相关操作
return result;
}
}
运行
public class Test {
public static void main(String[] args) {
ProxyHandler proxy = new ProxyHandler();
//绑定该类实现的所有接口
Subject sub = (Subject) proxy.bind(new SubjectImpl());
sub.doSomething();
}
}