Spring aop-本类方法调用切面增强失效

来源:互联网 发布:人声模拟软件 编辑:程序博客网 时间:2024/06/05 15:35

http://blog.csdn.net/u013076044/article/details/52954033


在我们使用spring的时候,往往会遇到在本类被aop代理的时候,访问本类其他被代理的方法,发现并没有被代理。那么我们应该如何实现呢

xml配置

       <!--expose-proxy 暴露代理类-->       <aop:aspectj-autoproxy expose-proxy="true"/>
  • 1
  • 2
  • 1
  • 2

Java

@Servicepublic class AService {    @Transactional(propagation = Propagation.REQUIRED)    public void a(){        System.out.println("---------------a start--------------------");        //此方法相当于调用当前线程中的Aservice的代理类,是保存在ThreadLocal中的        //1 ((AService) AopContext.currentProxy()).b();        //2 this.b();        System.out.println("---------------a end--------------------");        //throw new RuntimeException("i want run , but i have some error");    }    @Transactional(propagation = Propagation.REQUIRES_NEW)    public void b(){        System.out.println("----------------b start-------------------");        //throw new RuntimeException("i want run , but i have some error");        System.out.println("----------------b end-------------------");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

详情请看 文章,点击进入 
在说一下事务传播行为

1. 如果在b方法中抛出runtime Exception的时候,那么a方法回滚2. 如果在a方法中抛出runtime Exception的时候,那么b方法不回滚
  • 1
  • 2
  • 1
  • 2

首先分析一下第一种情况 
1. b在执行的时候会新建一个事务并把当前a的事务挂起,b在执行的时候回滚。那么a也会接受到此exeception并回滚 
2. 在a方法中抛出异常并回滚,但是现在b已经执行完毕了,已经commit了,那么只有a会回滚。

=====================2017 - 04 - 23=========================

现在发现上面说的都是屁话 
完全不知道当时在想些什么

现在重新陈述一遍

现在的需求是 我在a方法中直接调用的b的时候,会发生的状况就是 a 回滚的b也回滚了 很气 虽然没有合适的业务场景说明 a回滚的时候不需要b回滚。但是我们需要a回滚的情况下 b不需要回滚。

如果我们直接调用this.b()的话 确实是 ab 一起回滚。因为都是在一个事务里面。

但是我们的初衷在b上面标注b开启一个新的事务。那么这种情况下 
b是一个新的事务。a回滚的时候b已经commit了 
那么我们目的就达到了。 
这样的需求的解决方法就是: 在a调用的b方法上是已经被增强的b方法。那么我们就需要找到此时的代理类。增强了b方法的类。也就是当前线程中的代理类。

spring提供了这个配置

在配置文件中配置暴露代理类就好了

       <!--expose-proxy 暴露代理类-->       <aop:aspectj-autoproxy expose-proxy="true"/>
  • 1
  • 2
  • 1
  • 2

通过下面实现日志的切面说明一下

注解

@Target({ElementType.PARAMETER, ElementType.METHOD})@Retention(RetentionPolicy.RUNTIME)@Documentedpublic @interface PrintLog {}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 1
  • 2
  • 3
  • 4
  • 5

切面类

@Component@Aspectpublic class LogAspectj {    private final static Logger loggger = LoggerFactory.getLogger(LogAspectj.class);    @Pointcut("@annotation(com.wuhulala.studySpring.annotation.PrintLog)")    public void log(){    }    @Before("log()")    public void before(JoinPoint joinPoint){        loggger.debug(joinPoint.getSignature().getName()+" : start.....");    }    @After("log()")    public void after(JoinPoint joinPoint){        loggger.debug(joinPoint.getSignature().getName()+" : end.....");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

测试方法

@Servicepublic class AOPService {    @PrintLog    public void a(){        System.out.println("---------------a start--------------------");        ((AOPService) AopContext.currentProxy()).b();        //this.b();        System.out.println("---------------a end--------------------");    }    @PrintLog    public void b(){        System.out.println("----------------b start-------------------");        System.out.println("----------------b end-------------------");    }}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

this.b() 打印结果

21:40:37,957 DEBUG com.wuhulala.studySpring.Aspectj.LogAspectj (28) - a : start.....---------------a start------------------------------------b start-----------------------------------b end----------------------------------a end--------------------21:40:37,976 DEBUG com.wuhulala.studySpring.Aspectj.LogAspectj (35) - a : end.....
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

((AService) AopContext.currentProxy()).b()打印结果

21:41:57,381 DEBUG com.wuhulala.studySpring.Aspectj.LogAspectj (28) - a : start.....---------------a start--------------------21:41:57,399 DEBUG com.wuhulala.studySpring.Aspectj.LogAspectj (28) - b : start.....----------------b start-----------------------------------b end-------------------21:41:57,399 DEBUG com.wuhulala.studySpring.Aspectj.LogAspectj (35) - b : end.....---------------a end--------------------21:41:57,400 DEBUG com.wuhulala.studySpring.Aspectj.LogAspectj (35) - a : end.....
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

可见第二种是我们需要的。我们需要b被增强。


原创粉丝点击