Deep Spring AOP read the article [theory and practice]

What is AOP?

  • AOP (Aspect Oriented Programming), that is, aspect-oriented programming, can be said to OOP (Object Oriented Programming, Object Oriented Programming) added and improved. OOP introduced as encapsulation, inheritance, polymorphism, etc. concept to build a hierarchy of objects, used to simulate the behavior of a common set. However, OOP allows developers to define vertical relationship, but are not suitable for transverse relationship defined, for example, the log function. Log code tends to spread laterally in all object hierarchy, the core object corresponding to the function it no relation to other types of code, such as security, exception handling, and continuity are also transparent so, this spread independent code is referred to throughout the transverse (cross cutting), in OOP design, which led to a lot of code repetition, to the detriment of reusable modules.

  • Contrary AOP technology, which uses a technique called "transverse", the internal cross-sectional decapsulates the object, and those that affect the behavior of the public classes encapsulated into a plurality of reusable modules, and named it " Aspect ", namely section. The so-called "cut", it simply is that nothing to do with business, but it is the responsibility of the business logic or common module called encapsulated, easy to duplicate code to reduce system and reduce the degree of coupling between modules, and facilitate future operability and maintainability.

  • Use "cross-cutting" technology, AOP the software system is divided into two parts: the core concerns and crosscutting concerns. The main flow of business processes is a core concern, not part of the relationship is with crosscutting concerns. Features a crosscutting concern is that they often occur in many core concerns, and everywhere essentially similar, such as certification authority, log things.

  • AOP is that the various concerns separation system, the core and crosscutting concerns separated. Spring AOP module provides interceptors to intercept an application, for example, when performing a method, you can add additional features before or after execution method.

AOP terminology

  • Cross-cutting concerns: Which method to intercept, how to deal with the interception, these concerns called crosscutting concerns
  • Section (aspect): class is an abstract object features, is the abstract section of crosscutting concerns
  • Connection point (joinpoint): point being intercepted, since Spring supports only a connection point type method, it is to point refers to the connection to be intercepted in the Spring, in fact, the point of attachment may also be field or constructors
  • Entry point (pointcut): to define a connection point of interception
  • Notification (advice): refers to the so-called notification refers to the connection point codes after the interception to be performed, a notification is divided into front, rear, abnormal end, surrounded by five notifications
  • Audience: Acting target object
  • Weaving (weave): The section applied to the target object and the process leading to the proxy object created
  • Introducing (introduction): Under the premise of not modifying code, the introduction of some methods or fields may be added to the class dynamically at runtime

Spring section can be applied to five types of notification

  • Pre-notification (Before): call notice before the target method is called
  • After returning advice (After): call notification after completion target method (either normal or abnormal exit all calls)
  • Return notification (After-returning): call notification after successful execution of the target method
  • Exception notification (After-throwing): call notification when the target method throws an exception
  • Around advice (Around): implementation of custom wrapped after the notification method to be notified, before the method is notified of calls and call behavior

Spring AOP support

  • Spring AOP proxy in Spring's IOC container is responsible for generation, management, and its dependencies are also responsible for the management by the IOC container. Thus, the AOP agent may be used directly with other bean instance as a target container, this relationship may be provided dependency injection IOC containers. Spring create rules for agents:

    • 1, use Java to create a dynamic proxy AOP proxy by default, so you can create an instance of any of the interfaces that the proxy
    • 2, when the class is not required proxy interface agent, Spring CGLIB will switch to using a proxy, may also be used to force CGLIB
  • AOP programming is actually very simple thing, look at AOP programming, the programmer need only participate in three parts:

    • 1, the definition of common business components
    • 2, the definition of a starting point, a starting point may cross a plurality of business components
    • 3, the definition enhancement processing, enhancement processing in the operation processing is the frame AOP component is woven into ordinary traffic
  • So the key is to define the entry points and the definition AOP enhancement processing program, once the entry point and define an appropriate enhancement processing, AOP AOP proxy frame is automatically generated, namely: proxy object processing method is a method = + enhancement proxy object.

Spring AOP-based XML schema

  • Spring AOP .xml file template, called aop.xml
  • In SSM frame, aop configuration file in the file applicationContext.xml
    Sample Code
  • Logging.java
package com.tutorialspoint;
public class Logging {

   public void beforeAdvice(){
      System.out.println("前置通知");
   }
  
   public void afterAdvice(){
      System.out.println("后置通知");
   }

   public void afterReturningAdvice(Object retVal){
      System.out.println("返回通知:" + retVal.toString() );
   }

   public void AfterThrowingAdvice(IllegalArgumentException ex){
      System.out.println("异常通知: " + ex.toString());   
   }  
}
  • Student.java
