在Spring XML中,我可以定义一个bean,它实例化一个用@Configuration注释的类。当我这样做时,该bean被后处理。该类中带有@Bean的任何方法也会添加到容器中。如何在JavaConfig中执行类似的后处理?
这是XML版本:
<bean id="test" class="com.so.Test">
<property name="prop" value="set before instantiating @Beans defined in Test"/>
</bean>
相关的测试类:
@Configuration
class Test {
private String prop;
void setProp(final String prop) {
this.prop = prop;
}
@Bean
NeedThisBean needThisBeanToo() {
return new NeedThisBean(prop);
}
}
如果我使用Spring XML Config,容器中可以使用test
和needThisBeanToo
。 needThisBeanToo
是通过BeanPostProcessor添加的,虽然我不记得是哪一个。如果我使用JavaConfig,则容器中只有test
可用。如何使needThisBeanToo
可用于容器? @Import
可以正常工作,除了,prop
需要needThisBeanToo
才能正确初始化。
使所有这些变得复杂的部分是Test
从我正在消费的库中出售。我不控制Test
,也不能改变它。如果我从JavaConfig驱动它,它将如下所示:
@Configuration
class MyConfiguration
{
@Bean
Test test() {
Test test = new Test();
test.setProp("needed to init `needThisBeanToo` and others");
return test;
}
}
JavaConfig示例不会实例化needThisBeanToo
,尽管它是在Test
中定义的。我需要定义needThisBeanToo
,最好不要自己做,因为我不想复制我不拥有的代码。委托不具吸引力,因为needThisBeanToo
上定义了许多后续注释/范围(以及Test
内定义的其他注释/范围)。
答案 0 :(得分:0)
您的问题是,您完全忽略 @Configuration
注释。那是为什么?
当代码到达此行Test test = new Test();
时,它不会对@Configuration
执行任何操作。为什么?因为注释不是构造函数知道的东西。注释仅标记该类的一些元数据。当spring加载类时,它会搜索注释,当你调用类的构造函数时,则不会。因此,@Configuration
被忽略,因为您使用Test
而不是通过spring实例化new Test()
。
您需要做的是将Test
导入为spring bean。您可以通过问题中显示的XML或@Import
使用XML。 prop
的问题是没有调用setter,因为这不是这样做的方法。你需要做的是做这样的事情:
@Configuration
class Test {
private String prop = "set before instantiating @Beans defined in Test";
@Bean
NeedThisBean needThisBeanToo() {
return new NeedThisBean(prop);
}
}
或者在spring中创建一个属性(这是一个不同的主题)并注入值:
@Configuration
class Test {
@Autowired
@Value("${some.property.to.inject}") // You can also use SPeL syntax with #{... expression ...}
private String prop;
@Bean
NeedThisBean needThisBeanToo() {
return new NeedThisBean(prop);
}
}
您还可以创建类型为String
的bean,并按如下方式注入:
@Configuration
class Test {
@Autowired
@Qualifer("nameOfBeanToInject")
private String prop;
@Bean
NeedThisBean needThisBeanToo() {
return new NeedThisBean(prop);
}
}
在最后一种情况下,您可以使用此bean定义原始MyConfiguration
:
@Configuration
@Import(Test.class)
class MyConfiguration
{
@Bean(name = "nameOfBeanToInject")
String test() {
return "needed to init `needThisBeanToo` and others";
}
}
在任何情况下,您都必须使用Test
或普通的XML bean导入@Import
。通过显式调用构造函数它将无法工作。
答案 1 :(得分:0)
这是一种处理已售出的@Configuration类的方法,这些类需要在创建@Beans之前设置一些属性:
Vended @Configuration类:
@Configuration
class Test {
private String property;
public setProperty(final String property) {
this.property = property;
}
@Bean
PropertyUser propertyUser() {
return new PropertyUser(property);
}
@Bean
SomeBean someBean() {
// other instantiation logic
return new SomeBeanImpl();
}
}
这是消费的@Configuration类:
@Configuration
class MyConfig {
@Bean
static String myProperty() {
// Create myProperty
}
/**
* Extending Test allows Spring JavaConfig to create
* the beans provided by Test. Declaring
* Test as a @Bean does not provide the @Beans defined
* within it.
*/
@Configuration
static class ModifiedTest extends Test {
ModifiedTest() {
this.setProperty(myProperty());
}
@Override
@Bean
SomeBean someBean() {
return new SomeBeanCustomImpl(this.propertyUser());
}
}