spring中的AOP即面向切面编程:它是在不改变源代码的前提下,对类中的方法进行增强,分为前置,后置,环绕,异常,全篇分为三个
创建项目前:引入aop
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
创建Person:
@Component public class Person { public void eat(){ System.out.println("我要开始吃饭了"); } }
创建切面类:
第一个:前置增强:注意声明切面位置指定是类中的方法
@Component @Aspect @EnableAspectJAutoProxy public class PersonAspect {
private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))"; @Before(PERSON_POINT) public void before(){ System.out.println("请先喝汤"); } }
第二个:增加后置增强
@Component @Aspect @EnableAspectJAutoProxy public class PersonAspect { private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))"; @Before(PERSON_POINT) public void before(){ System.out.println("请先喝汤"); } @After(PERSON_POINT) public void after(){ System.out.println("睡觉了"); } }
第三个:环绕增强
@Component @Aspect @EnableAspectJAutoProxy public class PersonAspect { private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))"; //@Before(PERSON_POINT) public void before(){ System.out.println("请先喝汤"); } // @After(PERSON_POINT) public void after(){ System.out.println("睡觉了"); } @Around(PERSON_POINT) public void around(ProceedingJoinPoint joinPoint) throws Throwable { before(); joinPoint.proceed(); after(); } }
第四个:异常
先在被切面的类上设置异常
@Component public class Person { public void eat(){ System.out.println("我要开始吃饭了"); int num = 10/0; } }
在切面类中捕获异常
@Component @Aspect @EnableAspectJAutoProxy public class PersonAspect { private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))"; //@Before(PERSON_POINT) public void before(){ System.out.println("请先喝汤"); } // @After(PERSON_POINT) public void after(){ System.out.println("睡觉了"); } @Around(PERSON_POINT) public void around(ProceedingJoinPoint joinPoint) throws Throwable { before(); joinPoint.proceed(); after(); } //throwing = "aw" 和Throwable aw 俩个变量名要保持一致 @AfterThrowing(value =PERSON_POINT,throwing = "aw") public void exc(Throwable aw){ System.out.println("出错信息"+aw.getMessage()); } }
测试:
前置增强测试
@SpringBootTest @RunWith(SpringRunner.class) public class ApplicationTest { @Autowired private Person person; @Test public void aopTest(){ person.eat(); } }
结果:在执行自身方法,被拦截,先执行切面类中的方法

后置增强测试类同上,结果:

环绕增强测试结果
异常测试展示:
执行类中的方法时,在切面类的中返回值
问题出现:在类中方法设置返回值
@Component public class Person { public String eat(){ System.out.println("我要开始吃饭了"); return "吃肉了"; } }
增强类
@Component @Aspect @EnableAspectJAutoProxy public class PersonAspect { private static final String PERSON_POINT = "execution(* com.gwq.springmybatis.springmybatis.pojo.Person.eat(..))"; //@Before(PERSON_POINT) public void before(){ System.out.println("请先喝汤"); } // @After(PERSON_POINT) public void after(){ System.out.println("睡觉了"); } @Around(PERSON_POINT) public void around(ProceedingJoinPoint joinPoint) throws Throwable { before(); joinPoint.proceed(); after(); } }
测试类调用:输出方法中的值
@SpringBootTest @RunWith(SpringRunner.class) public class ApplicationTest { @Autowired private Person person; @Test public void aopTest(){ String food = person.eat(); System.out.println(food); } }
问题解决:输出类中的返回值

原文:https://www.cnblogs.com/ghwq/p/13285076.html