这一节提供对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
这些文章也同步到了我自己的公众号平台:互联网科技杂谈