本文主要是介绍【Struts2源码】@Inject查找并缓存注入器,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
注解@Inject的操作类是ContainerImpl,@Inject在Struts中用到了很多,主要用来构造函数、属性、方法及方法参数注入,当调用ContainerImpl的Inject方法时,这些部分就启动,ContainerImpl初始化时,缓存这些构建方法
这里我们只分析查找这些带@Inject的注入器,并把它们缓存起来。
1.初始化一个注入器Map,用来放置找到@Inject后实例化的注入器,这里使用ReferenceCache缓存类,在运行期构建map,核心方法create会调用addInjectors方法扫描所有注入器加入到ReferenceCache缓存Map里面,并且内部实现ThreadLocal模式规避多线程问题,
/*** Field and method injectors.*/final Map<Class<?>, List<Injector>> injectors =new ReferenceCache<Class<?>, List<Injector>>() {@Overrideprotected List<Injector> create( Class<?> key ) {List<Injector> injectors = new ArrayList<Injector>();addInjectors(key, injectors);return injectors;}};
2.addInjectors()方法
void addInjectors( Class clazz, List<Injector> injectors ) {if (clazz == Object.class) {return;}// Add injectors for superclass first.addInjectors(clazz.getSuperclass(), injectors);// TODO (crazybob): Filter out overridden members.addInjectorsForFields(clazz.getDeclaredFields(), false, injectors);addInjectorsForMethods(clazz.getDeclaredMethods(), false, injectors);}
void addInjectorsForMethods( Method[] methods, boolean statics,List<Injector> injectors ) {addInjectorsForMembers(Arrays.asList(methods), statics, injectors,new InjectorFactory<Method>() {public Injector create( ContainerImpl container, Method method,String name ) throws MissingDependencyException {return new MethodInjector(container, method, name);}});}void addInjectorsForFields( Field[] fields, boolean statics,List<Injector> injectors ) {addInjectorsForMembers(Arrays.asList(fields), statics, injectors,new InjectorFactory<Field>() {public Injector create( ContainerImpl container, Field field,String name ) throws MissingDependencyException {return new FieldInjector(container, field, name);}});}
3.
找到有注解@Inject的成员,调用传入的injectorFactory.create方法创建真正的Injector实例 加入到注入器集合中
<M extends Member & AnnotatedElement> void addInjectorsForMembers(List<M> members, boolean statics, List<Injector> injectors,InjectorFactory<M> injectorFactory ) {for ( M member : members ) {if (isStatic(member) == statics) {Inject inject = member.getAnnotation(Inject.class);if (inject != null) {try {injectors.add(injectorFactory.create(this, member, inject.value()));} catch ( MissingDependencyException e ) {if (inject.required()) {throw new DependencyException(e);}}}}}}
这样就可以无差别的在构造函数、属性、方法及方法参数处使用@Inject注解了
这篇关于【Struts2源码】@Inject查找并缓存注入器的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!