Spring Aop

一、Aop

Aop的常用注解:

@Before:前置通知:目标方法之前执行

@After:后置通知:目标方法之后执行(始终执行)

@AfterReturning:返回后通知:执行方法结束前执行(异常不执行)

@AfterThrowing:异常通知:出现异常时执行

@Around:环绕通知:环绕目标方法执行

java 复制代码
面试题:
1、你肯定知道spring,那说说aop的全部通知顺序?

2.springboot或springboot2对aop的执行顺序影响?

3.说说你使用aop中碰到的坑?

创建springboot项目

**pom--->切换springboot版本:**Spring4+springboot1.5.9/Spring5+springboot2.3.3

XML 复制代码
<?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.lwz</groupId>
    <artifactId>springboot_aop</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
        <!-- <version>2.3.3.RELEASE</version> -->
    </parent>
    
    <properties>
    	<java.version>1.8</java.version>
    </properties>

   <dependencies>
       <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter</artifactId>
       </dependency>
       <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
        <dependency>
           <groupId>org.springframework.boot</groupId>
           <artifactId>spring-boot-starter-test</artifactId>
           <scope>test</scope>
       </dependency>
   </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>

切面编程,切面类

java 复制代码
package com.lwz.aop;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class MyAspect {

	@Before("execution(public int com.lwz.service.impl.CalcServiceImpl.*(..))")
	public void beforeNotify() {
		System.out.println("******@Before我是前置通知");
	}

	@After("execution(public int com.lwz.service.impl.CalcServiceImpl.*(..))")
	public void afterNotify() {
		System.out.println("******@@After我是后置通知");
	}

	@AfterReturning("execution(public int com.lwz.service.impl.CalcServiceImpl.*(..))")
	public void afterReturningNotify() {
		System.out.println("******@AfterReturning我是返回后通知");
	}

	@AfterThrowing("execution(public int com.lwz.service.impl.CalcServiceImpl.*(..))")
	public void afterThrowingNotify() {
		System.out.println("******@AfterThrowing我是异常通知");
	}

	@Around("execution(public int com.lwz.service.impl.CalcServiceImpl.*(..))")
	public Object aroundNotify(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
		Object retValueObject = null;
		System.out.println("我是环绕通知之前AAA");
		retValueObject = proceedingJoinPoint.proceed();
		System.out.println("我是环绕通知之后BBB");
		return retValueObject;
	}
}

业务类

java 复制代码
package com.lwz.service;

public interface CalcService {
	public int div(int x, int y);
}

实现类

java 复制代码
package com.lwz.service.impl;

import org.springframework.stereotype.Service;

import com.lwz.service.CalcService;

@Service
public class CalcServiceImpl implements CalcService {

	@Override
	public int div(int x, int y) {
		int result = x / y;
		System.out.println("    ======>CalcServiceImpl被调用了,计算结果:" + result);
		return result;
	}

}

测试类

java 复制代码
package com.lwz;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringBootVersion;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.core.SpringVersion;
import org.springframework.test.context.junit4.SpringRunner;

import com.lwz.service.CalcService;

@SpringBootTest
@RunWith(SpringRunner.class)
public class AopTest {

	@Autowired
	private CalcService calcService;

	@Test
	public void testAop() {
		System.out.println(
				"spring版本:" + SpringVersion.getVersion() + "\t SpringBoot版本:" + SpringBootVersion.getVersion());
		calcService.div(5, 3);
		// calcService.div(5, 0);
	}
}

**pom--->切换springboot版本:**Spring4+springboot1.5.9/Spring5+springboot2.3.3正常系和异常系进行测试

Spring4运行结果:

java 复制代码
正常系运行结果:
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.9.RELEASE)

spring版本:4.3.13.RELEASE	 SpringBoot版本:1.5.9.RELEASE
我是环绕通知之前AAA
******@Before我是前置通知
    ======>CalcServiceImpl被调用了,计算结果:1
我是环绕通知之后BBB
******@@After我是后置通知
******@AfterReturning我是返回后通知


异常系运行结果:
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v1.5.9.RELEASE)

spring版本:4.3.13.RELEASE	 SpringBoot版本:1.5.9.RELEASE
我是环绕通知之前AAA
******@Before我是前置通知
******@@After我是后置通知
******@AfterThrowing我是异常通知

java.lang.ArithmeticException: / by zero

spring4 aop正常顺序:@Before-->

Spring5运行结果:

java 复制代码
正常系运行结果:
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.3.RELEASE)

spring版本:5.2.8.RELEASE	 SpringBoot版本:2.3.3.RELEASE
我是环绕通知之前AAA
******@Before我是前置通知
    ======>CalcServiceImpl被调用了,计算结果:1
******@AfterReturning我是返回后通知
******@@After我是后置通知
我是环绕通知之后BBB

异常系运行结果:
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::        (v2.3.3.RELEASE)

spring版本:5.2.8.RELEASE	 SpringBoot版本:2.3.3.RELEASE
我是环绕通知之前AAA
******@Before我是前置通知
******@AfterThrowing我是异常通知
******@@After我是后置通知

再小的努力,乘以365都很明显!
一个程序员最重要的能力是:写出高质量的代码!!
有道无术,术尚可求也,有术无道,止于术。
无论你是年轻还是年长,所有程序员都需要记住:时刻努力学习新技术,否则就会被时代抛弃!

相关推荐
考虑考虑37 分钟前
JDK9中的dropWhile
java·后端·java ee
想躺平的咸鱼干1 小时前
Volatile解决指令重排和单例模式
java·开发语言·单例模式·线程·并发编程
hqxstudying1 小时前
java依赖注入方法
java·spring·log4j·ioc·依赖
·云扬·1 小时前
【Java源码阅读系列37】深度解读Java BufferedReader 源码
java·开发语言
KellenKellenHao1 小时前
MySQL数据库主从复制
数据库·mysql
春生野草2 小时前
关于SpringMVC的整理
spring
Bug退退退1232 小时前
RabbitMQ 高级特性之重试机制
java·分布式·spring·rabbitmq
小皮侠2 小时前
nginx的使用
java·运维·服务器·前端·git·nginx·github
一只fish3 小时前
MySQL 8.0 OCP 1Z0-908 题目解析(16)
数据库·mysql
Zz_waiting.3 小时前
Javaweb - 10.4 ServletConfig 和 ServletContext
java·开发语言·前端·servlet·servletconfig·servletcontext·域对象