目录

一、注解配置AOP

1. 开启注解支持

2. 在类和方法加入注解

3. 测试

4.为一个类下的所有方法统一配置切点

二、原生Spring实现AOP

1. 引入依赖

2. 编写SpringAOP通知类

3. 编写配置类bean2.xml

4 测试

三、SchemaBased实现AOP

1. 配置切面

2. 测试

往期专栏&文章相关导读

1. Maven系列专栏文章

2. Mybatis系列专栏文章

3. Spring系列专栏文章


一、注解配置AOP

Spring可以使用注解代替配置文件配置切面:

1. 开启注解支持

在xml中开启AOP注解支持

以下是bean1.xml文件

2. 在类和方法加入注解

在通知类上方加入注解 @Aspect:配置切面

在通知方法上方加入注解

  • @Before:前置通知
  • @AfterReturning:后置通知
  • @AfterThrowing:异常通知
  • @After:最终通知
  • @Around:环绕通知

MyAspectAdvice通知类

package com.example.aspect;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.*;import org.springframework.stereotype.Component;@Aspect@Componentpublic class MyAspectJAdvice {// 后置通知@AfterReturning("execution(* com.example.dao.UserDao.*(..))")public void myAfterReturning(JoinPoint joinPoint){System.out.println("切点方法名:"+joinPoint.getSignature().getName());System.out.println("目标对象:"+joinPoint.getTarget());System.out.println("打印日志···"+joinPoint.getSignature().getName()+"方法被执行了!");}// 前置通知@Before("execution(* com.example.dao.UserDao.*(..))")public void myBefore(){System.out.println("前置通知···");}// 异常通知@AfterThrowing(value = "execution(* com.example.dao.UserDao.*(..))",throwing = "e")public void myAfterThrowing(Exception e){System.out.println("异常通知···");System.out.println(e.getMessage());}// 最终通知@After("execution(* com.example.dao.UserDao.*(..))")public void myAfter(){System.out.println("最终通知···");}// 环绕通知@Around("execution(* com.example.dao.UserDao.*(..))")public Object myAround(ProceedingJoinPoint point) throws Throwable {System.out.println("环绕前···");// 执行方法Object obj = point.proceed();System.out.println("环绕后···");return obj;}}

3. 测试

测试方法

// 测试注解开发AOP@Testpublic void testAdd2(){ApplicationContext ac = new ClassPathXmlApplicationContext("bean1.xml");UserDao userDao = (UserDao) ac.getBean("userDao");//userDao.update();userDao.delete();}

测试结果(无异常):

使用update方法测试结果(有异常):

可以看到环绕后没有打印,因为此时碰到异常终止了程序

4.为一个类下的所有方法统一配置切点

如何为一个类下的所有方法统一配置切点:

在通知类中添加方法配置切点

// 添加方法配置切点@Pointcut("execution(* com.example.dao.UserDao.*(..))")public void pointcut(){}

在通知方法上使用定义好的切点,就是把注解括号里面得内容替换成“pointCut()”即可。

二、原生Spring实现AOP

除了AspectJ,Spring支持原生方式实现AOP。但是要注意的是原生方式实现AOP只有四种通知类型:前置通知、后置通知、环绕通知,异常通知。少了最终通知。

1. 引入依赖

org.springframeworkspring-aop5.3.13

2. 编写SpringAOP通知类

Spring原生方式实现AOP时,只支持四种通知类型:

通知类型实现接口
前置通知MethodBeforeAdvice
后置通知AfterReturningAdvice
异常通知ThrowsAdvice
环绕通知MethodInterceptor
package com.example.aspect;import org.aopalliance.intercept.MethodInterceptor;import org.aopalliance.intercept.MethodInvocation;import org.springframework.aop.AfterReturningAdvice;import org.springframework.aop.MethodBeforeAdvice;import org.springframework.aop.ThrowsAdvice;import java.lang.reflect.Method;public class SpringAop implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice, MethodInterceptor {/** * 环绕通知 * @param invocation 目标方法 * @return * @throws Throwable */@Overridepublic Object invoke(MethodInvocation invocation) throws Throwable {System.out.println("环绕前");Object proceed = invocation.proceed();System.out.println("环绕后");return proceed;}/** * 后置通知 * @param returnValue 目标方法的返回值 * @param method 目标方法 * @param args 目标方法的参数列表 * @param target 目标对象 * @throws Throwable */@Overridepublic void afterReturning(Object returnValue, Method method, Object[] args, Object target) throws Throwable {System.out.println("后置通知");}/** * 前置通知 * @param method 目标方法 * @param args 目标方法的参数列表 * @param target 目标对象 * @throws Throwable */@Overridepublic void before(Method method, Object[] args, Object target) throws Throwable {System.out.println("前置通知");}/** * 异常通知 * @param e 异常对象 */public void afterThrowing(Exception e){System.out.println("发生异常了!");}}

3. 编写配置类bean2.xml

springAop

4 测试

测试类UserDaoTest2

import com.example.dao.UserDao;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.springframework.context.support.ClassPathXmlApplicationContext;public class userDaoTest2 {// 原生AOP测试@Testpublic void testAdd(){ApplicationContext ac = new ClassPathXmlApplicationContext("bean2.xml");UserDao userDao = (UserDao) ac.getBean("userDaoProxy");userDao.update();}}

测试结果

OK,这里有个惊喜,如果敲到这里同学,就知道了

其实标签那个bug,是因为原生方法配置类要加上那个标签才可以识别,否则会报一个错误。

三、SchemaBased实现AOP

SchemaBased(基础模式)配置方式是指使用Spring原生方式定义通知,而使用AspectJ框架配置切面。因此这里通知类和上面一样,看上面的即可。

1. 配置切面

aop3.xml配置文件

2. 测试

测试方法

// 使用AspectJ框架配置切面测试@Testpublic void t6(){ApplicationContext ac = new ClassPathXmlApplicationContext("aop3.xml");UserDao userDao = (UserDao) ac.getBean("userDao");userDao.add();}

测试结果

OK,这里的输出应该是我上面定义的不够完美,有些可能重复定义了,所以这里就重复输出了一些东西

往期专栏&文章相关导读

大家如果对于本期内容有什么不了解的话也可以去看看往期的内容,下面列出了博主往期精心制作的Maven,Mybatis等专栏系列文章,走过路过不要错过哎!如果对您有所帮助的话就点点赞,收藏一下啪。其中Spring专栏有些正在更,所以无法查看,但是当博主全部更完之后就可以看啦。

1. Maven系列专栏文章

Maven系列专栏Maven工程开发
Maven聚合开发【实例详解—5555字】

2. Mybatis系列专栏文章

Mybatis系列专栏MyBatis入门配置
Mybatis入门案例【超详细】
MyBatis配置文件 —— 相关标签详解
Mybatis模糊查询——三种定义参数方法和聚合查询、主键回填
Mybatis动态SQL查询 –(附实战案例–8888个字–88质量分)
Mybatis分页查询——四种传参方式
Mybatis一级缓存和二级缓存(带测试方法)
Mybatis分解式查询
Mybatis关联查询【附实战案例】
MyBatis注解开发—实现增删查改和动态SQL
MyBatis注解开发—实现自定义映射关系和关联查询

3. Spring系列专栏文章

Spring系列专栏Spring IOC 入门简介【自定义容器实例】
IOC使用Spring实现附实例详解
Spring IOC之对象的创建方式、策略及销毁时机和生命周期且获取方式
Spring DI简介及依赖注入方式和依赖注入类型
Spring IOC相关注解运用——上篇
Spring IOC相关注解运用——下篇
Spring AOP简介及相关案例
注解、原生Spring、SchemaBased三种方式实现AOP【附详细案例】
Spring事务简介及相关案例
Spring 事务管理方案和事务管理器及事务控制的API
Spring 事务的相关配置、传播行为、隔离级别及注解配置声明式事务