Spring学习笔记——AOP
参考:【狂神说Java】Spring5最新完整教程IDEA版通俗易懂
尚硅谷-Spring5框架2020最新版教程
1. 概述
- 百度百科
- 在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期间动态代理实现程序功能的统一维护的一种技术。
- AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。
- 利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
2. 环境搭建
-
导入aspectjweaver
<dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.9.5</version> </dependency>
3. 基于xml的AOP
-
编写测试文件
AOP.java
public class AOP { public void test(){ System.out.println("test"); } }
Before.java
public class Before{ public void beforeAOP(){ System.out.println("beforeAOP"); } }
After.java
public class After{ public void afterAOP() { System.out.println("afterAOP"); } }
Around.java
public class Around { public void aroundAOP() { System.out.println("aroundAOP"); } }
-
注册bean
<bean id="aop" class="com.naclo.AOP"/> <bean id="before" class="com.naclo.Before"/> <bean id="after" class="com.naclo.After"/> <bean id="around" class="com.naclo.Around"/>
-
使用
aop:config
声明aop配置<aop:config> .... </aop:config>
-
使用
aop:aspect
配置切面<aop:aspect id="" ref=""> ... </aop:aspect>
- id:切面的唯一标识;
- ref:引用配置好的通知类bean的id。
-
使用
aop:pointcut
配置切入点表达式<aop:pointcut id="pointcut" expression="execution(* com.naclo.AOP.*(..))"/>
说明:
-
id:切入点的唯一标识;
-
expression:定义切入点表达式:
-
execution(表达式)
-
语法:
execution([修饰符] 返回值类型 包名.类名.方法名(参数))
-
写法:
-
全匹配:
public void com.naclo.AOP.test()
-
访问修饰符可以省略:
void com.naclo.AOP.test()
-
返回值可以使用*号,表示任意返回值
* com.naclo.AOP.test()
-
包名可以使用*号,表示任意包,但是有几级包,需要写几个
* *.*.AOP.test()
-
使用…来表示当前包,及其子包
* com..AOP.test()
-
类名可以使用*号,表示任意类
* com..*.test()
-
方法名可以使用*号,表示任意方法
* com..*.*()
-
参数列表可以使用*,表示参数可以是任意数据类型,但是必须有参数
* com..*.*(*)
-
参数列表可以使用…表示有无参数均可,有参数可以是任意类型
* com..*.*(..)
-
全通配方式
* *..*.*(..)
-
-
-
-
-
使用
aop:xxx
配置对应的通知类型<aop:xxx method="" pointcut-ref=""/>
aop:before
:用于配置前置通知;aop:after
:用于配置最终通知;aop:after-returning
:用于配置后置通知;aop:after-throwing
:用于配置异常通知;aop:around
:用于配置环绕通知;
-
参数说明:
-
method:指定通知中方法的名称;
-
pointct:定义切入点表达式 ;
-
pointcut-ref:指定切入点表达式的引用;
-
-
ss
4. 使用aop:advisor实现AOP
-
增强类实现Advice接口。
-
前置增强需要实现MethodBeforeAdvice,重写before方法
public class Before implements MethodBeforeAdvice { public void before(Method method, Object[] args, Object target) throws Throwable { System.out.println("before"); } }
-
后置增强需要实现AfterReturningAdvice,重写afterReturning方法
public class After implements AfterReturningAdvice { public void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable { System.out.println("after"); } }
-
-
配置aop
<bean id="aop" class="com.naclo.AOP"/> <bean id="before" class="com.naclo.Before"/> <bean id="after" class="com.naclo.After"/> <aop:config> <aop:pointcut id="pointcut" expression="execution(* com.naclo.AOP.*(..))"/> <aop:advisor advice-ref="before" pointcut-ref="pointcut"/> <aop:advisor advice-ref="after" pointcut-ref="pointcut"/> </aop:config>
5. 基于注解的AOP
-
开启spring对注解AOP的支持
<aop:aspectj-autoproxy/>
-
注解说明
@Aspect
:把当前类声明为切面类;@Pointcut
:指定切入点表达式;- value:指定表达式的内容;
@Before
:把当前方法看成是前置通知;@AfterReturning
:把当前方法看成是后置通知;AfterThrowing
:把当前方法看成是异常通知;@After
:把当前方法看成是最终通知;@Around
:把当前方法看成是环绕通知;- value:用于指定切入点表达式,还可以指定切入点表达式的引用;
6. 其他
-
指定切面的优先级
-
在同一个连接点上应用不止一个切面时,除非明确指定,否则它们的优先级是不确定的。
-
切面的优先级可以通过实现Ordered 接口或利用@Order 注解指定。
-
实现Ordered 接口,getOrder()方法的返回值越小,优先级越高。
-
若使用@Order 注解,序号出现在注解中
-
注解:
@Aspect @Order(1) public class Around { }
-
接口:
public class Around implements Ordered { public int getOrder() { return 1; } }
-
-