如何以编程方式将@Bean定义添加到Spring上下文?

时间:2014-12-03 08:11:27

标签: java spring

通常我会使用@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?

3 个答案:

答案 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");  
    }
}