当你开始摆弄 Spring 的自动代理功能时,你经常会遇到这种行为,如下所示:
实现的类
BeanPostProcessor接口有
特殊,所以他们受到待遇
因容器而异。全部
BeanPostProcessors 及其直接
引用的bean将被实例化
启动时,作为特殊的一部分
的启动阶段
ApplicationContext,然后所有这些
BeanPostProcessor 将被注册
以排序的方式 - 并应用于
所有进一步的豆子。自从AOP
自动代理是作为
BeanPostProcessor 本身,没有
BeanPostProcessors 或直接
引用的 Bean 有资格获得
自动代理(因此不会有
各个方面“编织”到其中。
对于任何这样的 bean,您应该看到
信息日志消息:“Bean 'foo' 不是
有资格被所有人处理
BeanPostProcessors(例如:不
有资格自动代理)”。
换句话说,如果我编写自己的 BeanPostProcessor,并且该类直接引用上下文中的其他 bean,那么这些引用的 bean 将不符合自动代理的条件,并且会记录一条消息来说明这一点。
我的问题是,追踪直接引用的位置可能非常困难,因为“直接引用”实际上可能是一系列传递依赖项,最终会占用应用程序上下文中的一半 bean。 Spring 给你的只是一条信息消息,除了告诉你一个 bean 何时被捕获在这个引用网络中之外,它并没有多大帮助。
我正在开发的 BeanPostProcessor 确实有对其他 bean 的直接引用,但它是一组非常有限的引用。尽管如此,根据日志消息,我上下文中的几乎每个 bean 都被排除在自动代理之外,但我看不到这种依赖关系发生在哪里。
有没有人找到更好的方法来追踪这个问题?
按照这个食谱:
-
Open BeanPostProcessorChecker
在你的 IDE 中(它是一个内部类AbstractApplicationContext
)
-
设置断点if (logger.isInfoEnabled()) {
在方法中postProcessAfterInitialization
-
运行你的代码
-
当您到达断点时,查找对getBean(String,Class<T>)
在你的堆栈跟踪中。
其中一个调用将尝试创建一个BeanPostProcessor
。罪魁祸首应该是那个豆子。
背景
想象一下这种情况:
public class FooPP implements BeanPostProcessor {
@Autowire
private Config config;
}
当 Spring 必须创建时config
(因为它是一个依赖项FooPP
),它有一个问题:合同说所有BeanPostProcessor
必须应用于正在创建的每个 bean。但是当Spring需要的时候config
,至少有一个PP(即FooPP
) 尚未准备好提供服务!
当您使用@Configuration
定义这个bean的类:
@Configuration
public class BadSpringConfig {
@Lazy @Bean public Config config() { return new Config(); }
@Lazy @Bean public FooPP fooPP() { return new FooPP(); }
}
每个配置类都是一个 bean。这意味着要建造一个豆类工厂BadSpringConfig
,Spring需要应用后处理器fooPP
但要做到这一点,它首先需要 bean 工厂......
在此示例中,可以打破循环依赖性之一。你(们)能做到FooPP
实施BeanFactoryAware
让 Spring 注入BeanFactory
进入后处理器。这样,您就不需要自动装配。
稍后在代码中,您可以懒惰地请求 bean:
private LazyInit<Config> helper = new LazyInit<Config>() {
@Override
protected InjectionHelper computeValue() {
return beanFactory.getBean( Config.class );
}
};
@Override
public Object postProcessBeforeInitialization( Object bean, String beanName ) throws BeansException {
String value = helper.get().getConfig(...);
}
(LazyInit 的来源)
要打破 bean 工厂和后处理器之间的循环,您需要在 XML 配置文件中配置后处理器。 Spring 可以读取它并构建所有结构而不会感到困惑。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)