通常我会使用@Bean
定义将我的对象添加到spring上下文:
@Autowired
private SpringBus bus;
//register a singleton
@Bean
public WebservicePort getPort() {
//new port()
//initialize
//configure
//return port;
}
但是现在我需要更深入地控制进程,特别是我想动态地创建bean的名称,以便注册bean。
我试过了:
@Service
public class MyPortRegistrar implements BeanDefinitionRegistryPostProcessor {
@Autowired
private SpringBus bus;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println(bus); //prints null
//create and configure port with the SpringBus
Port port = new WebservicePort(bus); // -> throws NullPointerException
beanFactory.autowireBean(port);
beanFactory.initializeBean(port, "myDynamicPortName");
}
}
但是这会抛出一个NPE,因为这里还没有初始化自动连接的家属!
那么,我如何以编程方式添加这些bean?
答案 0 :(得分:4)
你应该把它放在:
之前beanFactory.autowireBean(port);
但是,如果你想初始化一个bean,我认为你想要创建一个单独的实例(我在说这个,因为在这个例子中,你使用了@Bean
注释):
beanFactory.initializeBean(port, "myDynamicPortName");
而不是单身人士:
beanFactory.registerSingleton("myDynamicPortName", port);
答案 1 :(得分:1)
您应该自动装配bean工厂,并使用@PostConstruct
注册您的bean。这样,您可以保证已注入所有依赖项(bean工厂由容器注入,不需要进行任何设置)。
@Service
public class MyPortRegistrar {
@Autowired
private ConfigurableBeanFactory beanFactory;
@Autowired
private SpringBus bus;
@PostConstruct
public void createPort() {
Port port = new WebservicePort(bus);
beanFactory.registerSingleton("myDynamicPortName", port);
}
}
答案 2 :(得分:1)
Khalid的答案(我认为需要一些额外的依赖关系和配置)的替代方法是实现InitializingBean接口:
@Service
public class MyPortRegistrar implements InitializingBean {
@Autowired
private SpringBus bus;
@Autowired
private ConfigurableBeanFactory beanFactory;
@Override
public void afterPropertiesSet() throws Exception
System.out.println(bus); //prints null
//create and configure port with the SpringBus
Port port = new WebservicePort(bus); // -> throws NullPointerException
beanFactory.autowireBean(port);
beanFactory.initializeBean(port, "myDynamicPortName");
}
}