![](/img/trans.png)
[英]Autowiring in Spring bean (@Component) created with new keyword
[英]How to use a dynamically created instance as a bean for use in Spring autowiring
我有特定的實例需要用於AnnotationConfigWebApplicationContext
中的自動裝配。 下面是演示錯誤的代碼。 當然,我的情況要復雜得多,實例是在運行時確定的。 我在 spring 配置時間發現了這些實例,這就是為什么如果下面的代碼有效,那就沒問題了。 我試過了,但它會拋出NoSuchBeanDefinitionException
,即使ctx.getBean
能夠找到它。 實現這一目標的正確方法是什么?
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
class Scratch {
static class MyClass {
}
@Configuration
static class TestConfig {
@Autowired
private MyClass myClass;
}
public static void main(String[] args) {
MyClass requiredInstance = new MyClass();
final AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.refresh(); // Throws "BeanFactory not initialized..." on next line if this not here
ctx.getBeanFactory().registerSingleton("myClass", requiredInstance);
// Also tried: ((DefaultListableBeanFactory)ctx.getAutowireCapableBeanFactory()).registerSingleton("myClass", requiredInstance);
System.out.println(ctx.getBean(MyClass.class)); // Outputs "Scratch$MyClass@1804f60d"
ctx.register(TestConfig.class);
ctx.refresh(); // Throws "NoSuchBeanDefinitionException: No qualifying bean of type 'Scratch$MyClass' available:"
}
}
在這里找到了解決方案https://blog.pchudzik.com/201705/dynamic-beans/ 。 我在其他地方看到過 BeanFactoryPostProcessor ,但他們沒有展示如何創建實例。 這個例子展示了使用我需要的工廠機制。
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
class Scratch {
static class MyClass {
}
@Configuration
static class TestConfig {
@Autowired
private MyClass myClass;
}
public static void main(String[] args) {
final AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(TestConfig.class);
ctx.register(DynamicBeanFactoryProcessor.class);
ctx.refresh();
System.out.println(ctx.getBean("myClass")); // Outputs "Scratch$MyClass@1804f60d"
System.out.println(ctx.getBean(MyClass.class)); // Outputs "Scratch$MyClass@1804f60d"
}
@Configuration
public static class DynamicBeanFactoryProcessor implements BeanFactoryPostProcessor {
public <T> T createInstance(Class<T> c) {
return c.cast(new MyClass()); // Create dynamic instance here
}
@Bean
public DynamicBeanFactoryProcessor dynamicBeanFactoryProcessor() {
return new DynamicBeanFactoryProcessor();
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
((BeanDefinitionRegistry)beanFactory).registerBeanDefinition("myClass",
BeanDefinitionBuilder.genericBeanDefinition(MyClass.class)
.setFactoryMethodOnBean("createInstance", "dynamicBeanFactoryProcessor")
.addConstructorArgValue(MyClass.class)
.getBeanDefinition());
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.