AOP development idea and underlying principle of Spring framework

AOP

1) Introduction to AOP

1.1)OOP development ideas

1.2)AOP development idea

1.3)AOP concept

  • AOP (aspect oriented programming) is a programming paradigm, which belongs to the category of software engineering and guides developers how to organize program structure
  • AOP makes up for the deficiency of OOP and carries out horizontal development based on OOP
    • uOOP stipulates that the program development takes the class as the main model, everything is carried out around the object, and the model is built before completing a task
    • uAOP program development mainly focuses on the common functions in OOP based development. Everything is carried out around the common functions. To complete a task, first build all the common functions that may be encountered (when all functions are developed, there is no difference between common and non common functions)
  • "AOP alliance"

1.4)AOP function

  • With the advent of AOP era, we can start with the standardization and standardization of various industries, develop all common functions step by step, and finally complete the development of individual business modules and even the overall business system with function combination
  • Objective: to move the software development from manual production to semi-automatic / fully automatic stage, and realize the construction of "plug-in component architecture"

1.5)AOP advantages

  • Improve code reusability
  • More concise business code
  • More efficient business code maintenance
  • More convenient business function expansion

2)AOP introduction case

2.1)AOP related concepts


  • Joinpoint: is the method
  • Pointcut: it is the method to dig out common functions
  • Advice: it is a common function, which is finally presented in the form of a method
  • Aspect: refers to the corresponding relationship between common functions and the location of excavation
  • Target: refers to the object generated by digging out the class corresponding to the function method. This kind of object cannot directly complete the final work
  • Weaving: the dynamic process of backfilling the excavated function
  • Proxy: the target object cannot complete the work directly, so it needs to be backfilled with functions, which can be realized by creating the proxy object of the original object
  • Introduction: it refers to adding member variables or member methods to the original object out of nothing

2.2)AOP development process

  • Development phase (completed by the developer)
    • Normal production procedure
    • Develop the non common functions into the corresponding target object classes, and make them into entry point methods
    • Develop the common functions independently and make them into notices
    • In the configuration file, declare the pointcut
    • In the configuration file, declare the relationship between the pointcut and the notification (including the notification type), that is, the aspect
  • Operation phase (AOP completed)
    • The Spring container loads the configuration file and monitors the execution of all configured pointcut methods
    • When it is monitored that the pointcut method is running, the proxy mechanism is used to dynamically create the proxy object of the target object. According to the notification category, the corresponding function of the notification is woven into the corresponding position of the proxy object to complete the complete code logic and run

2.2)AOP development mode

  • XML mode
  • XML + annotation method
  • Annotation method

2.3) introduction case production analysis

1. import relevant coordinates

2. Confirm the function to be extracted, make it into a method, save it to a special class, and delete the corresponding function in the original business

3. Load all resources for AOP operations into IoC container

4. Describe the location of the extracted function in the way of configuration, and describe the relationship between the extracted function and the corresponding location

5. Operation procedure

Step 1: import coordinates

<dependency>
    <groupId>org.aspectj</groupId>
    <artifactId>aspectjweaver</artifactId>
    <version>1.9.4</version>
</dependency>

Step 2: extract common codes in the business layer

Step 3 add the notification to the spring container management

Step 4: configure the aop configuration in the configuration file

<!--aop to configure-->
<aop:config>
    <!--Configure pointcuts-->
    <aop:pointcut id="pt" expression="execution(* *..*())"/>
    <!--Configuration section-->
    <aop:aspect ref="myAdvice">
        <!—Relationship between notifications and pointcuts-->
        <aop:before method="logAdvice" pointcut-ref="pt"/>
    </aop:aspect>
</aop:config>

3)AOP configuration (XML)

3.1)AspectJ

  • Aspect is used to describe the relationship between pointcuts and notifications. It is a concept in AOP programming
  • AspectJ is an implementation of Aspect based on java language

3.2)AOP configuration