package com.tutorialspoint;
public class Student {
   private Integer age;
   private String name;
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      System.out.println("Age : " + age );
      return age;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      System.out.println("Name : " + name );
      return name;
   }  
   public void printThrowException(){
       System.out.println("Exception raised");
       throw new IllegalArgumentException();
   }
}
  • MainApp.java
package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context =  new ClassPathXmlApplicationContext("aop.xml");
        Student student = (Student) context.getBean("student");
        student.getName();
        System.out.println("--------------------");
        student.getAge();
        System.out.println("--------------------");
        student.printThrowException();
    }
}
  • aop.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

    <aop:config>
        <!--aspect 是使用元素声明的,支持的 bean 是使用 ref 属性引用的-->
        <aop:aspect id="log" ref="logging">
            <!--切入点-->
            <aop:pointcut id="selectAll" expression="execution(* com.tutorialspoint.*.*(..))"/>
            <!--前置通知-->
            <aop:before pointcut-ref="selectAll" method="beforeAdvice"/>
            <!--后置通知-->
            <aop:after pointcut-ref="selectAll" method="afterAdvice"/>
            <!--返回通知-->
            <aop:after-returning pointcut-ref="selectAll"
                                 returning="retVal"
                                 method="afterReturningAdvice"/>
            <!--异常通知-->
            <aop:after-throwing pointcut-ref="selectAll"
                                throwing="ex"
                                method="AfterThrowingAdvice"/>
        </aop:aspect>
    </aop:config>

    <!-- Definition for student bean -->
    <bean id="student" class="com.tutorialspoint.Student">
        <property name="name"  value="Zara" />
        <property name="age"  value="11"/>
    </bean>

    <!-- Definition for logging aspect -->
    <bean id="logging" class="com.tutorialspoint.Logging"/>

</beans>
  • Run the code, the results as shown below
    Here Insert Picture Description

Spring AOP-based annotation mode

Sample Code

  • Logging.java
package com.tutorialspoint1;

import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class Logging {

    @Pointcut("execution(* com.tutorialspoint1.*.*(..))")
    private void selectAll(){}

    @Before("selectAll()")
    public void beforeAdvice(){
        System.out.println("前置通知");
    }

    @After("selectAll()")
    public void afterAdvice(){
        System.out.println("后置通知");
    }

    @AfterReturning(pointcut = "selectAll()", returning="retVal")
    public void afterReturningAdvice(Object retVal){
        System.out.println("返回通知:" + retVal.toString() );
    }

    @AfterThrowing(pointcut = "selectAll()", throwing = "ex")
    public void AfterThrowingAdvice(IllegalArgumentException ex){
        System.out.println("异常通知: " + ex.toString());
    }
}
  • Student.java
package com.tutorialspoint1;
public class Student {
   private Integer age;
   private String name;
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      System.out.println("Age : " + age );
      return age;
   }
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      System.out.println("Name : " + name );
      return name;
   }
   public void printThrowException(){
      System.out.println("Exception raised");
      throw new IllegalArgumentException();
   }
}
  • MainApp.java
package com.tutorialspoint1;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
    public static void main(String[] args) {
        ApplicationContext context =  new ClassPathXmlApplicationContext("aop1.xml");
        Student student = (Student) context.getBean("student");
        student.getName();
        System.out.println("--------------------");
        student.getAge();
        System.out.println("--------------------");
        student.printThrowException();
    }
}
  • aop1.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/aop
    http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">

    <aop:aspectj-autoproxy/>

    <!-- Definition for student bean -->
    <bean id="student" class="com.tutorialspoint1.Student">
        <property name="name"  value="Zara" />
        <property name="age"  value="11"/>
    </bean>

    <!-- Definition for logging aspect -->
    <bean id="logging" class="com.tutorialspoint1.Logging"/>

</beans>
  • Run the code, the results as shown below
    Here Insert Picture Description

To Learn More

Generate a proxy force the use of CGLIB

  • Spring said before the use of dynamic proxy or proxy is generated CGLIB regular, high version of the Spring will automatically select whether to use dynamic proxy or proxy CGLIB generated content, of course, we can also generate a proxy force the use of CGLIB that aop: config inside has a "proxy-target-class" attribute, if the value is set to true, then the function will be based on the agent class, if the proxy-target-class is set to false or omitted this property, then the agent-based interface It will work.

The sample code in the text: https: //github.com/Carroll-guogaoqin/Spring-AOP.git

The more you know, the more you do not know.
Proper way without surgery, patients can still seek, there is no way to surgery, ending surgery.
If you have other questions, welcome message, we can discuss, learn together and progress together

He published 193 original articles · won praise 116 · views 10000 +

Guess you like

Origin blog.csdn.net/qq_40722827/article/details/104926430