假设我的应用程序中有一个用于语言更改事件的接口(它基于Vaadin):
public interface ILanguageChangeListener{
@Subscribe onLanguageChange(LanguageChangeEvent event);
}
我有许多用@Component注释的实现此接口的IoC,因此它们在Spring中可用。我还有一个EventBus bean:
<bean id="languageSwitcher" class="com.google.common.eventbus" scope="session" />
现在,在从IoC获得任何bean的实例后,我还必须获得languageSwitcher的一个实例,并在其中注册新创建的bean:
languageSwitcher.register(myNewBean);
以便接收此事件。有没有可能以某种方式告诉IoC,我想在实现languageSwitcher的每个新bean上调用ILanguageChangeListener bean的注册方法?
发布于 2012-12-11 03:51:23
好的,使用BeanPostProcessor注册接口的每个bean:
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还是应用于创建的对象,或者两者都应用。
发布于 2016-03-21 03:27:50
与实现标记接口相比,使用类级注释来标记应该注册的bean甚至更好(耦合更少)。以下是修改后的bean后处理器代码:
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;
}
}
和注释:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@Inherited // important when working with dynamically generated proxies i.e. CGLib
public @interface RegisterWithEventBus {}
请注意,注释接口具有@Inherited元注释。这在使用CGLIB代理的Spring应用程序中是必要的,因为注释不会在对象的实际(动态)类上,而是在父类上。
发布于 2012-12-11 03:25:47
将工厂bean用于事件总线,并注入上下文中所有ILanguageChangeListener bean的列表。
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
对其进行注释
https://stackoverflow.com/questions/13804295
复制相似问题