java设计模式之代理模式(Adapter)

原创 2019-08-28 09:36:55 设计模式 阅读(294)

简介 java设计模式之代理模式,简单来说代理模式就是通过代理,控制对象的访问。分为静态代理和动态代理两类;
  • 代理模式

    • 可以详细控制访问某个对象的方法,在调用这个方法前做前置处理,调用者方法后做后置处理(即:AOP的微观实现)
  • 核心角色

    • 抽象角色:定义代理角色和真实角色的工共对外方法
    • 实现抽象角色,定义真实角色所要实现的业务逻辑,供代理角色调用;关注真正的业务逻辑
    • 代理角色:实现抽象角色,是真实角色的代理,通过真实角色的业务逻辑方法来实现抽象方法,并可以附加自己的操作。将统一的流程控制放到代理角色中处理!
  • 应用场景

    • 安全代理:屏蔽对真实角色的直接访问。
    • 远程代理:通过代理类处理远程方法调用(RMI)
    • 延迟加载:先加载轻量级的代理对象,真正需要时再加载真实对象。
  • 分类:

    • 静态代理(静态定义代理类):自己定义代理类

    • 动态代理(动态生成代理类):程序自动生成代理类

      • JDK自带的动态代理
      • javaassist字节码操作库实现
      • CGLIB
      • ASM(底层使用指令,可维护性较差)

代码实现,静态代理

抽象角色接口:

public interface SourceAble { void proxyMethod(); }

真实角色

public class Source implements SourceAble { @Override public void proxyMethod() { //真正的业务逻辑 System.out.println("真实角色的方法,真正的业务逻辑实现!"); } }

代理角色:

public class Proxy implements SourceAble { //真实角色对象,操作真实角色的方法(代理行使权力) private SourceAble source; public Proxy(SourceAble source){ this.source = source; } @Override public void proxyMethod() { before(); source.proxyMethod(); after(); } private void before() { System.out.println("代理自己的流程方法before"); } private void after() { System.out.println("代理自己的流程方法after"); } }

动态代理(jdk提供的类)

一个动态代理处理类,需要实现InvocationHandler接口

public class SourceHandler implements InvocationHandler { private SourceAble sourceAble; public SourceHandler(SourceAble sourceAble){ this.sourceAble = sourceAble; } /** * * @param proxy 代理对象 * @param method 方法 * @param args 方法参数 */ @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { Object result = null; System.out.println("动态代理方法执行----------"); if (method.getName().equals("proxyMethod")){ //执行代理方法 method.invoke(this.sourceAble, args); } return result; } }

测试类

public class DynamicProxyTest { public static void main(String[] args) { SourceAble source = new Source(); SourceHandler handler = new SourceHandler(source); SourceAble proxy = (SourceAble) Proxy.newProxyInstance(ClassLoader.getSystemClassLoader(), new Class[]{SourceAble.class}, handler); proxy.proxyMethod(); } }