代理模式

给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用。

使用代理模式的优点:

可以实现中介隔离,客户类可以使用代理对象在客户类和委托对象之间起到中介的作用(代理类和委托类实现相同接口)。遵循开闭原则,可以通过代理类扩展委托类的功能。

静态代理:

服务类接口:

1 public interface OriginService {
2 
3     String doSomeThing();
4 }

委托类:

1 public class OriginWorker implements OriginService {
2 
3     @Override
4     public String doSomeThing() {
5         System.out.println("do something");
6         return "i am origin worker";
7     }
8 }

代理类:

 1 public class OriginWorkerProxy implements OriginService{
 2 
 3     private OriginService originService;
 4 
 5     public OriginWorkerProxy(OriginService originService) {
 6         this.originService = originService;
 7     }
 8 
 9     @Override
10     public String doSomeThing() {
11         System.out.println("pre");
12         return originService.doSomeThing();
13     }
14 }

测试方法:

1 public class Main {
2 
3     public static void main(String[] args) {
4         OriginWorker originWorker = new OriginWorker();
5         OriginWorkerProxy originWorkerProxy = new OriginWorkerProxy(originWorker);
6         originWorkerProxy.doSomeThing();
7     }
8 }

可以实现编程阶段对类的功能进行扩展,但是使用的时候需要创建代理类,不易管理,接口改变,代理类也需要变动。

动态代理:(JDK、CGLIB)

JDK动态代理:

动态代理类:

 1 public class DynamicProxyHandler implements InvocationHandler {
 2 
 3     private Object object;
 4 
 5     public DynamicProxyHandler(Object object) {
 6         this.object = object;
 7     }
 8 
 9     @Override
10     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
11         System.out.println("pre");
12         Object result = method.invoke(object, args);
13         System.out.println("after");
14         return result;
15     }
16 }

测试类:

1 public class DynamicProxyMain {
2 
3     public static void main(String[] args) {
4         OriginService originWorker = new OriginWorker();
5         OriginService proxy = (OriginService) Proxy
6                 .newProxyInstance(OriginService.class.getClassLoader(), new Class[] { OriginService.class }, new DynamicProxyHandler(originWorker));
7         proxy.doSomeThing();
8     }
9 }

jdk动态代理需要委托类实现接口才可以。

CGLIB:

代理类:

 1 public class CglibProxy implements MethodInterceptor {
 2 
 3     private Object target;
 4 
 5     public Object getInstance(final Object object) {
 6         this.target = object;
 7         Enhancer enhancer = new Enhancer();
 8         enhancer.setSuperclass(this.target.getClass());
 9         enhancer.setCallback(this);
10         return enhancer.create();
11     }
12 
13     @Override
14     public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
15         System.out.println("pre");
16         Object result = methodProxy.invoke(target, objects);
17         System.out.println("after");
18         return result;
19     }
20 }

测试类:

1 public class CglibDynamicMain {
2 
3     public static void main(String[] args) {
4         OriginWorker originWorker = new OriginWorker();
5         CglibProxy cglibProxy = new CglibProxy();
6         OriginWorker workerProxy = (OriginWorker) cglibProxy.getInstance(originWorker);
7         workerProxy.doSomeThing();
8     }
9 }

Cglib根据委托类动态生成一个子类,代理委托类,所以不可以代理final修饰的类。Cglib可以代理没有实现接口的类。

原文地址:https://www.cnblogs.com/avalon-merlin/p/10515373.html