daily commit
This commit is contained in:
109
spring/Spring core/Spring Core AOP.md
Normal file
109
spring/Spring core/Spring Core AOP.md
Normal file
@@ -0,0 +1,109 @@
|
||||
# Spring AOP
|
||||
- ## Spring AOP的核心概念
|
||||
- Aspect:切面,一个模块化的考虑
|
||||
- Joint Point:连接点,程序执行时的一个时间点,通常是方法的执行
|
||||
- Advice:当切面在一个切入点执行多做时,执行的动作被称之为Advice,Advice有不同的类型:before、after、around
|
||||
- Pointcut:切入点,advice通常运行在满足pointcut的join point上,pointcut表达式与join point相关联,Spring中默认使用AspectJ切入点表达式
|
||||
- Introduction:在类中声明新的方法、域变量甚至是接口实现
|
||||
- linking:将应用类型或对象和切面链接起来
|
||||
- ## Spring AOP的类型
|
||||
- before:在连接点之前运行,但是无法阻止后续连接点的执行
|
||||
- after returning:在连接点正常返回之后进行
|
||||
- after throwing:在链接点抛出异常正常退出之后进行
|
||||
- after finally:上两种的结合,不管连接点是正常退出还是抛出异常退出,都会在其之后执行
|
||||
- around:around可以自定义连接点之前和之后的执行内容,其也能够选择时候执行连接点的方法
|
||||
- ## Spring AOP的特点
|
||||
- 区别于AspectJ AOP框架,Spring AOP框架是基于代理来实现的
|
||||
- 对于实现了接口的类,Spring AOP通常是通过JDK动态代理来实现的,对于没有实现接口的类,Spring AOP是通过cglib来实现的
|
||||
- 可以强制Spring AOP使用cglib,在如下场景:
|
||||
- 如果想要advise类中方法,而该方法没有在接口中定义
|
||||
- 如果想要将代理对象传递给一个具有特定类型的方法作为参数
|
||||
- ## Spring AOP的AspectJ注解支持
|
||||
- Spring AOP支持AspectJ注解,Spring AOP可以解释和AspectJ 5相同的注解,通过使用AspectJ提供的包来进行切入点解析和匹配
|
||||
- 但是,即使使用了AspectJ注解,AOP在运行时仍然是纯粹的Spring AOP,项目不需要引入AspectJ的编译器和weaver
|
||||
- Spring AOP对AspectJ注解支持的开启
|
||||
- 通过@EnableAspectJAutoProxy注解,会自动的为满足切入点匹配的连接点bean对象创建移动代理对象
|
||||
```java
|
||||
@Configuration
|
||||
@EnableAspectJAutoProxy
|
||||
class AspectJConfiguration {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
- ## 声明Spring AOP切面
|
||||
- 在容器中,任何bean对象,如其类型具有@AspectJ注解,将会被自动探知到并且用来配置spring aop
|
||||
- 在Spring AOP中,aspect其自身是无法作为其他aspect的目标对象的。被标记为@Aspect的类,不经标明其为aspect,并且将其从自动代理中排除
|
||||
```java
|
||||
@Component // 将该类型声明为bean对象
|
||||
@Aspect // 声明切面
|
||||
public class ProxyAspect {
|
||||
|
||||
}
|
||||
```
|
||||
- ## 声明Spring AOP切入点
|
||||
- 由于Spring AOP仅仅支持方法的连接点,故而可以将切入点看做对bean对象方法的匹配
|
||||
- Join Point expression的种类:
|
||||
- execution:匹配目标方法的执行,可以在括号中接收一个函数签名,包含返回类型、函数名和函数参数类型
|
||||
```java
|
||||
// 被@JointPoint注解标注的方法必须具有void的返回类型
|
||||
@JoinPoint("execution(* Point.*(..))")
|
||||
void methodInjected() {
|
||||
|
||||
}
|
||||
```
|
||||
- within:匹配声明在某一特定类中的方法
|
||||
```java
|
||||
@JoinPoint("within(Point)")
|
||||
```
|
||||
- this:匹配生成的代理对象为该类型的方法
|
||||
- target:匹配目标对象为该类型的方法
|
||||
- args:匹配特定参数的方法
|
||||
-
|
||||
- Spring AOP同样支持将JoinPoint匹配为具有特定name的Spring bean对象
|
||||
```java
|
||||
@JoinPoint("bean(nameA) || bean(nameB))")
|
||||
```
|
||||
- ## Spring AOP中的Advice
|
||||
- Advice和Pointcut Expresion相关联,主要可以分为before、after、around等种类
|
||||
- Before:
|
||||
```java
|
||||
@Before("execution(* Point.*(..))")
|
||||
public void doSomething() {
|
||||
|
||||
}
|
||||
```
|
||||
- AfterReturning:
|
||||
```java
|
||||
// AfterReturning支持获取切入点执行后返回的值
|
||||
@AfterReturning(
|
||||
pointcut="execution(* Point.*(..))",
|
||||
returning="retVal")
|
||||
public void doSomething(int retVal) {
|
||||
|
||||
}
|
||||
```
|
||||
- AfterThrowing:
|
||||
```java
|
||||
@AfterThrowing(
|
||||
pointcut="execution(* Point.*())",
|
||||
throwing="ex"
|
||||
)
|
||||
public void doSomething(Throwable ex) {
|
||||
|
||||
}
|
||||
```
|
||||
- After:After不管是切入点正常返回还是抛出异常,都会执行
|
||||
```java
|
||||
@After("execution(* Point.*())")
|
||||
public void doSomething() {
|
||||
|
||||
}
|
||||
```
|
||||
- Around:其方法必须会一个Oject类型的返回值,并且方法的第一个参数类型是ProceedingJoinPoint
|
||||
```java
|
||||
@Around("execution(* Point.*())")
|
||||
public Object doSomething(ProceedingJoinPoint pjp) {
|
||||
return isCacheExisted()?returnFromCache():pjp.proceed();
|
||||
}
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user