3.2.1)aop:config

  • Name: aop:config

  • Type: Label

  • Attribution: beans tag

  • Function: set AOP

  • Format:

    <beans>
        <aop:config>......</aop:config>
        <aop:config>......</aop:config>
    </beans>
    
  • Note: multiple aop:config tags can be configured in one beans tag

3.2.2)aop:aspect

  • Name: aop:aspect

  • Labels: Types

  • Attribution: aop:config tag

  • Function: set the entry point corresponding to the specific AOP notification

  • Format:

    <aop:config>
        <aop:aspect ref="beanId">......</aop:aspect>
        <aop:aspect ref="beanId">......</aop:aspect>
    </aop:config>
    
  • explain:

    Multiple aop:aspect tags can be configured in one aop:config tag

  • Basic properties:

    • ref: the id of the bean where the notification is located

3.2.3)aop:pointcut

  • Name: aop:pointcut

  • Type: Label

  • Attribution: aop:config tag, aop:aspect tag

  • Function: set entry point

  • Format:

    <aop:config>
        <aop:pointcut id="pointcutId" expression="......"/>
        <aop:aspect>
            <aop:pointcut id="pointcutId" expression="......"/>
        </aop:aspect>
    </aop:config>
    
  • explain:

    Multiple aop:pointcut tags can be configured in one aop:config tag, and the tag can be configured in the aop:aspect tag

  • Basic properties:

    • id: the name that identifies the pointcut
    • Expression: pointcut expression

3.3) entry point

  • Pointcuts describe a method
  • Pointcut expression is a generic format described by a fast matching method, which is similar to regular expression

3.4) composition of pointcut expression

  • Pointcuts describe a method

  • Pointcut expression is a generic format described by a fast matching method, which is similar to regular expression

    Keyword (access modifier) return value package name.Class name.Method name (parameter) (exception name)
    

Keyword: describes the matching pattern of the expression (see keyword list)

Access modifier: the access control permission modifier of the method

Class name: the class where the method is located (interface name can be configured here)

Exception: the exception thrown as specified in the method definition

  • example:

    execution(public User com.itheima.service.UserService.findById(int))
    

3.4.1) pointcut expression - Keyword

  • Execution: matches the execution of the specified method
  • args: matches the method with the specified parameter type
  • within : ......
  • this : ......
  • target : ......
  • @within : ......
  • @target : ......
  • @args : ......
  • @annotation : ......
  • bean : ......
  • reference pointcut : ......

3.4.2) pointcut expression - wildcard

  • *: any single independent symbol, which can appear independently or as a match for prefix or suffix

    execution(public * com.itheima.*.UserService.find*(*))
    

Match com The UserService class in any package under itheima package or all methods with one parameter starting with find in the interface

  • ...: multiple consecutive arbitrary symbols that can appear independently. They are often used to simplify the writing of package names and parameters

    execution(public User com..UserService.findById(..))
    

Match all methods named findById in UserService class or interface in any package under com package

  • +: specific to matching subclass types

    execution(* *..*Service+.*(..))
    

3.4.3) pointcut expression - logical operator

  • &&: connect two pointcut expressions, indicating that the two pointcut expressions are matched at the same time
  • ||: connect two pointcut expressions, indicating that any one of the two pointcut expressions matches
  • ! : Connect a single pointcut expression, indicating that the pointcut expression is not a valid match

3.4.4) pointcut expression - Example

execution(* *(..))
execution(* *..*(..))
execution(* *..*.*(..))
execution(public * *..*.*(..))
execution(public int *..*.*(..))
execution(public void *..*.*(..))
execution(public void com..*.*(..)) 
execution(public void com..service.*.*(..))
execution(public void com.itheima.service.*.*(..))
execution(public void com.itheima.service.User*.*(..))
execution(public void com.itheima.service.*Service.*(..))
execution(public void com.itheima.service.UserService.*(..))
execution(public User com.itheima.service.UserService.find*(..))
execution(public User com.itheima.service.UserService.*Id(..))
execution(public User com.itheima.service.UserService.findById(..))
execution(public User com.itheima.service.UserService.findById(int))
execution(public User com.itheima.service.UserService.findById(int,int))
execution(public User com.itheima.service.UserService.findById(int,*))
execution(public User com.itheima.service.UserService.findById(*,int))
execution(public User com.itheima.service.UserService.findById())
execution(List com.itheima.service.*Service+.findAll(..))

