[Spring] Two dynamic proxy methods and ProxyFactory proxy factory in AOP analysis in Spring

1. Demonstration of two dynamic proxy methods

1.1 JDK dynamic proxy

The dynamic proxy of JDK is the process of dynamically generating the class file of the proxy class according to the proxy interface during the running process of the program, and loading and running. Requires that the proxied class must implement an interface. The following case

interface

public interface TargetInterface {
    public void say();
}

proxied class

public class Target implements TargetInterface{

    @Override
    public void say() {
        System.out.println("方法被执行了");
    }

}

Proxy test class

public class JDK_Proxy {

    public static void main(String[] args) {

        Target target = new Target();

        //jdk动态代理
        TargetInterface proxyInstance = (TargetInterface) Proxy.newProxyInstance(target.getClass().getClassLoader(),
                target.getClass().getInterfaces(),
                (proxy, method, args1) -> {
                    System.out.println("方法执行前");
                    Object invoke = method.invoke(target, args);
                    System.out.println("方法执行后");
                    return invoke;
                }
        );

        proxyInstance.say();

    }

}

output result

image-20220406184305506

1.2 CGLB dynamic proxy

Unlike the JDK dynamic proxy, the target class of cglib can not implement the interface

proxied class

public class CGLB_Target {


    public void say() {
        System.out.println("方法被执行了");
    }

}

Proxy test class

/**
 * @author sz
 * @DATE 2022/4/6  18:44
 */
public class CGLB_Proxy {

    public static void main(String[] args) {
        //创建一个增强器
        Enhancer enhancer = new Enhancer();
        //设置父类  也就是被代理的类
        enhancer.setSuperclass(CGLB_Target.class);
        //设置代理逻辑
        enhancer.setCallbacks(new Callback[]{new MethodInterceptor() {
            /**
             * @param o  代理类
             * @param method  目标方法
             * @param objects  方法参数
             * @param methodProxy  代理方法
             * @return
             * @throws Throwable
             */
            @Override
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                System.out.println("cglb增强_方法执行前");
                Object result = methodProxy.invokeSuper(o,objects);
                System.out.println("cglb增强_方法执行后");
                return result;
            }
        }});

        //创建代理类
        CGLB_Target cglb_target = (CGLB_Target) enhancer.create();

        cglb_target.say();
    }

}

output result

image-20220406185426992

2. ProxyFactory encapsulated by Spring

1. Simple use case of proxy factory ProxyFactory

proxied class

public class CGLB_Target {
    
    public void say() {
        System.out.println("方法被执行了");
    }

}

advance notice

public class MyBeforeAdvice implements MethodBeforeAdvice {


    @Override
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println("beanfactory ---> 方法执行前");
    }
}

Notify when you return

public class MyAfterReturnAdvice implements AfterReturningAdvice {

    @Override
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("beanfactory --->"+method.getName()+" 方法  返回值为 "+returnValue);
    }

}

exception notification

public class MyThrowsAdvice implements ThrowsAdvice {

    public void afterThrowing(Method method, Object[] args, Object target, Exception ex)
    {

        System.out.println("beanfactory ---> 方法执行抛出异常"+ex.getMessage());
    }

}

Create a proxy factory


        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.setTarget(new CGLB_Target());
        //前置通知
        proxyFactory.addAdvice(new MyBeforeAdvice());
        //返回后通知
        proxyFactory.addAdvice(new MyAfterReturnAdvice());
        //异常后通知
        proxyFactory.addAdvice(new MyThrowsAdvice());

        CGLB_Target proxy = (CGLB_Target) proxyFactory.getProxy();

        proxy.say();

Results of the

image-20220406193619157

2. Notification interface

  1. `MethodBeforeAdvice pre-advice
  2. `AfterReturningAdvice return notification
  3. `ThrowsAdvice notification after exception

3.Advisor

In Spring AOP, an aspect class consists of pointcuts and advice, and the same Advisor consists of pointcuts and advice.

If you want to proxy the say method in a class

  //创建代理工厂
        ProxyFactory proxyFactory = new ProxyFactory();
        //设置代理类
        proxyFactory.setTarget(new CGLB_Target());
        //创建advisore
        proxyFactory.addAdvisor(new PointcutAdvisor() {
            @Override
            public Pointcut getPointcut() {
               return new StaticMethodMatcherPointcut() {
                   @Override
                   public boolean matches(Method method, Class<?> targetClass) {
                        if ("say".equals(method.getName())){
                            return true;
                        }
                       return false;
                   }
               };
            }

            @Override
            public Advice getAdvice() {
                return new MyAfterReturnAdvice();
            }

            @Override
            public boolean isPerInstance() {
                return false;
            }
        });

        //创建代理类
        CGLB_Target proxy = (CGLB_Target) proxyFactory.getProxy();
        proxy.say();

Guess you like

Origin blog.csdn.net/JAVAlife2021/article/details/123999090