Spring AOP做基于注解的缓存,不生效的可能原因小结

背景

AOP在处理一些共性业务的时候提供了十分便利的扩展性,有着十分广泛的应用场景。
在Java中常用的两种框架主要就是Spring AOP和原生的Aspectj,当然Spring AOP本身也借鉴和引用了很多Aspectj中的东西。

虽然AOP本身的使用很便利,但是在使用中主要还是有以下一些注意点,需要在使用Spring AOP(Aspectj由于了解不多暂不讨论)注意一些很容易被忽略的细节点和原因:

  1. AOP的切面方法,不能用于private的方法,但是aspectj是可以的;
  2. AOP是基于代理机制的,虽然可以通过xml声明究竟是使用jdk动态代理还是cglib的动态代理,但是是否可能存在一些场景使得代理不生效呢?
  3. AOP在作用自身类内部的方法调用的时候,为什么会失效呢?

虽然以上都是很简单的细节点,但是有时候忽略的话,会导致我们很难找到问题点从而改变我们的代码。笔者在实际的基于AOP的项目中就遇到了一些类似的问题。

好吧,终于我还是忍不住了,其实我主要就是来安利一个自己写的基于Annotation的AOP缓存插件的,以上问题是在运用插件的时候可能导致不生效的一些原因!所以我把不生效的原因都写这么具体了,你考虑看一下么?(p.s. 看都看了,不考虑试一下么~ 逃~)

所以,重要的事情说三遍,有兴趣的同学请参考基于基于Annotation的AOP缓存插件:

以下是项目说明:

基于AOP注解实现的缓存插件 在需要缓存的地方使用@SimpleCache注解即可实现缓存

  • 提供自定义的expiretime
  • 提供多种存储实现
  • 通过xml bean和AOP的方式来实现,侵入性小

不过既然为了凑字数,还是写到底吧~ 下面是刚刚三个小问题的答案~


为什么spring AOP不能应用于private方法

其实如果单纯说原因的话,可能主要还是基于安全性的考虑,因为私有的方法从本身机制上来说就应该是不可见的。
当然后来由于反射等的出现,特别是cglib直接能修改字节码这种神器,非要能代理到private的方法也是可以实现的(例如aspectj中就可以达到这个目的),但是这还是从根本上破坏了java对private的定义,因此spring可能考略这些因素,对aop的时候做了一些权限的检验限制,如下代码所示

//  有很多对权限做检验的地方
    /**
     * Implementation of AOP Alliance MethodInvocation used by this AOP proxy.
     */
    private static class CglibMethodInvocation extends ReflectiveMethodInvocation {

        private final MethodProxy methodProxy;

        private final boolean publicMethod;

        public CglibMethodInvocation(Object proxy, Object target, Method method, Object[] arguments,
                Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {
            super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);
            this.methodProxy = methodProxy;
            this.publicMethod = Modifier.isPublic(method.getModifiers());
        }

        /**
         * Gives a marginal performance improvement versus using reflection to
         * invoke the target when invoking public methods.
         */
        @Override
        protected Object invokeJoinpoint() throws Throwable {
            if (this.publicMethod) {
                return this.methodProxy.invoke(this.target, this.arguments);
            }
            else {
                return super.invokeJoinpoint();
            }
        }
    }

所以,在使用spring AOP的时候需要注意,不要切到private这些方法上去了(别问我怎么知道的……)


是否有存在使得代理失效导致AOP不成功的场景

这种情况主要还是出现于动态代理本身出现了问题导致,主要还是需要我们对动态代理的原理有一个比较好的了解(比如哪种代理是基友哪种实现方式的,以及什么场景下可能会导致无法代理):

  1. jdk动态代理,是jvm自身实现的一个代理,最核心的点在于是一种基于接口的代理,所以如果没有实现接口的话……

  2. cglib代理,核心原理是修改字节码,通过继承来实现代理对象,也就是说如果没法继承(如final修饰符),那么……(此刻补充一句题外话,在上面提到的插件里,设计的时候就是基于cglib的,所以如果你在配置文件里面没有设置使用cglib为true的话……请私信我,我考虑优化一下……)


为什么类的内部使用AOP方法会不走AOP流程

对于这个问题的理解主要还是要对代理方法的主要实现有个理解,如下图所示(图来源于Aspect Oriented Programming with Spring,建议有兴趣的同学可以深入看一下):

AOP使用代理的实际生效原理

代理方法直接上是通过对使用对象的做了一个封装之后,别的所有引入都是通过引用了代理类从而实现走了代理的流程的。那么是否内部调用就没有办法走代理的流程了呢?答案当然是否定的,其实只要在内部调用代理类的方法就可以了(虽然最终实现结果看起来有点奇怪),至于在spring中的实现可以参考之前写的这篇文章AOP切面时BeanPostProcessor返回Bean未被CGlib代理

后记

都看到这里,不点进项目链接里面看看么?(逃~)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,271评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,725评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,252评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,634评论 1 270
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,549评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,985评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,471评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,128评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,257评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,233评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,235评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,940评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,528评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,623评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,858评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,245评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,790评论 2 339

推荐阅读更多精彩内容