3.5) three configurations of entry points

<aop:config>
    <!--Configure common pointcuts-->
    <aop:pointcut id="pt1" expression="execution(* *(..))"/>
    <aop:aspect ref="myAdvice">
        <!--Configure local pointcuts-->
        <aop:pointcut id="pt2" expression="execution(* *(..))"/>
        <!--Reference public pointcuts-->
        <aop:before method="logAdvice" pointcut-ref="pt1"/>
        <!--Reference local pointcuts-->
        <aop:before method="logAdvice" pointcut-ref="pt2"/>
        <!--Direct configuration entry point-->
        <aop:before method="logAdvice" pointcut="execution(* *(..))"/>
    </aop:aspect>
</aop:config>

3.6) entry point configuration experience

  • The naming standard of enterprise development shall strictly follow the standard documents
  • Configure local pointcuts for the method first
  • Then extract the public pointcuts in the class
  • Finally, extract the global entry point
  • In the process of code walkthrough, check whether the pointcut has out of bounds inclusion
  • In the process of code walkthrough, check whether the entry point has non inclusive entry
  • Set the AOP execution detection program to monitor whether the number of notifications executed matches the expected number in the unit test
  • If the set entry point is adjusted, the regression test must be carried out

(the above rules apply to XML configuration format)

3.7) notification type

There are five types of AOP notifications

  • Pre notification: execute before the original method is executed. If an exception is thrown in the notification, the original method will be prevented from running

    Application: data verification

  • Post notification: after the original method is executed, the notification will be executed regardless of whether there is an exception in the original method

    Application: site cleaning

  • Notification after return: the original method executes normally and returns the result. If an exception is thrown in the original method, it cannot be executed

    Application: return value related data processing

  • Notification after exception thrown: the original method is executed after throwing an exception. If the original method does not throw an exception, it cannot be executed

    Application: handle the abnormal information in the original method

  • Surround notification: there is corresponding execution before and after the execution of the original method. It can also prevent the execution of the original method

    Application: very powerful and can do anything

3.7.1)aop:before

  • Name: aop:before

  • Labels: Types

  • Attribution: aop:aspect tag

  • Function: set pre notification

  • Format:

    <aop:aspect ref="adviceId">
        <aop:before method="methodName" pointcut="......"/>
    </aop:aspect>
    
  • Note: multiple aop:before tags can be configured in one aop:aspect tag

  • Basic properties:

    • Method: set the method corresponding to the current notification category in the notification class
    • Pointcut: sets the pointcut expression corresponding to the current notification, which conflicts with the pointcut ref attribute
    • Pointcut Ref: sets the pointcut id corresponding to the current notification, which conflicts with the pointcut property

3.7.2)aop:after

  • Name: aop:after

  • Labels: Types

  • Attribution: aop:aspect tag

  • Post notification: setting post notification

  • Format:

    <aop:aspect ref="adviceId">
        <aop:after method="methodName" pointcut="......"/>
    </aop:aspect>
    
  • Note: multiple aop:after tags can be configured in one aop:aspect tag

  • Basic properties:

    • Method: set the method corresponding to the current notification category in the notification class
    • Pointcut: sets the pointcut expression corresponding to the current notification, which conflicts with the pointcut ref attribute
    • Pointcut Ref: sets the pointcut id corresponding to the current notification, which conflicts with the pointcut property

3.7.3)aop:after-returning

  • Name: AOP: after returning

  • Labels: Types

  • Attribution: aop:aspect tag

  • Function: set notification after return

  • Format:

    <aop:aspect ref="adviceId">
        <aop:after-returning method="methodName" pointcut="......"/>
    </aop:aspect>
    
  • Note: multiple AOP: after returning tags can be configured in one aop:aspect tag

  • Basic properties:

    • Method: set the method corresponding to the current notification category in the notification class
    • Pointcut: sets the pointcut expression corresponding to the current notification, which conflicts with the pointcut ref attribute
    • Pointcut Ref: sets the pointcut id corresponding to the current notification, which conflicts with the pointcut property

