Hello!
憋不住了,好吧!一直对SpringBoot Aop
是一种看得见,但是细看又是朦胧的心痒痒感觉,且总是有点只知道理论知识,真叫我做,却一脸懵…为了解决此现象,今天砸门来个斩草除根,详细总结吧!!
创作不易,多多三连啊!!(厚脸皮来要赞啦~哈哈哈)
先打住!!!先说下总纲啊!!
我会先介绍下
AOP是啥?
,目的是搞清楚它是个什么鬼东西!!!其次:我们会进行案例实战,看半天专业术语,不如我们动手制作一遍!!!
最后,再次总结,相信当你看到这一步,你就把
AOP
玩弄于鼓掌之间!!!(有人说:你字打错了!没错,我就是故意的~~)
文章目录
1.基本概念:
什么是
AOP
?专业解释:[摘自百度百科]
- 在软件业,
AOP
为Aspect Oriented Programming
的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。AOP
是OOP(面向切面编程)的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。- 利用
AOP
可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。大白话: (若是小白上面就是看看行了,看不懂就看这行俺说的,感觉不恰当,**欢迎来锤!**哈哈)
AOP
就是相当于我们日常活动的使用的工具,
举个例子哈:我们吃完饭,是不是都要洗碗,假设以前早中晚都是要你自己亲自用手去洗碗,日积月累,你感觉好麻烦啊,为啥每次都要本尊亲自处理呢?这个时候,你就买了个洗碗机,这个洗碗机你就把它看成
AOP
的实践,每次吃完饭,你只要将碗交给洗碗机,你不用关心和亲自去洗碗,只需等待碗洗好这个结果就行,这个洗碗的过程就是AOP
的原理使用你可能会说?那我看
AOP
不是还有解耦的功能,你这洗碗机咋解释这解耦啊!!!别急啊!看下面以前洗碗,就算不是你洗碗,是不是你的家人都要亲自用手去洗碗,这是不是耦合度高(只要某人有这个洗碗任务,都要亲自去洗碗),但是有了洗碗机,不管是何人,只需要将碗交给洗碗机,就省去了**亲自洗碗!!!**的过程(好好理解这四个字),是不是就达到解耦的目的
嗯~~基础概念先说到这,我们先了解这个
AOP
,有个大概印象就够了,至于它里面的@**
注解字,我们实战完再看,(那时才更上一层楼嘛!!)
2.应用实践
纸上得来终觉浅,绝知此事要躬行! 先跟着做,再内化于心
2.1创建一个Springboot
项目,引入pom.xml
,搭建基本环境
通常若是你通过
SpringInitrial
创建都有,比对下就可以,没有就加上若你直接通过
maven
进行搭建,添加如下配置
<dependencies>
<!--引入提供Web开发场景依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入面向切面依赖, 这个要引入哈!!!-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
</dependencies>
2.2创建自定义注解
用于使用注解作为切入点
/**
* 自定义注解,你可以自定义成你自己想要的方法名
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface BeforeAspect {
public String value() default "我成功在此方法之前执行啦!!";
}
2.3设置切面类
以及切面方法
JoinPoint
: 主要是获取切入点方法相应数据getSignature()
: 是获取到这样的信息 :修饰符+ 包名+组件名(类名) +方法名joinPoint.getArgs()
:这里返回的是切入点方法的参数列表这里返回的是切入点方法的参数列表(MethodSignature) joinPoint.getSignature().getMethod().getAnnotation(BeforeDS.class)
:获取切入点 方法上的@BeforeAspect
注解
/**
* 通过业务代码动态切换数据源
* 识别执行方法上得注解
*/
@Component
@Aspect //设置当前类为切面类-----------------------核心注解!!!!
//设置order=0,执行时机优先于AbstractRoutingDataSource.determineCurrentLookupKey
@Order(0)
public class SwitchDSAspect {
/**
* 标注当前方法作为前置通知
*/
@Before("@annotation(com.it.mhh.anno.BeforeAspect)")//用自定义注解 BeforeAspect 作为切入点
public void before(JoinPoint joinPoint) throws Throwable {
Signature pointSignature = joinPoint.getSignature();
System.err.println("切入点方法的修饰符+ 包名+组件名(类名) +方法名-->:"+pointSignature);
Object[] args = joinPoint.getArgs();
System.err.println("切入点方法的参数列表-->:"+ Arrays.toString(args));
MethodSignature signature = (MethodSignature) joinPoint.getSignature();
Method method = signature.getMethod();
BeforeAspect beforeAspect = method.getAnnotation(BeforeAspect.class);
String value = beforeAspect.value();//获取切入点方法上BeforeDS注解的值
System.err.println("切面类中before方法--自定义注解BeforeDS中的值为-->:" + value);
}
}
2.4Controller
层配置
@RestController
@RequestMapping("aop_test")
public class AOPTestController {
@Value("#{AOPTestServiceImpl}")
private AopDrillService aopDrillService;
@RequestMapping("before")
public String beforeTest() {
System.out.println("before测试-controller");
return aopTestService.beforeTest();
}
}
2.5Service
层配置
@Service
public class AopDrillService{
@BeforeAspect //使用自定义注解 执行切面(这个就是我们买的洗碗机!!!)
@Override
public String beforeTest() {
System.out.println("before测试-serviceimpl层");
return "before测试end";
}
}
好啦!!上面的配置完成,进行启动,你会看到控制台打印输出的数据
3.AOP
专业术语的解释
注解字 | 解释 | 应用 |
---|---|---|
@After |
后置通知:原始方法执行后执行,无论原始方法中是否出现异常,都将执行通知 | 现场清理 |
@Before |
前置通知:原始方法执行前执行,如果通知中抛出异常,阻止原始方法运行 | 数据校验 |
@Aspect |
设置当前类为切面类 | 定义切面 |
@annotation |
指定用注解进行切面 | |
@Around |
环绕通知:在原始方法执行前后均有对应执行执行,还可以阻止原始方法的执行 | 啥都可以做!! |
@AfterReturning |
返回后通知:原始方法正常执行完毕并返回结果后执行,如果原始方法中抛出异常,无法执行 | 返回值相关数据处理 |
@AfterThrowing |
抛出异常后通知:原始方法抛出异常后执行,如果原始方法没有抛出异常,无法执行 | 对原始方法中出现的异常信息进行处理 |
怎么说?看到这里?是不是已经懂了,感觉
AOP
就那样吧!!!哈哈~!什么?写的不够详细?欢迎小主宝贵意见分享啊!!!也是我创作不竭的动力啊!!!