![](/img/trans.png)
[英]Use Spring Transactional with guava eventBus subscriber
[英]Register beans automatically in Guava EventBus with Spring IoC
假設我的應用程序中有一個語言更改事件接口(它基於Vaadin):
public interface ILanguageChangeListener{
@Subscribe onLanguageChange(LanguageChangeEvent event);
}
我有很多bean實現了這個用@Component注釋的接口,因此它們可以在Spring IoC中使用。 我還有一個EventBus bean:
<bean id="languageSwitcher" class="com.google.common.eventbus" scope="session" />
現在,在從IoC獲取任何bean的實例之后,我還必須得到一個languageSwitcher的實例,並在其中注冊newely創建的bean:
languageSwitcher.register(myNewBean);
為了接收這個事件。 有可能以某種方式告訴IoC我想在每個實現ILanguageChangeListener的新bean上調用languageSwitcher bean的register方法嗎?
好的,使用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創建的對象(從Spring 2.0開始)調用此回調。 后處理器可以通過相應的Bean instanceof FactoryBean檢查來決定是應用於FactoryBean還是應用於創建的對象。
IMO,它更好(更少耦合),而不是實現標記接口,使用類級別注釋來標記應該注冊的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應用程序中是必需的,因為注釋不會在對象的實際(動態)類上,而是在父類上。
使用工廠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 Definition文件中定義bean或使用@Component
注釋它
一種方法是使用接口InitializingBean並在bean中注入語言切換器。 像這樣的東西:
public class NotVeryUsefulLanguageListener implements ILanguageChangeListener,
InitializingBean {
@Autowired
private EventBus languageSwitcher;
public void afterPropertiesSet() throws Exception {
this.languageSwitcher.register(this);
}
//... getters, setters, etc
}
如果NotVeryUsefulLanguageLisetener
是單例,它只會發生一次......如果是原型然后每次從Spring獲得一個實例
如果您使用的是XML,那么您可以使用以下內容:
<bean id="languageListenerA" init-method="afterPropertiesSet" class="org.company.whatever.NotVeryUsefulLanguageListener">
<!-- stuff -->
</bean>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.