3.7.4)aop:after-throwing

  • Name: AOP: after throwing

  • Labels: Types

  • Attribution: aop:aspect tag

  • Function: set the notification after throwing an exception

  • Format:

    <aop:aspect ref="adviceId">
        <aop:after-throwing method="methodName" pointcut="......"/>
    </aop:aspect>
    
  • Note: multiple AOP: after throwing tags can be configured in one aop:aspect tag

  • Basic properties:

    • Method: set the method corresponding to the current notification category in the notification class
    • Pointcut: sets the pointcut expression corresponding to the current notification, which conflicts with the pointcut ref attribute
    • Pointcut Ref: sets the pointcut id corresponding to the current notification, which conflicts with the pointcut property

3.7.5)aop:around

  • Name: aop:around

  • Labels: Types

  • Attribution: aop:aspect tag

  • Function: set surround notification

  • Format:

    <aop:aspect ref="adviceId">
        <aop:around method="methodName" pointcut="......"/>
    </aop:aspect>
    
  • Note: multiple aop:around tags can be configured in one aop:aspect tag

  • Basic properties:

    • Method: set the method corresponding to the current notification category in the notification class
    • Pointcut: sets the pointcut expression corresponding to the current notification, which conflicts with the pointcut ref attribute
    • Pointcut Ref: sets the pointcut id corresponding to the current notification, which conflicts with the pointcut property

Development method of surround notification

  • Wrap notification is to add functions before and after the original method. In wrap notification, there are explicit calls to the original method

    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object ret = pjp.proceed();
        return ret;
    }
    
  • Description of surrounding notification method:

    • Method must set the return value of Object type, otherwise the return of the original method will be intercepted. If the return value type of the original method is void, the notifier can also set the return value type to void and finally return null
    • Method needs to set the ProceedingJoinPoint object at the first parameter position, and call the processed () method through this object to call the original method. If this parameter is omitted, the original method cannot be executed
    • When using the processed () method to call the original method, because it is impossible to predict whether an exception will occur during the operation of the original method, the Throwable object is forcibly thrown to encapsulate the possible exception information in the original method

3.8) order of notice (understand)

When multiple notifications are configured for the same entry point, there will be a running sequence of notifications, which is subject to the sequence of notification configuration

3.9) notification of data acquisition

  • parameter
  • Return value
  • abnormal

3.9.1) notify to obtain parameter data

First case:

  • Set the first parameter of the notification method as JoinPoint, and call the getArgs() method through this object to obtain the parameter array of the original method

    public void before(JoinPoint jp) throws Throwable {
        Object[] args = jp.getArgs();
    }
    
  • All notifications can get parameters

The second case:

  • Set the pointcut expression to pass parameters to the notification method (lock the notification variable name)
  • Original method

The third case

  • Set the pointcut expression to pass parameters to the notification method (change the definition order of notification variable names)
  • Original method

3.9.2) notify to obtain return value data

First: return value variable name

  • Set return value variable name

  • Original method

    public int save() {
    	System.out.println("user service running...");
        return 100;
    }
    
  • AOP configuration

  <aop:aspect ref="myAdvice">
      <aop:pointcut id="pt3" expression="execution(* *(..))  "/>
      <aop:after-returning method="afterReturning" pointcut-ref="pt3" returning="ret"/>
  </aop:aspect>
  • Notification class

    public void afterReturning(Object ret) {
        System.out.println(ret);
    }
    
  • Applicable to after returning notification

