Spring AOP的内部调用问题

前几天遇到一个AOP内部调用不生效的问题,在网上查找了一些办法

1、使用@EnableAspectJAutoProxy(exposeProxy = true)注解

然后调用AopContext.currentProxy() 获取当前代理对象调用需要使用的方法

2、实现BeanPostProcessor接口,重写postProcessAfterInitialization方法,在初始化的时候手动注入需要用到的对象

第一种方法 我试了下没起作用后台会报错,大概意思设置exposeProxy = true可是我已经设置了

分析原因可能是我用定时器调用的方法而AopContext.currentProxy() 是使用ThreadLocal存储的当前代理,可能是线程上下文不一致导致获取不到单签代理。

第二种方法是好用的附上代码方便以后自己看,

@Configuration
public class InjectBeanSelfProcessor implements BeanPostProcessor, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        //如果Bean不是MyService跳过
        if (!(bean instanceof MyService)) {
            return bean;
        }
        MyService service = (MyService) bean;
        //如果当前对象是AOP代理对象,直接注入
        if (AopUtils.isAopProxy(bean)) {
            service.setSelf(bean);
        } else {
            //如果当前对象不是AOP代理,则通过context.getBean(beanName)获取代理对象并注入
            //此种方式不适合解决prototype Bean的代理对象注入
            service.setSelf(applicationContext.getBean(beanName));
        }
        return bean;
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
}

  

//如果有多个类需要内部调用,可以用接口定义
//然后实现接口就行了
public class MyService {

        MyService proxySelf;

        public void setSelf(Object proxyBean) {
            this.proxySelf = (MyService) proxyBean;
        }

    }


原文地址:https://www.cnblogs.com/wangchaoyu/p/10935791.html

时间: 2024-11-06 07:25:13

Spring AOP的内部调用问题的相关文章

spring aop 之链式调用

关关雎鸠,在河之洲.窈窕淑女,君子好逑. 概述 AOP(Aspect Orient Programming),我们一般称为面向方面(切面)编程,作为面向对象的一种补充,用于处理系统中分布于各个模块的横切关注点,比如事务管理.日志.缓存等等. Spring AOP采用的是动态代理,在运行期间对业务方法进行增强,所以不会生成新类,Spring AOP提供了对JDK动态代理的支持以及CGLib的支持.本章我们不关注aop代理类的实现,我简单实现一个指定次序的链式调用. 实现链式调用的 MethodIn

关于 Spring AOP (AspectJ) 你该知晓的一切

[版权申明]未经博主同意,谢绝转载!(请尊重原创,博主保留追究权) http://blog.csdn.net/javazejian/article/details/54629058 出自[zejian的博客] 关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容

Spring AOP 问与答

AOP的实现有哪些 AOP常见的实现有: Spring AOP Aspectj Guice AOP Jboss AOP 等 AOP Alliance 是什么, 为什么Spring AOP, G UICE AOP等需要aopalliance.jar? AOP Alliance定义了AOP中的基础概念,但它并不是一种AOP的实现,它的目标为各种AOP实现提供统一的接口.Spring AOP, GUICE等都采用了AOP Alliance中定义的接口. Spring AOP 和 Aspectj的区别?

关于 Spring AOP (AspectJ) 该知晓的一切

关联文章: 关于Spring IOC (DI-依赖注入)你需要知道的一切 关于 Spring AOP (AspectJ) 你该知晓的一切 本篇是年后第一篇博文,由于博主用了不少时间在构思这篇博文,加上最近比较忙,所以这篇文件写得比较久,也分了不同的时间段在写,已尽最大能力去连贯博文中的内容,尽力呈现出简单易懂的文字含义,如文中有错误请留言,谢谢. OOP的新生机 OOP新生机前夕 神一样的AspectJ-AOP的领跑者 AspectJ的织入方式及其原理概要 基于Aspect Spring AOP

Spring技术内幕:Spring AOP的实现原理(三)

生成SingleTon代理对象在getSingleTonInstance方法中完成,这个方法时ProxyFactoryBean生成AopProxy对象的入口.代理对象会封装对target目标对象的调用,也就是说针对target对象的方法调用行为会被这里生成的代理对象所拦截.具体的生成过程是首先读取ProxyFactoryBean配置,为生成代理对象做好准备.Spring通过AopProxy类来具体生成代理对象.对于getSingleTonInstance方法中生成代理对象的过程如下: /** *

Spring技术内幕:Spring AOP的实现原理(一)

一.SpringAOP的概述 1.AOP概念 AOP是Aspect-Oriented Programming(面向切面编程)的简称.维基百科的解释如下: Aspect是一种新的模块化机制,用来描述分散在对象.类或函数中的横切关注点(crosscutting concern).从关注点中分离出横切关注点是面向切面的程序设计的核心.分离关注点使解决特定领域问题的代码从业务逻辑代码中独立出来,业务逻辑的代码中不再含有针对特定领用问题代码的调用,业务逻辑同特定领域问题的关系通过切面来封装.维护,这样原本

Spring AOP不拦截从对象内部调用的方法

拦截器的实现原理很简单,就是动态代理,实现AOP机制.当外部调用被拦截bean的拦截方法时,可以选择在拦截之前或者之后等条件执行拦截方法之外的逻辑,比如特殊权限验证,参数修正等操作. 但是最近在项目中要在一个事务中跨数据源进行操作.数据库跨源就不在这里说了,可以自行百度. 这里出现的问题就是,如果我们要拦截某个类的多个方法,且在该类的方法中使用this调用要拦截的方法时会导致拦截失败. 这样说有点抽象,看一个代码: package com.intsmaze.before; public clas

Spring AOP不拦截从对象内部调用的方法原因

拦截器的实现原理很简单,就是动态代理,实现AOP机制.当外部调用被拦截bean的拦截方法时,可以选择在拦截之前或者之后等条件执行拦截方法之外的逻辑,比如特殊权限验证,参数修正等操作. 但是最近在项目中要在一个事务中跨数据源进行操作.数据库跨源就不在这里说了,可以自行百度. 这里出现的问题就是,如果我们要拦截某个类的多个方法,且在该类的方法中使用this调用要拦截的方法时会导致拦截失败. 这样说有点抽象,看一个代码: package com.intsmaze.before; public clas

Spring的Bean内部方法调用无法使用AOP切面(CacheAble注解失效)

今天在使用Spring cache的Cacheable注解的过程中遇见了一个Cacheable注解失效的问题,检查问题发生的原因是因为Spring的Cacheable注解是基于Spring AOP实现的,但是类内部方法互相调用时不会被Spring AOP拦截的,所以导致被调用方法的Cacheable注解失效,特此记录. 问题复现 @Service public class UserServiceImpl{ @Override public User detail(Long id) { // 校验