diff --git a/spring/Spring core/Spring Core AOP.md b/spring/Spring core/Spring Core AOP.md new file mode 100644 index 0000000..fea4b2d --- /dev/null +++ b/spring/Spring core/Spring Core AOP.md @@ -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(); + } + ``` +