Second:

  • In the middle note method, the original method is called to get the return value.

  • Original method

    public int save() {
        System.out.println("user service running...");
        return 100;
    }
    
  • AOP configuration l

    <aop:aspect ref="myAdvice">
        <aop:pointcut id="pt2" expression="execution(* *(..))  "/>
        <aop:around method="around" pointcut-ref="pt2" />
    </aop:aspect>
    
  • Notification class

    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object ret = pjp.proceed();
        return ret;
    }
    
  • For around notification

3.9.3) notify to obtain abnormal data

The middle note: calling the original method to capture the exception in the notification class method.

  • Calling the original method to catch exceptions in middle note method

  • Original method

    public void save() {
        System.out.println("user service running...");
        int i = 1/0;
    }
    
  • AOP configuration

  <aop:aspect ref="myAdvice">
      <aop:pointcut id="pt4" expression="execution(* *(..))  "/>
      <aop:around method="around" pointcut-ref="pt4" />
  </aop:aspect>
  • Notification class

    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object ret = pjp.proceed();	//try... Catch... On the call here to catch exceptions or throw exceptions
        return ret;
    }
    
  • For around notification

Second:

  • Set exception object variable name

  • Original method

    public void save() {
        System.out.println("user service running...");
        int i = 1/0;
    }
    
  • AOP configuration

  <aop:aspect ref="myAdvice">
  	<aop:pointcut id="pt4" expression="execution(* *(..))  "/>
      <aop:after-throwing method="afterThrowing" pointcut-ref="pt4" throwing="t"/>
  </aop:aspect>
  • Notification class

    public void afterThrowing(Throwable t){
        System.out.println(t.getMessage());
    }
    
  • Applicable to after throwing

4)AOP configuration (note)

4.1)AOP configuration

4.2) annotation development AOP production steps

Based on XML format

  • Import coordinates (with spring context coordinates, the import has been completed depending on the import)
  • Enable AOP annotation support
  • Configure Aspect @ Aspect
  • Define a dedicated Pointcut method and configure the Pointcut @ Pointcut
  • Configure notification type and corresponding pointcut @ Before for notification method

4.3) notes on AOP development

1. The entry point is finally embodied as a method, with no parameters, no return value and no actual method body content, but it cannot be an abstract method

2. When referring to the pointcut, the method call name must be used, and the () after the method cannot be omitted

3. The pointcuts defined in the aspect class can only be used in the current class. If you want to reference the pointcuts defined in other classes, use "class name. Method name ()" to reference

4. You can add parameters after the notification type annotation to realize the attributes in XML configuration, such as the returning attribute after after returning

4.4)AOP annotation details

4.4.1)@Aspect

  • Name: @ Aspect

  • Type: Annotation

  • Location: above class definition

  • Function: set the current class as the section class

  • Format:

    @Aspect
    public class AopAdvice {
    }
    
  • Note: multiple aop:config tags can be configured in one beans tag

4.4.2)@Pointcut

  • Name: @ Pointcut

  • Type: Annotation

  • Location: above method definition

  • Function: use the current method name as the pointcut reference name

  • Format:

    @Pointcut("execution(* *(..))")
    public void pt() {
    }
    
  • Note: the modified method ignores its business function. The format is set as a method with no parameters and no return value. The method body is empty (non Abstract)

4.4.3)@Before

  • Name: @ Before

  • Type: Annotation

  • Location: above method definition

  • Function: label the current method as a pre notification

  • Format:

    @Before("pt()")
    public void before(){
    }
    
  • Special parameters:

    • nothing

4.4.4)@After

  • Name: @ After

  • Type: Annotation

  • Location: above method definition

  • Function: label the current method as a post notification

  • Format:

    @After("pt()")
    public void after(){
    }
    
  • Special parameters:

    • nothing

4.4.5)@AfterReturning

  • Name: @ AfterReturning

  • Type: Annotation

  • Location: above method definition

  • Function: mark the current method as notification after return

  • Format:

    @AfterReturning(value="pt()",returning = "ret")
    public void afterReturning(Object ret) {
    }
    
  • Special parameters:

    • returning: sets the variable name that receives the return value using the notification method parameter

