创建注入框架(5)

这一节提供对Qualifier的实现。 这个我思考过比较久,因为这种实现起来要简单方便就不是很容易,这里我提供一种很简陋的办法。 首先创建一个接口,名为ID:

ID.java

public interface ID<Qualifier extends Annotation> {

String name(Qualifier qualifier);

}

然后在Container里面添加一个映射,以及注册方法和提取方法,如下:

Container.java部分代码

private Map<Class<? extends Annotation>,ID> qualifiers;


public Container() {
    mapper = new HashMap<>();
    qualifiers = new HashMap<>();
    registerQualifier(Named.class,new NamedId());
}

@SuppressWarnings("unchecked")
public <T> _binder<T> registerClass(Class<T> inter) {
    Binder<T> binder;
    if (mapper.containsKey(inter)) {
        binder= (Binder<T>) mapper.get(inter);
    }else {
        binder = new Binder<>(inter);
        mapper.put(inter,binder);
    }
    return new _binder<>(binder);
}

public <T extends Annotation> void registerQualifier(Class<T> annotationClass,
                                                     ID<T> id) {
    qualifiers.put(annotationClass,id);
}

@SuppressWarnings("unchecked")
<T extends Annotation> ID<T> findQualifier(Class<T> annotationClass) {
    return qualifiers.get(annotationClass);
}

<T extends Annotation> String getName(Class<T> annotationClass,T annotation) {
    if (qualifiers.containsKey(annotationClass))
        return findQualifier(annotationClass).name(annotation);
    return Binder.DEFAULT_BIND_NAME;
}

最后给_binder添加一个withAnnotate方法,如下

@SuppressWarnings("unchecked")
    public _binder<T> withAnnotate(Annotation annotate) {
        Class annotationType = annotate.annotationType();
        if (annotationType.isAnnotationPresent(Qualifier.class)) {
            setName(Container.this.getName(annotationType,annotate));
        }
        return this;
    }

当然instanceOf方法就需要改变一下:

public <K extends T> _binder<T> instanceOf(Class<K> impl) {
        for (Annotation annotation:impl.getAnnotations()) {
            withAnnotate(annotation);
        }
        if (impl.isAnnotationPresent(Singleton.class)) {
            this.singleton(true);
        }
        return providedBy(new ParseClass<>(binder.gettClass(),impl,Container.this));
}

然后ParseClass的GetValue方法:

@SuppressWarnings("unchecked")
private Object getValue(AnnotatedElement accessibleObject,Class tClass) {
    for (Annotation annotation:accessibleObject.getAnnotations()){
        Class annotationType = annotation.annotationType();
        if (annotationType.isAnnotationPresent(Qualifier.class)) {
            String name = container.getName(annotationType,annotation);
            return container.getImplByName(tClass,name);
        }
    }
    return container.getImpl(tClass);
}

我提供了一个NamedId

NamedId.java:

public class NamedId implements ID<Named> {
    @Override
    public String name(Named named) {
        return "NAMED_"+named.value();
    }
}

对_binder的named的方法修改下:

public _binder<T> named(final String name) {
        withAnnotate(new Named(){

            @Override
            public Class<? extends Annotation> annotationType() {
                return Named.class;
            }

            @Override
            public String value() {
                return name;
            }
        });
        return this;
}

测试能够使用,不过对于自定义的Qualifier,需要先在container注册。

注解框架的创建就到这,后期我可能再进行完善,但估计是不会去完善,我是个懒人,除非很有必要,我估计不会去做了。如果大家对spring用的烦了,推荐一个注解框架,谷歌的guice,它做的真的很不错,我也是看到了它才想着写这个伪教程。这个项目我提交到了github上,大家有兴趣可以下载下来,不过基本代码文章都写了 项目地址:https://github.com/liuguobing634/zhuru

这些文章也同步到了我自己的公众号平台:互联网科技杂谈

转载于:https://my.oschina.net/mylgb634335272/blog/777583

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值