Design Pattern | Proxy Pattern 接口模式
by Botao Xiao
代理模式就是多一个代理类出来,替原对象进行一些操作。 在我们使用代理模式的时候需要生成一个新的对象。
为什么需要使用代理
- 调用对象本身是一件很耗时的事情,因为对象可能正在被占用,需要等很长时间才能对象才能被业务释放。所以我们可以在本地通过代理工厂生成一个代理,代为接收信息,做出相应。
- 实现横向增强。
通过new生成新的对象进行加强
- 首先定义一个接口,并实现这个接口。
public interface Sourcable { public void method(); } public class Source implements Sourcable { @Override public void method() { System.out.println("This is a method..."); } }
- 定义一个接口类实现要增强的方法,在接口的内部新建一个对象的实例,并通过对该实例方法的重写,在重写中对实例的方法进行调用,并在调用前后进行增强。
public class SourceProxy implements Sourcable{ //继承要实现的接口 private final Sourcable source; public SourceProxy(){ source = new Source(); //在类的内部重新生成一个对象作为代理。 } public void before(){ System.out.println("Advice before..."); } public void after(){ System.out.println("Advice after..."); } @Override public void method() { //重写要增强的方法 before(); source.method(); //调用方法,在方法的前后进行织入 after(); } public static void main(String[] args) { Sourcable s = new SourceProxy(); s.method(); } }
通过JDK中的Proxy类进行增强
要求:该类必须实现接口
public class ProxyFactory<T> {
private T target; //传入一个实例,用于生成该实例的对象。
public ProxyFactory(T target){
this.target = target;
}
@SuppressWarnings("unchecked")
public T getProxyInstance(){ //生成一个对象的代理
return (T) Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
beforeAdvice(); //前置增强
Object ret = method.invoke(target, args);
afterAdvice(); //后置增强
return ret;
}
});
}
private void beforeAdvice(){
System.out.println("Advice before...");
}
private void afterAdvice(){
System.out.println("Advice after...");
}
public static void main(String[] args) {
ProxyFactory<Sourcable> factory = new ProxyFactory<Sourcable>(new Source());
Sourcable instance = factory.getProxyInstance();
instance.method();
}
}
通过CgLib实现代理
- 要代理的类不需要实现接口。
- Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)
- 实际上是一个class文件修改器(ASM)
public class CglibProxyFactory<T> implements MethodInterceptor{ private final T target; public CglibProxyFactory(T target){ this.target = target; } @SuppressWarnings("unchecked") public T getProxyInstance(){ Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); //会调用intercept方法,MethodInterceptor实现了Callback方法,enhancer会生成一个代理对象,在对方法进行调用的时候,会使用intercept方法对方法进行横向增强。 return (T) enhancer.create(); } @Override public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable { //增强的方法 System.out.println("Advice before..."); Object ret = method.invoke(target, arg2); System.out.println("Advice after..."); return ret; } public static void main(String[] args) { CglibProxyFactory<Bird> factory = new CglibProxyFactory<>(new Bird()); Bird instance = factory.getProxyInstance(); instance.shout(); } }
Subscribe via RSS