当 spring 和 guice 共同存在一个项目中,且 spring 中需要访问 guice 的注入时,这个方法似乎可以使用。
(1) spring 中配置转换的 factory
<bean id="guiceBeanProvider" class="com.plusrun.util.GuiceBeanProviderFactory"/>
(2)GuiceBeanProviderFactory
package com.plusrun.util; import com.google.inject.AbstractModule; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.name.Names; import javax.servlet.ServletContext; import org.apache.log4j.Logger; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.web.context.WebApplicationContext; public class GuiceBeanProviderFactory<T> extends AbstractModule implements ApplicationContextAware, BeanFactoryAware { private final Logger log = Logger.getLogger(GuiceBeanProviderFactory.class); protected WebApplicationContext applicationContext; protected static BeanFactory beanFactory; private static BeanFactory getBeanFactory() { return beanFactory; } public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { if (!(applicationContext instanceof WebApplicationContext)) { this.log.warn("Application context is not instance of WebApplicationContext unable to provide Guice registersthrough Spring."); } this.applicationContext = ((WebApplicationContext)applicationContext); } public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; } public T get(Class clazz) throws ClassNotFoundException { return (T) injector().getInstance(clazz); } public BeanProvider<T> getNamed(final Class clazz, final String name) { return new BeanProvider() { public Object get() { return GuiceBeanProviderFactory.this.injector().getInstance(Key.get(clazz, Names.named(name))); } }; } protected void configure() { BeanFactory beanFactory = getBeanFactory(); if (beanFactory != null) { bind(BeanFactory.class).toInstance(beanFactory); } else this.log.warn("BeanFactory not initialized Spring -> Guice Integration will not function"); } protected Injector injector() { return (Injector)this.applicationContext.getServletContext().getAttribute("guice-injector"); } }
(3)spring 配置使用
<bean id="iframeUriManager" scope="singleton" factory-bean="guiceBeanProvider" factory-method="get" lazy-init="true"> <constructor-arg type="java.lang.Class" value="org.apache.shindig.gadgets.uri.IframeUriManager"/> </bean>