Spring aspect oriented programming AOP

9.1 what is AOP

AOP (Aspect Oriented Programming) means: Aspect Oriented Programming, which realizes the unified maintenance of program functions through precompiled mode and runtime dynamic agent. AOP is the continuation of OOP, a hot spot in software development, an important content in Spring framework, and a derivative paradigm of functional programming. AOP can isolate each part of business logic, reduce the coupling between each part of business logic, improve the reusability of program, and improve the efficiency of development.

9.2 role of AOP in Spring

Provide declarative transactions; Allows you to customize the cut plane

  • Crosscutting concerns: methods or functions that span multiple modules of an application. That is, the part that has nothing to do with our business logic, but we need to focus on is crosscutting concerns. Such as logging, security, caching, transactions, and so on

  • Aspect: a special object whose crosscutting concerns are modularized. That is, it is a class

  • Advice: work that must be completed in all aspects. That is, it is a method in a class

  • Target: the notified object

  • Proxy: an object created after notification is applied to the target object

  • PointCut: the definition of the "place" where the aspect notification is executed

  • Join point: the execution point that matches the pointcut

In spring AOP, crosscutting logic is defined through Advice. Spring supports five types of Advice

Notification typeConnection pointImplementation interface
Before advice Before methodorg.springframework.aop.MethodBeforeAdvice
Post notificationAfter methodorg.springframework.aop.AfterReturningAdvice
Around Advice Before and after methodorg.aopalliance.intercept.MethodInterceptor
Exception throw notificationMethod throws an exceptionorg.springframework.aop.ThrowsAdvice
Introduction noticeAdd a new method attribute to the classorg.springframework.aop.IntroductionInterceptor

That is, AOP adds new functions without changing the original code

9.3 using Spring to implement AOP

Using AOP weaving requires importing a dependency package

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

Premise Code:

UserService interface

public interface UserService {
    void add();
    void delete();
    void update();
    void select();
}

UserServiceImpl

public class UserServiceImpl implements UserService{
    public void add() {
        System.out.println("Add a new user");
    }

    public void delete() {
        System.out.println("Delete a user");
    }

    public void update() {
        System.out.println("Modify a user");
    }

    public void select() {
        System.out.println("Query a user");
    }
}
  • Method 1: use the Spring API interface

Pre Log

public class Log implements MethodBeforeAdvice {

    //Method: the method of the target object to execute
    //args: parameter
    //Target: target object
    public void before(Method method, Object[] args, Object target) throws Throwable {
        System.out.println(target.getClass().getName() + "of" + method.getName() + "Executed");
    }
}

Post Log

public class AfterLog implements AfterReturningAdvice {

    //returnValue: return value
    public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {
        System.out.println("Yes" + method.getName() + "Method, the return result is" + returnValue);
    }
}

applicationContext.xml configuration file

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--register bean-->
    <bean id="userService" class="com.lrm.service.UserServiceImpl"/>
    <bean id="log" class="com.lrm.log.Log"/>
    <bean id="afterLog" class="com.lrm.log.AfterLog"/>

    <!--Method 1: use native Spring API Interface-->
    <!--to configure aop: Import required aop Constraints of-->
    <aop:config>
        <!--Entry point: expression: expression, execution(Return type package name.Class name.Method name(parameter))-->
        <aop:pointcut id="pointcut" expression="execution(* com.lrm.service.UserServiceImpl.*(..))"/>

        <!--Execute surround increase-->
        <aop:advisor advice-ref="log" pointcut-ref="pointcut"/>
        <aop:advisor advice-ref="afterLog" pointcut-ref="pointcut"/>
    </aop:config>
</beans>

Test class

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //The dynamic proxy is the interface
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();

    }
}
  • Method 2: Customize to implement AOP

Custom pointcuts

public class DiyPointCut {

    public void before(){
        System.out.println("=====Before method execution=====");
    }
    public void after(){
        System.out.println("=====After method execution=====");
    }
}

applicationContext.xml configuration file

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--register bean-->
    <bean id="userService" class="com.lrm.service.UserServiceImpl"/>
    <bean id="log" class="com.lrm.log.Log"/>
    <bean id="afterLog" class="com.lrm.log.AfterLog"/>

    <!--Method 2: user defined class-->
    <bean id="diy" class="com.lrm.diy.DiyPointCut"/>
    <aop:config>
        <!--Custom cut, ref Class to reference-->
        <aop:aspect ref="diy">
            <!--breakthrough point-->
            <aop:pointcut id="point" expression="execution(* com.lrm.service.UserServiceImpl.*(..))"/>
            <!--notice-->
            <aop:before method="before" pointcut-ref="point"/>
            <aop:after method="after" pointcut-ref="point"/>
        </aop:aspect>
    </aop:config>
</beans>

Test class

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //The dynamic proxy is the interface
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();

    }
}
  • Method 3: using annotations

Write annotation class

//Using annotation to implement aop
@Aspect //Label this class as a facet
public class AnnotationPointCut {

    @Before("execution(* com.lrm.service.UserServiceImpl.*(..))")
    public void before(){
        System.out.println("=====Before method execution=====");
    }

    @After("execution(* com.lrm.service.UserServiceImpl.*(..))")
    public void after(){
        System.out.println("=====After method execution=====");
    }

    //In surround enhancement, you can give a parameter that represents the point at which you want to get the processing pointcut
    @Around("execution(* com.lrm.service.UserServiceImpl.*(..))")
    public void around(ProceedingJoinPoint point) throws Throwable {
        System.out.println("Surround front");

        //Get signature
        Signature signature = point.getSignature();
        System.out.println("signature: "+signature);

        //Execution method
        point.proceed();

        System.out.println("After surround");
    }
}

applicationContext.xml configuration file

<?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
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        https://www.springframework.org/schema/aop/spring-aop.xsd">

    <!--register bean-->
    <bean id="userService" class="com.lrm.service.UserServiceImpl"/>
    <bean id="log" class="com.lrm.log.Log"/>
    <bean id="afterLog" class="com.lrm.log.AfterLog"/>

    <!--Method 3: use annotation-->
    <bean id="annotationPointCut" class="com.lrm.anno.AnnotationPointCut"/>
    <!--Enable annotation support JDK(default proxy-target-class="false") cglib(proxy-target-class="true")-->
    <aop:aspectj-autoproxy/>
</beans>

Test class

public class MyTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        //The dynamic proxy is the interface
        UserService userService = context.getBean("userService", UserService.class);
        userService.add();

    }
}

Keywords: Java Spring AOP Dynamic Proxy SSM

Added by i on Sun, 26 Sep 2021 09:30:39 +0300