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

相关推荐
缺点内向2 小时前
Java:创建、读取或更新 Excel 文档
java·excel
带刺的坐椅3 小时前
Solon v3.4.7, v3.5.6, v3.6.1 发布(国产优秀应用开发框架)
java·spring·solon
四谎真好看4 小时前
Java 黑马程序员学习笔记(进阶篇18)
java·笔记·学习·学习笔记
桦说编程4 小时前
深入解析CompletableFuture源码实现(2)———双源输入
java·后端·源码
java_t_t4 小时前
ZIP工具类
java·zip
lang201509285 小时前
Spring Boot优雅关闭全解析
java·spring boot·后端
pengzhuofan5 小时前
第10章 Maven
java·maven
百锦再6 小时前
Vue Scoped样式混淆问题详解与解决方案
java·前端·javascript·数据库·vue.js·学习·.net
刘一说6 小时前
Spring Boot 启动慢?启动过程深度解析与优化策略
java·spring boot·后端
壹佰大多6 小时前
【spring如何扫描一个路径下被注解修饰的类】
java·后端·spring