AOP(面向切面编程):将那些与业务无关,却为业务模块所共同调用的逻辑(例如事务处理、日志管理、权限控制等)封装抽取成一个可重用的模块,这个模块被命名为“切面”(Aspect),便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可拓展性和可维护性;
在Spring AOP中,切面由切点(Pointcut)和通知(Advice)组成。切点是一个表达式,用于匹配哪些方法需要被横切,通知是在切点位置执行的代码,表示横切逻辑。
切点表达式配置语法:
execution(修饰符 返回值 包名称.类名称.方法名称(参数列表))
execution(public void com.apesource.service.ServiceImp.findAll())
如果有参数 int======>int String===>java.lang.String
Spring AOP提供了几种常见的通知类型,包括:
Spring AOP 基于动态代理实现:
- 如果被代理的对象,已经实现某个接口,则 Spring AOP 会使用 JDK Proxy(反射),基于接口的方式,创建代理对象;
- 如果被代理的对象,没有实现某个接口, Spring AOP 会使用 Cglib,基于继承的方式,生成一个被代理对象的子类来作为代理;
Spring AOP可以通过注解或XML配置的方式来定义切点和通知,并且可以与Spring的IOC容器无缝集成,使得切面和目标对象的创建和管理变得更加简单。
1.添加依赖:
-
-
org.springframework -
spring-context -
5.3.28 -
-
-
-
org.aspectj -
aspectjweaver -
1.9.7 -
2.创建切面类:
- public class LoggerUtil {
- //前置通知
- public void beforeMethod(){
- System.out.println("前置通知=====>"+new Date());
- }
- //返回通知
- public void afterRrturnMethod(){
- System.out.println("返回通知=====>"+new Date());
- }
- //异常通知
- public void throwMethod(){
- System.out.println("异常通知=====>"+new Date());
- }
- //后置通知
- public void afterMethod(){
- System.out.println("后置通知=====>"+new Date());
- }
-
- //环绕通知
- public Object arroundMethod(ProceedingJoinPoint pjp){
- Object obj = null;
- try {
- //环绕通知---前置通知
- System.out.println("环绕通知---前置通知");
- Object[] objs = pjp.getArgs();
- obj = pjp.proceed(objs);
- //环绕通知---返回通知
- System.out.println("环绕通知---返回通知");
- } catch (Throwable throwable) {
- //环绕通知---异常通知
- System.out.println("环绕通知---异常通知");
- throwable.printStackTrace();
- } finally {
- //环绕通知---后置通知
- System.out.println("环绕通知---后置通知");
- }
- return obj;
- }
- }
3.配置XML:
-
- <aop:config>
-
- <aop:aspect id="mian" ref="loggerUtil">
-
- <aop:pointcut id="dian" expression="execution(* *...*.*(..))"/>
-
- <aop:before method="beforeMethod" pointcut-ref="dian">aop:before>
- <aop:after-returning method="afterRrturnMethod" pointcut-ref="dian">aop:after-returning>
- <aop:after-throwing method="throwMethod" pointcut-ref="dian">aop:after-throwing>
- <aop:after method="afterMethod" pointcut-ref="dian">aop:after>
- <aop:around method="arroundMethod" pointcut-ref="dian">aop:around>
- aop:aspect>
- aop:config>
1.添加依赖:
-
-
org.springframework -
spring-context -
5.3.28 -
-
-
-
org.aspectj -
aspectjweaver -
1.9.7 -
2.创建切面类:
- @Component
- @Aspect//切面
- //@EnableAspectJAutoProxy
- public class LoggerUtil {
- //切点
- @Pointcut(value="execution(* com.apesource.service.*.*(..))")
- public void dian(){}
-
- //前置通知
- // @Before("dian()")
- public void beforeMethod(){
- System.out.println("前置通知=====>"+new Date());
- }
- //返回通知
- // @AfterReturning("dian()")
- public void afterRrturnMethod(){
- System.out.println("返回通知=====>"+new Date());
- }
- //异常通知
- // @AfterThrowing("dian()")
- public void throwMethod(){
- System.out.println("异常通知=====>"+new Date());
- }
- //后置通知
- // @After("dian()")
- public void afterMethod(){
- System.out.println("后置通知=====>"+new Date());
- }
-
- //环绕通知
- @Around("dian()")
- public Object arroundMethod(ProceedingJoinPoint point){
- Object returnObj = null;//执行切点方法
- try {
- System.out.println("环绕通知====>前置通知");
- //切点
- Object[] obj = point.getArgs();//切点方法的参数
- returnObj = point.proceed(obj);
- System.out.println("环绕通知====>返回通知");
- } catch (Throwable throwable) {
- throwable.printStackTrace();
- System.out.println("环绕通知====>异常通知");
- } finally {
- System.out.println("环绕通知====>后置通知");
- }
- return returnObj;//切点方法的返回值
- }
- }
3.配置XML:(也大可不配直接注解)
-
- <aop:aspectj-autoproxy>aop:aspectj-autoproxy>