The way to learn SSM -- the third day of spring

1, pom.xml

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

2, bean.xml

This is the xml configuration for aop using annotations
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

<?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:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:tx="http://www.springframework.org/schema/tx"
       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
    http://www.springframework.org/schema/tx
    http://www.springframework.org/schema/tx/spring-tx.xsd">
    <context:component-scan base-package="com.itheima"></context:component-scan>
    <aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>

3, Using annotations to write the Logger class

1. Four separate notification types are used to realize pre, post, final and exception notification respectively
@Aspect represents this class as a tangent
There are two ways to write expressions
One is to fill in the expression directly as After @ After
The other is to write a pt1() method first, mark @ Pointcut on it, and fill in the expression
When quoting Pointcut annotation, such as @ Before, please note that pT1 (parenthesis) should be used. Parenthesis should not be omitted, otherwise the Pointcut expression error will be reported

@Component("logger")
@Aspect
public class Logger {
    @Pointcut("execution(* com.itheima.service.impl.*.*(..))")
    public void pt1(){}
    @Before("pt1()")
    public void beginLog(){
        System.out.println("Start execution method");
    }
    @After("execution(* com.itheima.service.impl.*.*(..))")
    public void endLog(){
        System.out.println("End of method execution (final)");
    }
    @AfterReturning("pt1()")
    public void successLog(){
        System.out.println("Method executed successfully (called after method execution)");
    }
    @AfterThrowing("pt1()")
    public void exceptionLog(){
        System.out.println("Method execution exception");
    }
}

4, Client class

Only the saveAccount method is called to test

public class Client {
    public static void main(String[] args) {
        ApplicationContext ac = new ClassPathXmlApplicationContext("bean.xml");
        IAccountService as = ac.getBean("accountService",IAccountService.class);
        as.saveAccount();
    }
}

Operation result:

Start execution method
 New account
 End of method execution (final)
Method executed successfully (called after method execution)

notice:

Here's a discovery: when we use spring to write several notices separately with annotations (that is, we don't use surround notices), we first execute the final notice, and then execute it successfully. (it's equivalent to executing finally, and then execute the operation that the method executes. We usually execute the operation that the method executes first, and then finally execute finally). There is a sequence For example, we need to close a flow in the final method, and the successful method needs to operate on the flow. In this order, there will be a problem, because the final operation will be performed after all operations are performed normally.

Using surround notifications does not have this problem:
Use surround notification annotation:

@Around("execution(* com.itheima.service.impl.*.*(..))")
    public Object arroundLogger(ProceedingJoinPoint pdj){
        Object rtValue = null;
        try {
            Object args[] = pdj.getArgs();
            System.out.println("Pre method execution");
            rtValue=pdj.proceed(args);
            System.out.println("Method executed successfully (called after method execution)");
            return rtValue;
        } catch (Throwable throwable) {
            System.out.println("Exception method execution");
            throwable.printStackTrace();
        }finally {
            System.out.println("Final method execution");
        }
        return rtValue;
    }

No problem with execution order

Pre method execution
 New account
 Method executed successfully (called after method execution)
Final method execution

Therefore, it is more recommended to use surround notification

Published 18 original articles, won praise 0, visited 210
Private letter follow

Tags: Spring xml encoding

Posted on Sun, 02 Feb 2020 22:32:04 -0800 by Garrett