4.4.6)@AfterThrowing

  • Name: @ AfterThrowing

  • Type: Annotation

  • Location: above method definition

  • Function: mark the current method as notification after exception

  • Format:

    @AfterThrowing(value="pt()",throwing = "t")
    public void afterThrowing(Throwable t){
    }
    
  • Special parameters:

    • throwing: sets the object name of the exception thrown in the original method to be received using the notification method parameter

4.4.7)@Around

  • Name: @ Around

  • Type: Annotation

  • Location: above method definition

  • Purpose: label the current method as a surround notification

  • Format:

    @Around("pt()")
    public Object around(ProceedingJoinPoint pjp) throws Throwable {
        Object ret = pjp.proceed();
        return ret;
    }
    
  • Special parameters:

    • nothing

4.5)AOP annotation development notice execution sequence control (understanding)

1. When AOP is configured with XML, the execution order of the notification is determined by the configuration order. In the case of annotation, since there is no concept of configuration order, it can be simply understood as alphabetic sorting by referring to the coding value order corresponding to the method name string configured in the notification

  • In the same notification class, the same notification type is subject to the sorting of method name
  • In different notification classes, the order of class name shall prevail
  • Use the @ Order annotation to change the loading Order of notifications by changing the loading Order of bean s

2. Enterprise development experience

  • The notification method name consists of three parts: prefix, sequence code and function description
  • The prefix is a fixed string, such as baidu, itheima, etc., which has no practical significance
  • The sequence code is an integer within 6 bits, usually 3 bits, and the insufficient bits are supplemented by 0
  • The function description is the actual notification function corresponding to the method, such as exception and strLenCheck
    • The execution sequence of the notification system is controlled by sequence coding, and a certain space is reserved during use
    • 003 used, 006 used, 001, 002, 004, 005, 007, 008 reserved
    • When using, it starts from the middle section, which is convenient for pre addition or post addition in the later stage
    • The final sequence shall be subject to the operation sequence, the test results and not the set rules

4.6)AOP annotation driven

  • Name: @ EnableAspectJAutoProxy

  • Type: Annotation

  • Location: above the Spring annotation configuration class definition

  • Function: set the current class to enable AOP annotation driven support and load AOP annotations

  • Format:

    @Configuration
    @ComponentScan("com.itheima")
    @EnableAspectJAutoProxy
    public class SpringConfig {
    }
    

5) Comprehensive case

5.1) case introduction

Monitor the implementation of the business layer interface of the project and measure the implementation efficiency of the business layer interface

public interface AccountService {
    void save(Account account);
    void delete(Integer id);
    void update(Account account);
    List<Account> findAll();
    Account findById(Integer id);
}

5.2) case analysis

  • Measure the execution efficiency of the interface: obtain the execution time before and after the execution of the interface method, and calculate the execution time
    • System.currentTimeMillis( )
  • Monitor the project: all interface methods in the project, AOP ideas, and dynamically weave code during execution
    • Around Advice
    • The processed () method obtains the system time before and after execution

5.3) case making steps

  • Define pointcuts (be sure to bind to interfaces, not interface implementation classes)
  • Make AOP surround notification and complete the measurement function
  • Annotation configuration AOP
  • Enable annotation driven support

5.4) core code of case making

public class RunTimeMonitorAdvice {
    //Intercept the execution of query operations in all business layer interfaces
    @Pointcut("execution(* com.itheima.service.*Service.find*(..))")
    public void pt(){}
    @Around("pt()")
    public Object runtimeMonitor(ProceedingJoinPoint pjp) throws Throwable {
        //Get execution signature information
        Signature signature = pjp.getSignature();
        //Get execution type (interface name) by signature
        String targetClass = signature.getDeclaringTypeName();
        //Obtain the execution operation name (method name) through signature
        String targetMethod = signature.getName();
        //Get the pre operating system time beginTime
        long beginTime = System.currentTimeMillis();
        Object ret = pjp.proceed(pjp.getArgs());
        //Get the system time endTime after operation
        long endTime = System.currentTimeMillis();
        System.out.println(targetClass+" in "+targetMethod+" Run time "+(endTime-beginTime)+"ms");
        return ret;
    }
}

