环绕通知的基本概念
它是通过拦截目标方法的方式,在目标方法的前后增强功能的通知。它是功能最强大的通知,一般事务使用此通知。它可以轻易的改变目标方法的返回值。
环绕通知执行流程分析
环绕通知的方法 (切面方法的返回值(就是目标方法的返回值) myAruond (切面方法的参数(就是目标方法本身)))
目标方法的前切功能的实现
目标方法
public String doSome(){return "abcd";}
调用目标方法
Object obj = doSome();
目标方法的后切功能的实现
环绕通知代码实现
业务
package com.chentianyu.s03;public interface SomeService {String doSome(String name,int age);}
业务实现类
package com.chentianyu.s03;import org.springframework.stereotype.Service;@Servicepublic class SomeServiceImpl implements SomeService {@Overridepublic String doSome(String name, int age) {System.out.println("doSome业务方法被执行了..."+name);return "abcd";}}
切面类
package com.chentianyu.s03;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.Aspect;import org.springframework.stereotype.Component;@Aspect@Componentpublic class MyAspect {/*** 环绕通知方法的规范* 1.访问权限:public* 2.切面方法有返回值,此返回值就是目标方法的返回值* 3.方法名自定义* 4.方法有参数,此参数就是目标方法本身* 5.回避异常Throwable(目标方法传过来,通过反射去调用)* 6.使用@Around声明是环绕通知* value: 指定切入点表达式*/@Around(value = "execution(* com.chentianyu.s03.*.*(..))")public Object myAround(ProceedingJoinPoint/*通过这个接口的实现类去我们需要的目标方法*/ pjp) throws Throwable {//前切功能实现System.out.println("环绕通知中的前置功能实现...");//目标方法调用Object obj = pjp.proceed(pjp.getArgs());//后切功能实现System.out.println("环绕通知中的后置功能实现...");return obj.toString().toUpperCase();//改变了目标方法的返回值}}
配置文件
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd"><aop:aspectj-autoproxy></aop:aspectj-autoproxy><context:component-scan base-package="com.chentianyu.s03" /></beans>
测试类
@Test
public void test03(){
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("s03/applicationContext.xml");
com.chentianyu.s03.SomeService someService = (com.chentianyu.s03.SomeService) applicationContext.getBean("someServiceImpl");
String s = someService.doSome("张三", 23);
System.out.println("在测试方法中的目标方法返回值:" + s);
}
结果
环绕通知中的前置功能实现...
doSome业务方法被执行了...张三
环绕通知中的后置功能实现...
在测试方法中的目标方法返回值:ABCD
