Design Mode - (Agent Mode)

Agency mode:

         The proxy mode is also an implementation of the principle of opening and closing. The function is extended without changing the source code, and the target object is encapsulated by the proxy object, which hides the target object and performs a pre-sales of the original function. After-sales work; spring aop is a typical agency model

         Static proxy mode:

   

// 目标对象和代理对象实现同一个接口
interface Interface01{
    void fun01();
}
// 目标对象
class TargetClass implements Interface01{

    @Override
    public void fun01() {
        System.out.println("执行目标对象函数");
    }
}
// 代理对象
class ProxyClass implements Interface01{
   // 目标对象
    private TargetClass targetClass ;
   // 有参构造器(传入一个目标对象的实例)
    public ProxyClass(TargetClass targetClass) {
        this.targetClass = targetClass;
    }
    // 执行方法
    @Override
    public void fun01() {
        System.out.println("执行前***");
        targetClass.fun01();
        System.out.println("执行后***");
    }
}

   Dynamic proxy:

        Since static agents need a proxy class each time, dynamic proxy appears, and proxy class is created dynamically

      Dynamic proxy supported by j'd'k: The dynamic proxy of jdk is based on interfaces, and the target class must implement an interface, but in fact not all classes have an interface

public class TestDynamicProxy {
    public static void main(String[] args) {
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(new TargetDncymicClass());
        // 获取代理对象
        Interface02 proxy = (Interface02) myInvocationHandler.getProxy();
        proxy.fun02();
    }
}
// 接口
interface  Interface02{
      void fun02();
}
// 目标类
class TargetDncymicClass implements Interface02{

    @Override
    public void fun02() {
        System.out.println("TargetDncymicClass...");
    }
}
// invocationHandler
class MyInvocationHandler implements InvocationHandler{
    private Object target;
    // 传入目标对象
    public MyInvocationHandler(Object target) {
        this.target = target;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("执行前。。");
        // 执行目标方法
        Object object = method.invoke(target, args);
        System.out.println("执行后。。");
        return object;
    }
    // 获取生成的代理对象
    public Object getProxy() {
        // 参数1 类加载器,参数2 目标类的所有实现接口, 参数3 InvocationHandler
        return Proxy.newProxyInstance(this.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                this);
    }
}

Cglib :

   The dynamic proxy implemented by cglib does not require the target class to implement the interface, and the bottom layer uses asm bytecode to generate the bytecode of the proxy class

// 定义目标类
class TargetCglibClass{
// 目标方法
    public void test() {
        System.out.println("TargetCglibClass...");
    }

// methodInterceptor 方法拦截器
class MyMethodInterceptor implements MethodInterceptor{

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        System.out.println("执行前。。");
        // 执行目标方法
        Object object = methodProxy.invokeSuper(o, objects);
        System.out.println("执行后。。");
        return object;
    }
}

//测试
  public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(TargetCglibClass.class);
        enhancer.setCallback(new MyMethodInterceptor());
        TargetCglibClass o = (TargetCglibClass) enhancer.create();
        o.test();
    }

 

The difference between jdk and cglib dynamic proxy implementation

1. The proxy class and the delegated class generated by the jdk dynamic proxy implement the same interface;
2. The bytecode generated in the cglib dynamic proxy is more complicated. The generated proxy class is a subclass of the delegated class and cannot handle final keywords. Modified method;
3. jdk uses reflection mechanism to call delegate class method, cglib uses similar index method to directly call delegate class method;

Guess you like

Origin blog.csdn.net/xiaodujava/article/details/88866292