5.5) case follow-up thinking and design

  • Measurement authenticity
    • Development measurement is an isolated and repeated operation, which is an ideal situation. The difference between on-line measurement is too large
    • The performance of online measurement server is slightly lower than that of single machine development measurement
    • Online measurement cache based performance query is better than database query measurement
    • The performance of the on-line measurement interface is too different from that of the final external service
    • When external conditions change (hardware), regression testing is required, such as database migration
  • Display of measurement results
    • The measurement results do not need to be displayed every time, and the detection threshold needs to be set
    • The threshold setting should be distinguished according to the business. A complex query is very different from a simple query
    • Threshold setting requires independent configuration files or configuration through graphical tools (tool level development)
    • Display the measurement results with the graphical interface

6)AOP underlying principle

  • Static proxy
  • Dynamic Proxy proxy
  • Dynamic agent - CGLIB
  • Weaving form

6.1) static agent

Decorator Pattern: add functions to the original design without disturbing it

public class UserServiceDecorator implements UserService{
    private UserService userService;
    public UserServiceDecorator(UserService userService) {
        this.userService = userService;
    }
    public void save() {
        //Original call
        userService.save();
        //Enhancements (rear)
        System.out.println("Scrape white");
    }
}

6.2) dynamic proxy - JDK Proxy

JDKProxy dynamic proxy is a proxy for objects. The original object is required to have interface implementation, and the interface method is enhanced

public class UserServiceJDKProxy {
    public UserService createUserServiceJDKProxy(final UserService userService){
        //Gets the class loader of the proxied object
        ClassLoader classLoader = userService.getClass().getClassLoader();
        //Get the interface implemented by the proxy object
        Class[] classes = userService.getClass().getInterfaces();
        //Intercept and enhance the original method execution
        InvocationHandler ih = new InvocationHandler() {
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                //Pre enhanced content
                Object ret = method.invoke(userService, args);
                //Post enhancement
                System.out.println("Scraping White 2");
                return ret;
            }
        };
        //Creates a new proxy object using the original proxy object
        UserService proxy = (UserService) Proxy.newProxyInstance(classLoader,classes,ih);
        return proxy;
    }
}

6.3) dynamic agent - CGLIB

  • CGLIB(Code Generation Library)
  • CGLIB dynamic agent does not limit whether it has an interface, and can enhance any operation
  • CGLIB dynamic proxy does not need the original proxy object, and dynamically creates a new proxy object

public class UserServiceImplCglibProxy {
    public static UserServiceImpl createUserServiceCglibProxy(Class clazz){
        //Create Enhancer object (it can be understood as the bytecode of a class dynamically created in memory)
        Enhancer enhancer = new Enhancer();
        //Sets that the parent class of the Enhancer object is the specified type UserServerImpl
        enhancer.setSuperclass(clazz);
        Callback cb = new MethodInterceptor() {
            public Object intercept(Object o, Method m, Object[] a, MethodProxy mp) throws Throwable {
                Object ret = mp.invokeSuper(o, a);
                if(m.getName().equals("save")) {
                    System.out.println("Scrape white");
                }
                return ret;
            }
        };
        //Set callback method
        enhancer.setCallback(cb);
        //Use the Enhancer object to create the corresponding object
        return (UserServiceImpl)enhancer.create();
    }
}

6.4) selection of agency mode

Spirng can control the proxy form through configuration. jdkproxy is used by default, and cglib can be modified through configuration

  • XML configuration

    <!--XMP to configure AOP-->
    <aop:config proxy-target-class="false"></aop:config>
    
  • XML annotation support

    <!--Annotation configuration AOP-->
    <aop:aspectj-autoproxy proxy-target-class="false"/>
    
  • Annotation driven

    //Annotation driven
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    

6.5) weaving timing

Tags: Spring AOP

Posted by alisam on Sat, 16 Apr 2022 23:40:03 +0300