Spring AOP

I. AOP (Concept)

1. What is AOP

  • Section-oriented programming (aspect), using AOP can be isolated to each part of the business logic, so that the coupling degree between each part of the business logic is reduced, improve the reusability of the program, and improve the efficiency of development

  • Common description: To add new functionality to the trunk functionality without modifying the source code

  • Use login examples to illustrate AOP:

2. AOP underlying principles

  • AOP uses dynamic proxies underneath

    1. In the case of interfaces, use JDK dynamic proxies: create proxy objects that implement the interface class and enhance the class’s methods

    2. Without an interface, use CGLIB dynamic proxies: create subclass proxy objects and enhance class methods

3. AOP(JDK Dynamic Proxy)

  • Using the JDK dynamic Proxy, create Proxy objects using methods in the Proxy class

    1. Call the newProxyInstance static method with three arguments:

      public static Object newProxyInstance(ClassLoader loader, Class
                 [] interfaces, InvocationHandler h)
      Copy the code

      First parameter: class loader

      The second argument: the class of the enhanced method, which implements the method, supports multiple interfaces

      The third argument: the created proxy object implements the InvocationHandler interface, which writes the logic code, which is the enhanced part

    2. Write JDK dynamic proxy code

      1. Create interfaces and define methods

        public interface UserDao {
            int add(int a, int b);
            String update(String id);
        }
        Copy the code
      2. Create interface implementation classes and implement methods

        public class UserDaoImpl implements UserDao {
            @Override
            public int add(int a, int b) {
                System.out.println("Add method executed......");
                return a + b;
            }
        
            @Override
            public String update(String id) {
                System.out.println("Update method executed......");
                returnid; }}Copy the code
      3. Use the Proxy class to create interface Proxy objects

        public class JDKProxy {
            public static void main(String[] args) {
                // Create an interface implementation class proxy object
                Class[] interfaces = {UserDao.class};
                UserDaoImpl userDao = new UserDaoImpl();
                
                UserDao dao = (UserDao)Proxy.newProxyInstance(JDKProxy.class.getClassLoader(), interfaces, new UserDaoProxy(userDao));
                
                int result = dao.add(1.2);
                System.out.println("result: "+ result); }}Copy the code
      4. Create the proxy object code

        class UserDaoProxy implements InvocationHandler {
        
            private Object obj;
            public UserDaoProxy(Object obj) {
                this.obj = obj;
            }
        
            // Enhanced logic
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                // before the method
                System.out.println("Method before executing......" + method.getName() + ", passed parameters" + Arrays.toString(args));
        
                // The enhanced method executes
                Object res = method.invoke(obj, args);
        
                // After the method
                System.out.println("Execute...... after method" + obj);
        
                returnres; }}Copy the code

4. AOP terminology

  1. ** join points: Which methods in the ** class can be enhanced are called join points
  2. ** pointcuts: ** The methods that are actually enhanced are called pointcuts
  3. ** Notification (enhancement) : ** The logical part of the actual enhancement, called notification
    • There are many types of notifications:
      • Pre notice
      • The rear notice
      • Surrounding the notification
      • Final notice
      • Abnormal notice
  4. ** Aspect: ** The process of applying advice to a pointcut is called aspect (which is an action process)

5. AOP operation

  • The Spring framework generally implements AOP operations based on AspectJ

    • AspectJ is not part of the Spring framework, but is an independent AOP framework. Spring and AspectJ are commonly used together for AOP operations
  • Implement AOP operations based on AspectJ

    • Implemented based on XML configuration files
    • Annotation-based implementation (common)
  • Import relevant JAR packages

  • Pointcut expressions (important) :

    • Pointcut expressions are used to know which methods in which classes are enhanced

    • Execution ([permission modifier] [return type] [full class name] [method name]([parameter list]))

      • The permission modifier can be omitted, but the return value type (which can be replaced by *) must be written!!!
      • Parameter lists are available.Represents an automatic match parameter list
    • Examples are as follows:

      // Add in com.atguigu.dao.bookdaoexecution(* com.atguigu.dao.BookDao.add(..) )// Enhance all methods in the com.atguigu.dao.bookdao classexecution(* com.atguigu.dao.BookDao.* (..) )// Enhance all classes and methods in the com.atguigu.dao packageexecution(* com.atguigu.dao.*.* (..) )Copy the code

