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

相关推荐
Dcs16 分钟前
VSCode等多款主流 IDE 爆出安全漏洞!插件“伪装认证”可执行恶意命令!
java
保持学习ing22 分钟前
day1--项目搭建and内容管理模块
java·数据库·后端·docker·虚拟机
京东云开发者33 分钟前
Java的SPI机制详解
java
超级小忍1 小时前
服务端向客户端主动推送数据的几种方法(Spring Boot 环境)
java·spring boot·后端
发仔1231 小时前
Oracle与MySQL核心差异对比
mysql·oracle
程序无bug1 小时前
Spring IoC注解式开发无敌详细(细节丰富)
java·后端
小莫分享1 小时前
Java Lombok 入门
java
程序无bug1 小时前
Spring 对于事务上的应用的详细说明
java·后端
食亨技术团队1 小时前
被忽略的 SAAS 生命线:操作日志有多重要
java·后端
苦学编程的谢1 小时前
Maven
java·maven·intellij-idea