BeanFactoryPostProcessor

BeanFactoryPostProcessor

如果是这样,则需要哪种配置?不推荐这样吗?

带注释的类:

package com.springbug.beanfactorydependencyissue;

import javax.annotation.Resource;
import org.springframework.stereotype.Component;

@Component
public class DependantBean {

    @Resource
    DependencyBean dependencyBean; // Isn't initialized correctly

    public DependencyBean getDependencyBean() {
        return dependencyBean;
    }
}

失败的依赖项Bean:
package com.springbug.beanfactorydependencyissue;

import org.springframework.stereotype.Component;

@Component
public class DependencyBean {

}

测试用例:
package com.springbug.beanfactorydependencyissue;

import static org.fest.assertions.Assertions.assertThat;

import javax.annotation.Resource;

import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.Test;

import com.springbug.beanfactorydependencyissue.DependantBean;

@ContextConfiguration(locations = "/applicationContext.xml")
public class AppTest extends AbstractTestNGSpringContextTests {

    @Resource
    private DependantBean annotatedBean;

    @Test
    public void testThatDependencyIsInjected() {
        // Fails as dependency injection of annotatedBean.dependencyBean does not work
        assertThat(annotatedBean.getDependencyBean()).isNotNull();
    }
}

具有“错误”依赖项的自定义BeanFactoryPostProcessor:
package com.springbug.beanfactorydependencyissue;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class BeanFactoryPostProcessorConfiguration {

    /**
     * The {@link DependantBean} here causes the bug, can
     * {@link BeanFactoryPostProcessor} have regular beans as dependencies?
     */
    @Bean
    public static BeanFactoryPostProcessor beanFactoryPostProcessor(
            DependantBean dependantBean) {
        return new BeanFactoryPostProcessor() {

            public void postProcessBeanFactory(
                    ConfigurableListableBeanFactory beanFactory)
                    throws BeansException {

            }
        };
    }
}

applicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:component-scan base-package="com.springbug.beanfactorydependencyissue" />
</beans>
BeanFactoryPostProcessorConfiguration为什么不能引用DependantBean
DependantBean中生成的AppTest实例不为null,即它是由spring创建的,但其依赖项(DependencyBean)为null。 Spring完全不提示的事实使我相信这是Spring内的错误。是否应该支持该用例?

顺便说一句,我正在使用spring-*-3.1.1.RELEASE.jar
顺便说一句2:也可以在here中找到重现该错误的代码。

最佳答案

也许更简单和更具描述性的答案:

是的,可以将@Component bean作为BeanFactoryPostProcessor依赖项。

但是,在激活任何BeanFactoryPostProcessor之前,将实例化BeanPostProcessor的每个依赖项。其中包括:

  • CommonAnnotationBeanPostProcessor-负责@PostConstruct@Resource和其他一些批注
  • AutowiredAnnotationBeanPostProcessor-负责@Autowired@Value批注
  • ...还有更多...

  • 所以总结一下:

    是的,可以将@Component bean用作BeanFactoryPostProcessor依赖项,但是他们不能使用基于注释的注入(inject)(@Autowired@Resource@WebServiceRef,...)以及BeanPostProcessor s提供的其他功能。

    您的示例的解决方法可能是按照您的建议创建ApplicationContext层次结构:
  • 每个上下文初始化并应用其自己的后处理器基础结构,您仍然可以在这些基础结构中引用父上下文的依赖关系。


  • 其他方法可能是(我更喜欢):
  • BeanFactoryAware bean上使用@Component接口(interface)并自己拉出依赖项(因为Spring不会注入(inject)它)。
  • 在上下文配置BeanFactoryPostProcessorXML中定义与@Configuration连接的bean(即,对于这些bean不要使用@Component)。
  • 09-27 13:43