2. AOP operations (AspectJ annotations)

1. Create a class and define methods in it

public class User {
    public void add(a) {
        System.out.println("add......"); }}Copy the code

2. Create enhancement classes (write enhancement logic)

  • Create methods in the enhanced class so that different methods represent different notification types
public class UserProxy {
    // Pre-notification
    public void before(a) {
        System.out.println("before......"); }}Copy the code

3. Configure the notification function

  1. In the Spring configuration file, turn on annotation scanning

    • To add these two tags:contextandaop:
    
            <beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"       xmlns:context="http://www.springframework.org/schema/context"       xmlns:aop="http://www.springframework.org/schema/aop"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">    <! -- Enable annotation scan -->    <context:component-scan base-package="com.atguigu.spring5.aopanno"></context:component-scan>    <! -- Enable Aspect generation proxy object -->    <aop:aspectj-autoproxy></aop:aspectj-autoproxy></beans>A
    Copy the code
  2. Create User and UserProxy using annotations

    // The enhanced class @ComponentPublic class User {... }// Class @componentPublic Class UserProxy {... }
    Copy the code
  3. Add the @aspect annotation to the annotation of the enhanced class

    // Enhanced class @Component@Aspectpublic class UserProxy {... }
    Copy the code
  4. Enable proxy object generation in the Spring configuration file

    <! -- Enable Aspect generation proxy object --><aop:aspectj-autoproxy></aop:aspectj-autoproxy>
    Copy the code

4. Configure different types of notification

  • In the enhanced class, add the annotation of the notification type above the notification method, using only the pointcut expression configuration

    @Component/ / generated proxy objects @ Aspectpublic class prior notification UserProxy {/ / @ Before execution (value = "(. * com. Atguigu spring5. Aopanno. User. The add (..) )") public void before() { System.out.println("before......" ); } / / rear notice (return) @ After (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) )") public void after() { System.out.println("after......" ); } / / final notice @ AfterReturning (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) )") public void afterReturning() { System.out.println("afterReturning......" ); } / / exception notification @ AfterThrowing (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) )") public void afterThrowing() { System.out.println("afterThrowing......" ); } / / notify @ Around round (value = "execution (* com. Atguigu. Spring5. Aopanno. User. The add (..) )") public void around(ProceedingJoinPoint ProceedingJoinPoint) throws Throwable {system.out.println (" surround before......") ); proceedingJoinPoint.proceed(); System.out.println(" surround after......" ); }}
    Copy the code

5. Same pointcut extraction

  • Extract pointcut expressions

    @Pointcut(value = "execution(* com.atguigu.spring5.aopanno.User.add(..) )"public void pointdemo(a) {}@Before(value = "pointdemo()")public void before(a) {    System.out.println("before......"); }Copy the code

6. If multiple enhancement classes enhance the same method, set the enhancement priority

  • Add the annotation @ORDER (numeric type value) above the enhanced class, with a small number indicating a higher priority

    @Component@Aspect@Order(3)public class PersonProxy {}@Component@Aspect@Order(1) Public class UserProxy {}
    Copy the code

7. Fully annotated development

  • To create a configuration class, you do not need to create an XML configuration file

    @Configuration@ComponentScan(basePackages = {"com.atguigu"})@EnableAspectJAutoProxy(proxyTargetClass = true)public class ConfigAOP {}
    Copy the code

3. AOP operations (AspectJ configuration files)

1. Create two classes, the enhanced class and the enhanced class, and create methods in the class

2. Create two objects in the Spring configuration file

<! Create object -->
<bean id="book" class="com.atguigu.spring5.aopxml.Book"></bean>
<bean id="bookProxy" class="com.atguigu.spring5.aopxml.BookProxy"></bean>
Copy the code

3. Configure pointcuts and facets in the Spring configuration file

<! Configure AOP enhancement -->
<aop:config>
    <! -- entry point -->
    <aop:pointcut id="p" expression="execution(* com.atguigu.spring5.aopxml.Book.buy(..) )"/>
    <! -- Configuration section -->
    <aop:aspect ref="bookProxy">
        <aop:before method="before" pointcut-ref="p"/>
    </aop:aspect>
</aop:config>
Copy the code