Aspect-Oriented Programming (AOP) in Architecture Adventures (Part 1)

Writing code should be a spiral process from complex to simple, and then from simple to complex.

 

        A very important feature in Spring is Aspect Oriented Programming (AOP). Suppose such a scenario, if there is a piece of logic that many methods need before or after execution, what would we do? We try to think about this from one extreme to the other. From an extreme, if the number of methods that need this logic is very small and only one, we can directly call this logic at the front or the back of the aspect, how simple it is, like this:

public void function(){
    commonBegin();
    ...
    commonEnd();
}

         When such methods change from one to two or three, we will see two or three similar methods, and then when the number of methods becomes particularly large, we will see a bunch of such methods, when not only When a Begin or End contains other Begins and Ends, as the code continues to increase, the code looks like a man with a horse pole.

        So how can we make such a problem simpler? Find an agent~

        1. Static proxy:

        First of all, we can try to find a static proxy. It is obvious that a static proxy is who is who, a one-to-one service, like this (for example, your sequence of methods belongs to the behavior of some customers ):

public class Proxy implements Cliemt{    
    private Client client; //Client is just one of the customer classes
    public Proxy(Client client){
        this.client = client;
   }
    public void buy(){
        doSomething();
        client.buy(); //The customer's job is to buy, buy, buy
    }
}

         In this case, there is no need to write those pre- or post-logic logic in the customer method, and the agent can implement this part, which ensures the innocence of the customer. However, however, this is not just like the customer class. Are there more proxy classes? Not only did the code not decrease, but instead doubled.

       2. JDK dynamic proxy:

        If a static proxy doesn't work, look for a dynamic proxy. The dynamic proxy will produce the corresponding proxy class according to your class. First, let's look at the implementation mechanism of JDK's dynamic proxy. In a static proxy, how many classes need to implement the same common logic need to correspond to how many static proxy classes. If the proxy object type in the proxy class is not specified, that is, if ClientImpl is not specified before, then the call control of a proxy can be abstracted. The controller uses the reflection mechanism to call the method of the specific object in the controller:

public class DynamicInvocationHandler implements InvocationHandler{
     private Object object;
     public DynamicInvocationHandler (Object object){
         this.object = object;
     }

     public Object invoke(Object proxy, Method method, Object... params){
         return method.invoke(object, params);  // try
     }
}

         Then we can dynamically generate our proxy based on our calling controller via Proxy in Java:

Client client= new ClientImpl();
DynamicInvocationHandler handler = new DynamicInvocationHandler (client);
Client clientProxy = (Client ) Proxy.newInstance(client.getClass().getClassLoader(), client             .getClass().getInterfaces(), handler);

         3. CGLIB dynamic proxy:

        JDK dynamic proxy requires the class to implement the corresponding interface. If it is for a class without an interface, CGlib can be used to implement it. The implementation method is roughly like this:

public class CGLibInterceptor implements MethodInterceptor{
     public Object intercept(Object object, Method method, Object... params, MethodProxy proxy){
         return proxy.invokeSuper(object, params);  // try
     }
}

         Then you can create proxy objects through Enhance's create method:

CGLibInterceptor cglibInterceptor = new CGLibInterceptor();
Hello helloProxy = (Hello)Enhancer.create(Hello.class, cglibInterceptor);
helloProxy.say("````");

          With dynamic proxy, when we call specific logic before or after a method of a class, we can create a dynamic proxy object, and the specific logic is placed in InvocationHandler or MethodInterceptor, and these two classes can be viewed as Cheng is the intermediary of dynamic agents. With this intermediary, no matter what class can create corresponding dynamic agents as needed, it saves the trouble of writing a bunch of static agents, and the specific logic in this intermediary is actually the medium of AOP. Sliced ​​(to be continued~)

Guess you like

Origin http://10.200.1.11:23101/article/api/json?id=326699335&siteId=291194637