• @EnableAspectJAutoProxy 注解的作用 —— 转载


    @EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)解决同类方法调用时异步和事务不生效:

    我们在开启springboot启动类上添加@EnableAsync,从而启动异步注解@Async

    启动之后,我们可以在需要异步执行的方法上面添加@Async注解,即可实现异步,但是有一点,如果我们需要用同一个类中的方法调用另一个加了@Async注解的方法,这时@Async不起作用,原因和事务注解@Transactional失效的原因一样,没有用到代理类导致,这时我们可以通过在启动类添加@EnableAspectJAutoProxy(proxyTargetClass = true, exposeProxy = true)来解决问题。

    该注解两个参数作用分别为:

        一个是控制aop的具体实现方式,为true的话使用cglib,为false的话使用java的Proxy,默认为false。
        第二个参数控制代理的暴露方式,解决内部调用不能使用代理的场景,默认为false。

    具体解决办法:

    /**
     * 1、首先要知道spring的aop切面的原理是什么?
     * 答:Spring是采用动态代理(AOP)实现对bean的管理和切片,它为我们的每个class生成一个代理对象。
     * 只有在代理对象之间进行调用时,可以触发切面逻辑,也就是切面才可以切进去,才能执行切面里编写的代码。
     * 而在同一个class中,方法B调用方法A,调用的是原对象的方法,而不通过代理对象。所以Spring无法切到这次调用。
     * 2、所以想必你大致也明白了为什么在同一个类里面一个方法调用另外一个带有@Async的方法不起作用了?
     * 不仅仅是这个,同一个类里面一个方法调用另外一个开启事物(@Transactional)的的方法,事物也是不起作用的。
     * 3、自定义的注解在同一个类里面方法调用也是不起作用的,总的来说同一个类里面总的来说只要是同一个类里面的方法间调用,
     * 那么切面都是无效的,aop都无法切入进入。
     * 4、解决办法用AopContext.currentProxy()获取一个代理类,然后用代理类再去调用就好了 代码示例:
     */
    @Service
    public
    class serviceImpl implements service {
     
        @Async
        @TargetDataSource("db1")
        @Override
        public void do(String value) {
            /**
             * 获取本对象的代理对象,再进行调用这个类里面的其他方法,那么被调用的那个方法上面如果有切面     
             * 那么切面就可以生效了,本代码示例就是在开启事物之前先动态切换数据源,       
             * 这样下面的dosomething上的@Transactional开启事物方法就可以生效了,      
             * 动态切换数据源要注意一个问题,就是在开启事物之前要先切换成需要的数据源,不要在开启事物     
             * 之后在切换数据源不然会切换失败,因为一个事物的开启是建立在与一个数据源建立连接的基础上开启的    
             * 所以如果先开启事物然后再切换数据源会报错,切换会失败       
             */
            ((serviceImpl) AopContext.currentProxy()).dosomething(value);
        }
     
        /**
         * 要注意
         * @Transactional是否是生效的
         *
         * @param value
         */
        @Transactional
        @Override
        public void dosomething(String value) {
            //dosomething()
        }
    }

    ————————————————
    版权声明:本文为CSDN博主「LiZhen798」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/LiZhen314/article/details/120495143

  • 相关阅读:
    微信退款和支付宝退款接口调用(java版)
    SpringBoot实现JWT认证
    param-validate的使用
    SpringBoot统一参数校验开源项目:param-validate
    AOP+自定义注解实现全局参数校验
    Java自定义注解的实现
    Java初级面试题--持续更新
    React-native run-android fail on :app:processDebugResources解决办法
    【原创】Ionic单页应用跳转外链,构造路由返回的解决办法及代码
    angular 负数遇到货币过滤器,负号会变成括号的解决办法
  • 原文地址:https://www.cnblogs.com/winstonet/p/16132363.html
Copyright © 2020-2023  润新知