guice与spring交互

起因:
因为二开需要改造源码, 源框架是guice, 转成springboot 相关需要彼此访问对方的bean对象等

1. 访问spring的工具类


import com.google.inject.AbstractModule;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Provider;
import com.google.inject.name.Names;
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.stereotype.Component;
import org.springframework.web.context.WebApplicationContext;

/**
 * guice 访问spring 工具类
 * @param <T>
 */
@Component
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 Provider<T> getNamed(final Class clazz, final String name) {
        return new Provider() {
            public Object get() {
                return GuiceBeanProviderFactory.this.injector().getInstance(Key.get(clazz, Names.named(name)));
            }
        };
    }

    @Override
    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");
    }
}
复制代码

2. 访问guice的配置核心(组要用这个)

@Component
public class ComposeApplicationRunner implements ApplicationRunner {

    @Autowired
    ApiComposeProperties apiComposeProperties;
    private Injector injector;

    {
        Injector bootstrapInjector = Guice.createInjector(new BootstrapModule());
        ModulesProvider modulesProvider = bootstrapInjector.getInstance(ModulesProvider.class);
        injector = Guice.createInjector(modulesProvider.get());
    }

    @Bean
    public Injector injector(){
        return injector;
    }

    @Override
    public void run(ApplicationArguments args) throws Exception {
复制代码

3. spring中注入


import cn.getech.poros.apicompose.service.IComposeService;
import com.google.inject.Injector;
import com.netflix.conductor.service.WorkflowService;
import org.springframework.stereotype.Service;

/**
 * <p>
 *
 * </p>
 *
 * @author guohun.liang@getech.cn
 * @since 2021/5/31 15:55
 */
@Service
public class ComposeServiceImpl implements IComposeService {

    private final WorkflowService workflowService;

    ComposeServiceImpl(Injector injector){
        workflowService = injector.getInstance(WorkflowService.class);
    }

    @Override
    public void getHttpTask() {
        System.out.println("----------");
    }

}
复制代码