Road SSM learning --spring third day _ using AOP annotations

A, 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>

Two, bean.xml

This is achieved using annotations aop configuration xml
<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>

Third, the use of the Logger class to write notes

1, before use of four separate types of notifications are implemented, the final, the exception notification
@Aspect representing the class as an aspect
here are two ways to write expressions using
one is like behind @After fill in as a direct expression
of another species is the first to write a pt1 () method, above note on @Pointcut, which fill expression
when referring to pointcut annotations, such as @Before, to note that pt1 (in parentheses), parentheses can not be omitted, otherwise it will report an entry point expression error type

@Component("logger")
@Aspect
public class Logger {
    @Pointcut("execution(* com.itheima.service.impl.*.*(..))")
    public void pt1(){}
    @Before("pt1()")
    public void beginLog(){
        System.out.println("开始执行方法");
    }
    @After("execution(* com.itheima.service.impl.*.*(..))")
    public void endLog(){
        System.out.println("方法执行结束(最终)");
    }
    @AfterReturning("pt1()")
    public void successLog(){
        System.out.println("方法执行成功(执行完方法后就调用)");
    }
    @AfterThrowing("pt1()")
    public void exceptionLog(){
        System.out.println("方法执行异常");
    }
}

Four, Client class

Call only way to test saveAccount

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:

开始执行方法
新建账户
方法执行结束(最终)
方法执行成功(执行完方法后就调用)

notice:

Here's a discovery that we use several notification spring of using annotations separate writing (ie do not use around advice) time, the first implementation of the final notice, then execution is successful, (equivalent to the first execution finally, and then executing the execution method operation, we usually is to perform an operation method of performing complete, and finally execute finally) is problematic on a sequence of, for example, we need to close a stream in the final method, and the method succeeded in turn requires the stream to operate, According to this order, then there will be problems, because the normal completion of all operations, and then perform a final operation.

Use around advice is not the problem:
use around advice notes:

@Around("execution(* com.itheima.service.impl.*.*(..))")
    public Object arroundLogger(ProceedingJoinPoint pdj){
        Object rtValue = null;
        try {
            Object args[] = pdj.getArgs();
            System.out.println("前置方法执行");
            rtValue=pdj.proceed(args);
            System.out.println("方法执行成功(执行完方法就调用)");
            return rtValue;
        } catch (Throwable throwable) {
            System.out.println("异常方法执行");
            throwable.printStackTrace();
        }finally {
            System.out.println("最终方法执行");
        }
        return rtValue;
    }

Execution order is no problem

前置方法执行
新建账户
方法执行成功(执行完方法就调用)
最终方法执行

Therefore more recommended around advice

Published 23 original articles · won praise 0 · Views 593

Guess you like

Origin blog.csdn.net/SixthMagnitude/article/details/104155892