Google Guice 使用总结

Guice 简介

Guice是由Google开发的轻量级的依赖注入的工具。 也许大家都了解Spring的依赖注入,两者的功能基本相同。依赖注入在我们的工程项中最主要的功能就是解耦,并能够管理对象的生命周期。

Guice 基本使用

    /**
     * 基于注解的bind接口
     */
    @ImplementedBy(GuiceService.DefaultGuiceService.class)
    public interface GuiceService {

        public String info();

        class DefaultGuiceService implements GuiceService {

            @Override
            public String info() {
                return "this is a test";
            }
        }
    }

    /**
     *
     * 注入类
     *
    */
    public class Client {

        @Inject
        private GuiceService guiceService; //@ImplementedBy(GuiceService.DefaultGuiceService.class) 注解表明接口和实现的关系

        public void print() {
            System.out.println("client :" + guiceService.info());
        }
    }
    
    /**
     * 调用
     *
     */

    public class Main {
        public static void main(String[] args) {
            Injector injector = Guice.createInjector(new AbstractModule() {
                @Override
                protected void configure() {
//                  bind(GuiceService.class).to(GuiceService.DefaultGuiceService.class); //配置中绑定
                }
            });

            Client client = injector.getInstance(Client.class);

            client.print();
        }
    }

接口与实现类的绑定

  1. bind(A.class).toInstance(new AImpl())

    将A接口绑定到一个对象的实例; 这表明这个接口是单例?

  2. bind(A.class).to(AImpl.class)

    指明接口的实现类

  3. @ImplementedBy

    接口的注解,标记此接口是哪个实现类的接口

  4. Provider

    更灵活的一种绑定方式,比如可以绑定代理类

  5. annotatedWith(AA.class)

    当一个接口有多个实现的时候,使用自定义annotation区分

以上四点都是指明接口和实现类的关系,将两者绑定,在使用的时候,则直接使用接口对象即可。如果一个类不是接口的实现类,则在系统中直接使用即可

Provider

    bind(GuiceService.class).toProvider(new Provider<GuiceService>() {
                    @Override
                    public GuiceService get() {
                        return ProxyFactory.create(GuiceService.class); // 绑定到代理类
                    }
                });

这里Provider就对使用者开放了更多的权限,可以在每次获取对象的时候,做一些额外的事情。这需要在具体使用中,自己发挥想象

Scope

一个对象的作用域有两种方式定义,一种是基于注解,一种是在Module中指定

  1. @Singleton

    单例

  2. 无注解

    每次都会生成新的对象

  3. 自定义Scope

    比如requestScope,SessionScope,将一个对象的生命周期限制在一次请求,或者一个会话之中

  4. in(Scopes.SINGLETON) or in(Class-Annotation)

    Module中指定

  5. 自定义Scope

    /**
     *
     * Scope 的实现
     * 作用: 被VineScope定义的对象,它的生命周期在enter 和 exit之间。 在enter之后,对象被存储在ThreadLocal之中,exit之后则被删除。在两者之间的操作中,都可以获取到这个对象
     *
     */
    public class VineScope implements Scope {
        private static VineScope vineScope = new VineScope();

        public static VineScope getScope() {
            return vineScope;
        }

        private final ThreadLocal<Map<Key<?>, Object>> scopedObjectMapHolder = new ThreadLocal<>();

        private VineScope() {}

        public void enter() {
            checkState(scopedObjectMapHolder.get() == null, "A vine scope block is already in progress");
            scopedObjectMapHolder.set(new HashMap<>());
        }

        public void exit() {
            checkState(scopedObjectMapHolder.get() != null, "No vine scope block in progress");
            scopedObjectMapHolder.remove();
        }

        public <T> void seed(Key<T> key, T value) {
            Map<Key<?>, Object> scopedObjectMap = getScopedObjectMap(key);
            checkState(!scopedObjectMap.containsKey(key), "A value for key [%s] was already seeded in this vine scope, " +
                "old value: [%s], new value: [%s]", key, scopedObjectMap.get(key), value);
            scopedObjectMap.put(key, value);
        }

        public <T> void seed(Class<T> clazz, T value) {
            seed(Key.get(clazz), value);
        }

        @Override
        public <T> Provider<T> scope(final Key<T> key, final Provider<T> unscoped) {
            return () -> {
                Map<Key<?>, Object> scopedObjectMap = getScopedObjectMap(key);

                @SuppressWarnings("unchecked")
                T current = (T) scopedObjectMap.get(key);
                if (current == null && !scopedObjectMap.containsKey(key)) {
                    current = unscoped.get();

                    if (Scopes.isCircularProxy(current)) {
                        return current;
                    }

                    scopedObjectMap.put(key, current);
                }

                return current;
            };
        }

        private <T> Map<Key<?>, Object> getScopedObjectMap(Key<T> key) {
            Map<Key<?>, Object> scopedObjectMap = scopedObjectMapHolder.get();
            if (scopedObjectMap == null) {
                throw new OutOfScopeException("Cannot access " + key
                        + " outside of a vine scoping block");
            }
            return scopedObjectMap;
        }
    }


    /**
     * 将VineScope绑定到一个注解上,在Module中定义
     *
     */

    // Scope
    VineScope scope = VineScope.getScope();
    bindScope(VineScoped.class, scope);
    bind(VineScope.class).toInstance(scope);

转载于:https://my.oschina.net/le284/blog/516296

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值