spring Framework Learning-aop-Annotation

Keywords: PHP Spring xml Maven Java

Preface

aop in annotation mode needs several new annotations

1.@Aspect// indicates that this is a faceted class
2. @Pointcut ("execution (* com.cong.service.AccountService Impl. *(.))")// pointcut expression
  private void accountPointcut(){}
3. @Before (value = accountPointcut())// Pre-notification annotation, the parentheses of accountPointcut() cannot be removed
Similarly, there are AfterReturning,AfterThrowing,Around
4. Also add a sentence in the configuration file to tell spring to turn on annotation aop support
    <! - Tell spring to turn on support for annotation aop - >.
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>

1. Create maven projects and add dependencies

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.cong</groupId>
    <artifactId>spring_aop_annotation</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>jar</packaging>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>5.0.2.RELEASE</version>
        </dependency>
        <!-- aop -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.9</version>
        </dependency>
    </dependencies>
</project>

2. Create the com.cong.pojo.Account class in the java directory, create objects through annotations, inject data, and add it to the ioc container

package com.cong.pojo;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component//Injection into ioc In containers
public class Account {
    @Value("1")
    private int id;
    @Value("cong")
    private String name;
    @Value("100")
    private float money;
    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", money=" + money +
                '}';
    }
}

3. Create the com.cong.service package in the java directory, and create interfaces and classes

package com.cong.service;

import com.cong.pojo.Account;

public interface AccountService {
    void saveAccount(Account account);
}



package com.cong.service;

import com.cong.pojo.Account;
import org.springframework.stereotype.Service;

@Service("accountService")
public class AccountServiceImpl implements AccountService {
    @Override
    public void saveAccount(Account account) {
        System.out.println("save account..." + account.toString());
//        int i = 1/0;
    }
}

4. Create a com.cong.utils.MyTransaction notification class in the java directory

Comment out the comments surrounding the notification first

package com.cong.utils;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

@Component//
@Aspect//Indicates that this is a tangent class
public class MyTransaction {
    @Pointcut("execution(* com.cong.service.AccountServiceImpl.*(..))")//Pointcut expression
    private void accountPointcut(){}
    //Before advice
    @Before(value = "accountPointcut()")//Pre-notification annotations
    public void beforeTransaction(){
        System.out.println("Before advice MyTransaction In the class beforeTransaction Method executed...");
    }
    //after returning advise
    @AfterReturning("execution(* com.cong.service.AccountServiceImpl.*(..))")//If no pointcut expression is configured
    public void afterReturningTransaction(){
        System.out.println("after returning advise MyTransaction In the class afterReturningTransaction Method executed...");
    }
    //Exception Notification
    @AfterThrowing("accountPointcut()")
    public void afterThrowingTransaction(){
        System.out.println("Exception Notification MyTransaction In the class afterThrowingTransaction Method executed...");
    }
    //Final Notice
    @After("accountPointcut()")
    public void afterTransaction(){
        System.out.println("Final Notice MyTransaction In the class afterTransaction Method executed...");
    }
    //Around Advice
    //@Around("accountPointcut()")
    public Object aroundTransaction(ProceedingJoinPoint proceedingJoinPoint){
        Object res = null;
        try {
            Object args [] = proceedingJoinPoint.getArgs();
            beforeTransaction();
            proceedingJoinPoint.proceed(args);
            afterReturningTransaction();
            return res;
        }catch (Throwable throwable){
            afterThrowingTransaction();
            return new RuntimeException(throwable);
        }finally {
            afterTransaction();
        }
    }
}

5. Create a bean.xml file in the resources directory

<?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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/aop
        http://www.springframework.org/schema/aop/spring-aop.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- To configure spring Packets to be scanned -->
    <context:component-scan base-package="com.cong"></context:component-scan>
    <!-- inform spring,Open Notes aop Support -->
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

6. Create test classes under test, java directory

import com.cong.pojo.Account;
import com.cong.service.AccountService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AopAnnotationTest {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
        AccountService accountService = (AccountService)context.getBean("accountService");
        Account account = (Account)context.getBean("account");
        accountService.saveAccount(account);
    }
}

7. Operational results are somewhat different from what we imagine.

The order of post-notification and exception notification is obviously different.

This is the problem that spring annotation-based aop does have sequential calls, so the choice in actual development should be carefully considered.

Information: Loading XML bean definitions from class path resource [bean.xml]
The beforeTransaction method in the MyTransaction class is notified in advance that it executes...
save account...Account{id=1, name='cong', money=100.0}
Eventually notify the MyTransaction class that the afterTransaction method has executed...
The after Returning Transaction method in the MyTransaction class is notified to execute the ___________.

8. Annotate the pre-notification, post-notification, exception notification and final notification, and cancel the annotation surrounding the notification.

    //Before advice
    //@Before(value = "accountPointcut()")//Pre-notification annotations
    public void beforeTransaction(){
        System.out.println("Before advice MyTransaction In the class beforeTransaction Method executed...");
    }
    //after returning advise
    //@AfterReturning("execution(* com.cong.service.AccountServiceImpl.*(..))")//If no pointcut expression is configured
    public void afterReturningTransaction(){
        System.out.println("after returning advise MyTransaction In the class afterReturningTransaction Method executed...");
    }
    //Exception Notification
    //@AfterThrowing("accountPointcut()")
    public void afterThrowingTransaction(){
        System.out.println("Exception Notification MyTransaction In the class afterThrowingTransaction Method executed...");
    }
    //Final Notice
    //@After("accountPointcut()")
    public void afterTransaction(){
        System.out.println("Final Notice MyTransaction In the class afterTransaction Method executed...");
    }
    //Around Advice
    @Around("accountPointcut()")
    public Object aroundTransaction(ProceedingJoinPoint proceedingJoinPoint){
        Object res = null;
        try {
            Object args [] = proceedingJoinPoint.getArgs();
            beforeTransaction();
            proceedingJoinPoint.proceed(args);
            afterReturningTransaction();
            return res;
        }catch (Throwable throwable){
            afterThrowingTransaction();
            return new RuntimeException(throwable);
        }finally {
            afterTransaction();
        }
    }

9. Execute it again so that the order of calls is not a problem. After all, this is all our own code.

Information: Loading XML bean definitions from class path resource [bean.xml]
The beforeTransaction method in the MyTransaction class is notified in advance that it executes...
save account...Account{id=1, name='cong', money=100.0}
The after Returning Transaction method in the MyTransaction class is notified to execute the ___________.
Eventually notify the MyTransaction class that the afterTransaction method has executed...

Posted by jamest on Tue, 23 Jul 2019 11:48:48 -0700