如果是这样,则需要哪种配置?不推荐这样吗?
带注释的类:
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)它)。 BeanFactoryPostProcessor
或XML
中定义与@Configuration
连接的bean(即,对于这些bean不要使用@Component
)。