首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用Spring IoC在Guava EventBus中自动注册beans

使用Spring IoC在Guava EventBus中自动注册beans
EN

Stack Overflow用户
提问于 2012-12-10 23:48:28
回答 4查看 6K关注 0票数 5

假设我的应用程序中有一个用于语言更改事件的接口(它基于Vaadin):

代码语言:javascript
运行
复制
public interface ILanguageChangeListener{
    @Subscribe onLanguageChange(LanguageChangeEvent event);
}

我有许多用@Component注释的实现此接口的IoC,因此它们在Spring中可用。我还有一个EventBus bean:

代码语言:javascript
运行
复制
<bean id="languageSwitcher" class="com.google.common.eventbus" scope="session" />

现在,在从IoC获得任何bean的实例后,我还必须获得languageSwitcher的一个实例,并在其中注册新创建的bean:

代码语言:javascript
运行
复制
languageSwitcher.register(myNewBean);

以便接收此事件。有没有可能以某种方式告诉IoC,我想在实现languageSwitcher的每个新bean上调用ILanguageChangeListener bean的注册方法?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2012-12-11 03:51:23

好的,使用BeanPostProcessor注册接口的每个bean:

代码语言:javascript
运行
复制
public class EventBusRegisterBeanPostProcessor implements BeanPostProcessor,
        ApplicationContextAware {

    private ApplicationContext context;

    @Autowired
    private EventBus eventBus; // The only event bus i assume...

    public Object postProcessBeforeInitialization(Object bean, String beanName)
            throws BeansException {

        return bean;
    }

    public Object postProcessAfterInitialization(Object bean, String beanName)
            throws BeansException {

        if (bean instanceof ILanguageChangeListener) {
            registerToEventBus(bean);
        }

        return bean;
    }

    private void registerToEventBus(Object bean) {
        this.eventBus.register(bean);
    }

    public void setApplicationContext(ApplicationContext applicationContext)
            throws BeansException {
        this.context = applicationContext;
    }

}

请注意,如果您有许多EventBus bean,则应该使用ApplicationContext.getBean(String)来获取所需的EventBus。

我引用javadoc的话

在FactoryBean的情况下,将为FactoryBean实例和由FactoryBean创建的对象调用此回调(从Spring2.0开始)。后处理器可以通过相应的bean instanceof FactoryBean checks来决定是应用于FactoryBean还是应用于创建的对象,或者两者都应用。

票数 9
EN

Stack Overflow用户

发布于 2016-03-21 03:27:50

与实现标记接口相比,使用类级注释来标记应该注册的bean甚至更好(耦合更少)。以下是修改后的bean后处理器代码:

代码语言:javascript
运行
复制
public class EventBusListenersRegistererBeanPostProcessor implements BeanPostProcessor{

    Logger log = LoggerFactory.getLogger(this.getClass());

    @Inject
    private EventBus bus;

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        if(bean.getClass().isAnnotationPresent(RegisterWithEventBus.class)){
            log.info("Event Bus is registering bean named \"{}\" of class {}.", beanName, bean.getClass().getCanonicalName());
            bus.register(bean);
        }

        return bean;
    }
}

和注释:

代码语言:javascript
运行
复制
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited // important when working with dynamically generated proxies i.e. CGLib
public @interface RegisterWithEventBus {}

请注意,注释接口具有@Inherited元注释。这在使用CGLIB代理的Spring应用程序中是必要的,因为注释不会在对象的实际(动态)类上,而是在父类上。

票数 3
EN

Stack Overflow用户

发布于 2012-12-11 03:25:47

将工厂bean用于事件总线,并注入上下文中所有ILanguageChangeListener bean的列表。

代码语言:javascript
运行
复制
public class EventBusFactoryBean implements FactoryBean<EventBus> {

    @Autowired
    private List<ILanguageChangeListener> languageChangeListeners;

    private EventBus instance;

    @PostConstruct
    public void init() {

        this.instance = new EventBus();

        for (ILanguageChangeListener listener : this.languageChangeListeners) {
            this.instance.register(listener);
        }
    }

    public EventBusFactoryBean() {

    }

    public EventBus getObject() throws Exception {
        return this.instance;
    }

    public Class<?> getObjectType() {
        return EventBus.class;
    }

    public boolean isSingleton() {
        return true;
    }

    public List<ILanguageChangeListener> getLanguageChangeListeners() {
        return languageChangeListeners;
    }

    public void setLanguageChangeListeners(
            List<ILanguageChangeListener> languageChangeListeners) {
        this.languageChangeListeners = languageChangeListeners;
    }

}

然后在Spring bean定义文件中定义Bean或使用@Component对其进行注释

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13804295

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档