Spring AOP-高级
来,直上案例说明: 咻咻........
一. 高级案例1:定义公共切入点
简述
切面类中会有很多通知,大部分通知的切入点都是相同的。
为了切入点 管理和维护更加方便,使用公共切入点。
@Pointcut
方法的修饰符:private
方法的返回值:void
方法无参数
方法无方法体
代码实现
切面类: (注意:标黄色是基于上篇新增的代码)
@Component
@Aspect
public class MyAspect {
@Pointcut("execution(* com.czxy.demo1.service..*.*(..))")
private void myCut1(){}
@AfterThrowing(value="myCut1()",throwing = "ex")
public void a1(JoinPoint joinPoint,Throwable ex){
System.out.println("异常通知:"+joinPoint.getSignature().getName()+"方法出异常了"+ex.getMessage());
}
@AfterReturning(value="myCut1()",returning = "obj")
public void a2(JoinPoint joinPoint,Object obj){
System.out.println("后置通知:"+joinPoint.getSignature().getName()+"方法返回值值是:"+obj);
}
}
二. 高级案例2:定义完整的切面类
代码实现
配置类:
@Configuration
@ComponentScan(basePackages = {"com.czxy.demo2"})
@EnableAspectJAutoProxy
public class SpringConfiguration {
}
切面类:
@Component
@Aspect
public class MyAspect {
/*
* 定义公共切入点
* */
@Pointcut("execution(* com.czxy.demo2.service..*.*(..))")
private void myCut1(){}
/*
* 环绕通知
* */
@Around("myCut1()")
public void a1(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知---连接点执行之前");
Object proceed = pjp.proceed();
System.out.println("环绕通知中-连接点返回值:"+proceed);
System.out.println("环绕通知---连接点执行之后");
}
/*
* 前置通知
* */
@Before("myCut1()")
public void b1(JoinPoint joinPoint){
System.out.println("前置通知---"+joinPoint.getSignature().getName());
}
/*
* 最终通知
* */
@After("myCut1()")
public void a2(JoinPoint joinPoint){
System.out.println("最终通知---"+joinPoint.getSignature().getName());
}
/*
* 后置通知
* */
@AfterReturning(value="myCut1()",returning = "obj")
public void a3(JoinPoint joinPoint,Object obj){
System.out.println("后置通知---"+joinPoint.getSignature().getName());
}
/*
* 异常通知
* */
@AfterThrowing(value="myCut1()",throwing = "ex")
public void a4(JoinPoint joinPoint,Throwable ex){
System.out.println("异常通知---"+joinPoint.getSignature().getName()+"异常是:"+ex.getMessage());
}
}
Service:
@Service
public class Demo2ServiceImpl implements Demo2Service {
@Override
public void test01() {
System.out.println("---test01---");
}
@Override
public String test02() {
System.out.println("---test02---");
return "嘤嘤嘤";
}
@Override
public void test03(String a, String b) {
System.out.println("---test03---");
System.out.println("参数a:"+a+"\t 参数b:"+b);
}
@Override
public void test04() {
System.out.println("---test04---");
int a=1/0;
}
}
测试类:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {SpringConfiguration.class})
public class Demo2Test {
@Resource
private Demo2Service demo2Service;
@Test
public void run1(){
demo2Service.test01();
System.out.println("++++++++");
demo2Service.test02();
System.out.println("++++++++");
demo2Service.test03("aa","bb");
System.out.println("++++++++");
demo2Service.test04();
System.out.println("++++++++");
}
}
通知的执行顺序【重点】
三. 高级案例3:后置通知和环绕通知的结合 (返回值传递)
代码实现
切面类
@Component@Aspect
public class MyAspect {
/*
* 定义公共切入点
* */
@Pointcut("execution(* com.czxy.demo2.service..*.*(..))")
private void myCut1(){}
/*
* 环绕通知
* */
@Around("myCut1()")
public Object a1(ProceedingJoinPoint pjp) throws Throwable {
System.out.println("环绕通知---连接点执行之前");
Object proceed = pjp.proceed();
System.out.println("环绕通知中-连接点返回值:"+proceed);
System.out.println("环绕通知---连接点执行之后");
return proceed;
}
/*
* 前置通知
* */
@Before("myCut1()")
public void b1(JoinPoint joinPoint){
System.out.println("前置通知---"+joinPoint.getSignature().getName());
}
/*
* 最终通知
* */
@After("myCut1()")
public void a2(JoinPoint joinPoint){
System.out.println("最终通知---"+joinPoint.getSignature().getName());
}
/*
* 后置通知
* */
@AfterReturning(value="myCut1()",returning = "obj")
public void a3(JoinPoint joinPoint,Object obj){
System.out.println("后置通知---"+joinPoint.getSignature().getName()+"返回值是:"+obj);
}
/*
* 异常通知
* */
@AfterThrowing(value="myCut1()",throwing = "ex")
public void a4(JoinPoint joinPoint,Throwable ex){
System.out.println("异常通知---"+joinPoint.getSignature().getName()+"异常是:"+ex.getMessage());
}
}
小结;
SpringAOP:面向切面编程。 在不修改原有代码的基础上,把新代码插入到原有代码的执行中。
连接点:被spring拦截的方法
切入点:通常是一个表达式。表示spring需要拦截的连接点有哪些
通知:拦截到连接点后要做哪些事
切面:包含切入点和通知 。 @Aspect
@Around:环绕通知。控制连接点是否执行
@Before:前置通知。
@After:最终通知。无论如何都一定会被执行的通知
@AfterReturning:后置通知。获取连接点的返回值。(若设置了环绕通知,环绕通知必须使用返回值的形式传递连接点返回值)
@AfterThrowring:异常通知。仅连接点出现异常时。
看完恭喜你,又进步了一点点!!!
你知道的越多,不知道的越多!
~感谢志同道合的你阅读, 你的支持是我学习的最大动力 ! 加油 ,陌生人一起努力,共勉!!
来源:oschina
链接:https://my.oschina.net/ithuang/blog/4263583