@Around
图示
- 环绕通知的切面参数就是目标方法本身
- 环绕通知的返回值就是目标方法的返回值,如果目标方法有返回值的话,可以对该返回值进行修改
- 不论目标方法的返回值是基本类型(8 + 1),还是引用类型,环绕通知对该返回值的修改都可以真正影响到目标方法的返回值
业务接口
package com.example.s03;
/**
* 业务接口
*/
public interface SomeService {
default String order(int orderNums){return null;}
}
业务实现类
package com.example.s03;
import org.springframework.stereotype.Service;
/**
* 业务实现类
*/
@Service
public class SomeServiceImpl implements SomeService{
@Override
public String order(int orderNums) {
System.out.println("预定图书: " + orderNums + "册");
return "order success";
}
}
切面类
package com.example.s03;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
/**
* 切面类
*/
@Aspect
@Component
public class SomeServiceAspect {
/**
* a.环绕通知的方法规范
* 1.方法权限:public
* 2.方法返回值:目标方法的返回值,如果目标方法有返回值可以直接修改
* 3.方法名称:自定义
* 4.方法参数:目标方法本身
* 5.需要使用注解:@Around来指定通知的切入时机
* value参数:用来指定切入点表达式
*
* b.环绕通知示例
* public String order(int orderNums)
*/
@Around(value = "execution(* com.example.s03.*.*(..))")
public Object myAround(ProceedingJoinPoint pjp) throws Throwable {
//前置通知
System.out.println("环绕通知的前置通知: 检查现有图书的册数");
//pjp即为目标方法本身,res为目标方法的返回值,根据反射获取外部调用的目标方法和目标方法需要的参数
Object res = pjp.proceed(pjp.getArgs());
//后置通知
System.out.println("环绕通知的后置通知: 检查预定后的图书册数");
return res.toString().toUpperCase();
}
}
applicationContext.xml
<!-- 添加包扫描 -->
<context:component-scan base-package="com.example.s03"/>
<!-- 绑定业务功能和切面功能-->
<aop:aspectj-autoproxy/>
测试
package com.example.test;
import com.example.s03.SomeService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAroundAspect {
//测试环绕通知
@Test
public void testAroundAspect(){
//获取Spring容器
ApplicationContext ac = new ClassPathXmlApplicationContext("s03/applicationContext.xml");
//获取动态代理对象
SomeService agent = (SomeService) ac.getBean("someServiceImpl");
//调用业务功能
String res= agent.order(1000);
System.out.println("目标方法的返回值: " + res);
}
}
测试输出
- 由测试结果可知,环绕通知包裹了目标方法,依次执行前置通知,目标方法,后置通知,并且成功的对目标方法返回的基本类型的数据做了修改
环绕通知的前置通知: 检查现有图书的册数
预定图书: 1000册
环绕通知的后置通知: 检查预定后的图书册数
目标方法的返回值: ORDER SUCCESS
Process finished with exit code 0
相关文章
暂无评论...