struts2源码分析(依赖注入)

来源:互联网 发布:gpd pocket 知乎 编辑:程序博客网 时间:2024/04/30 03:33

1、首先Inject(com.opensymphony.xwork2.inject)这个Annotation类

这个类是对Inject的定义,其内容如下:

/** * @Retention(RetentionPolicy.RUNTIME)在这里指定了注解保留的周期;有三个周期 * CLASS:编译器将把注释记录在类文件中,但在运行时 VM 不需要保留注释。 * RUNTIME:编译器将把注释记录在类文件中,在运行时 VM 将保留注释,因此可以反射性地读取。 * SOURCE:编译器要丢弃的注释。 * @Target(ElementType.TYPE)  这个标识注解应该标在那里   ElementType的几个枚举值就代表了  注解应该写在的位置 * CONSTRUCTOR:构造方法声明 * FIELD:字段声明(包括枚举常量) * LOCAL_VARIABLE: 局部变量声明 * METHOD:方法声明 * PACKAGE:包声明 * PARAMETER:参数声明 * TYPE: 类、接口(包括注释类型)或枚举声明 */@Target({METHOD, CONSTRUCTOR, FIELD, PARAMETER})@Retention(RUNTIME)public @interface Inject {  /**   * 依赖的名字. 默认为Struts2的Container中的DEFAULT_NAME(default).   */  String value() default DEFAULT_NAME;  /**   * 是否必须注入.    */  boolean required() default true;}

2、Struts2内部的依赖注入核心参考《Struts2的IoC解析

链接地址为:http://blog.csdn.net/yanlinwang/article/details/8944632

3、以下是对Struts2的个人理解

/** * 默认Container的实现 */@SuppressWarnings("serial")class ContainerImpl implements Container {/** * bean容器 */final Map<Key<?>, InternalFactory<?>> factories;/** * 定义一个类型到名称集合的映射关系,一个类型对应于多个名称  */final Map<Class<?>, Set<String>> factoryNamesByType;/** * 构造方法、在该方法中对factories和factoryNamesByType进行初始化 * @param factories */ContainerImpl( Map<Key<?>, InternalFactory<?>> factories ) {//初始化factoriesthis.factories = factories;//一个类型对应于多个名称,构建一个类型到名称集合的映射关系Map<Class<?>, Set<String>> map = new HashMap<Class<?>, Set<String>>();/** * 对factories进行遍历 */for ( Key<?> key : factories.keySet() ) {Set<String> names = map.get(key.getType());if (names == null) {names = new HashSet<String>();map.put(key.getType(), names);}names.add(key.getName());}/** * 将名称集合固化为不可修改的 */for ( Entry<Class<?>, Set<String>> entry : map.entrySet() ) {entry.setValue(Collections.unmodifiableSet(entry.getValue()));}//将类型到名称集合的映射关系固化为不可修改this.factoryNamesByType = Collections.unmodifiableMap(map);}/** * 根据KEY找到该类型的构造工厂类  * @param <T> * @param key 类型 * @return */@SuppressWarnings("unchecked")<T> InternalFactory<? extends T> getFactory( Key<T> key ) {return (InternalFactory<T>) factories.get(key);}/** * 初始化一个注入器map,用来保存类和其注入器之间的关系 * 该变量是ReferenceCache的一个实例 */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);//在这里对key进行依赖注入return injectors;}};/** * 从给定的类中循环向给定的列表中注入变量和方法。父类在子类之前注入 */void addInjectors( Class clazz, List<Injector> injectors ) {if (clazz == Object.class) {return;}//向父类进行递归,为其父类进行依赖注入,直到遇到Object类为止addInjectors(clazz.getSuperclass(), injectors);// TODO (crazybob): Filter out overridden members./** * 通过该方法,将需要注入的非静态属性放入injectors中 */addInjectorsForFields(clazz.getDeclaredFields(), false, injectors);/** * 通过该方法,将需要注入的非静态方法放入injectors中 */addInjectorsForMethods(clazz.getDeclaredMethods(), false, injectors);}/** * 依赖注入(静态参数、方法) * @param staticInjections */void injectStatics( List<Class<?>> staticInjections ) {final List<Injector> injectors = new ArrayList<Injector>();/** * 对参数staticInjections进行遍历 */for ( Class<?> clazz : staticInjections ) {//class的getDeclaredFields()方法返回此 Class 对象所表示的类或接口所声明的所有字段/** * 通过该方法,将需要注入的静态属性放入injectors中 */addInjectorsForFields(clazz.getDeclaredFields(), true, injectors);//class的getDeclaredMethods()方法返回此 Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。/** * 通过该方法,将需要注入的静态方法放入injectors中 */addInjectorsForMethods(clazz.getDeclaredMethods(), true, injectors);}callInContext(new ContextualCallable<Void>() {/** * 实现该ContextualCallable接口中的call方法 */public Void call( InternalContext context ) {for ( Injector injector : injectors ) {injector.inject(context, null);}return null;}});}/** * 找到对象所定义的全部方法,并且表示成注入器列表方式 * @param methods * @param statics * @param 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);}});}/** * 找到对象所定义的全部字段,并且表示成注入器列表方式  * @param fields 某个类的所有属性 * @param statics false * @param injectors  */void addInjectorsForFields( Field[] fields, boolean statics, List<Injector> injectors ) {//Arrays.asList();返回一个受指定数组支持的固定大小的列表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);}});}/** * 找到有注解@Inject的成员,调用传入的injectorFactory.create方法创建真正的Injector实例 加入到注入器集合中  * @param <M> * @param members 参数或是方法列表 * @param statics  * @param injectors a new Object * @param injectorFactory */<M extends Member & AnnotatedElement> void addInjectorsForMembers(List<M> members, boolean statics, List<Injector> injectors, InjectorFactory<M> injectorFactory ) {//对members对象进行遍历for ( M member : members ) {if (isStatic(member) == statics) {//如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。Inject inject = member.getAnnotation(Inject.class);//这里inject.value()默认为defaultif (inject != null) {try {injectors.add(injectorFactory.create(this, member, inject.value()));//把这个Member放入injectors中} catch ( MissingDependencyException e ) {if (inject.required()) {throw new DependencyException(e);}}}}}}/** * 注入器工厂接口 * @author Administrator * * @param <M> */interface InjectorFactory<M extends Member & AnnotatedElement> {Injector create( ContainerImpl container, M member, String name ) throws MissingDependencyException;}/** * 检查成员是否为静态的 * @param member * @return */private boolean isStatic( Member member ) {//member.getModifiers()返回作为整数返回由此 Member 所表示的成员或构造方法的 Java 语言修饰符//Modifier.isStatic()如果整数参数包括 static 修饰符,则返回 true,否则返回 false。return Modifier.isStatic(member.getModifiers());}/** * 字段属性注入器 * @author Administrator * */static class FieldInjector implements Injector {final Field field;//类加载的时候需要注入的成员final InternalFactory<?> factory;//运行时需要注入的成员final ExternalContext<?> externalContext;/** * 属性注入构造器 * @param container 容器实例 * @param field 字段 * @param name 属性字段名称 * @throws MissingDependencyException */public FieldInjector( ContainerImpl container, Field field, String name )throws MissingDependencyException {this.field = field;//初始化field字段//field.isAccessible获取此对象的 accessible 标志的值。if (!field.isAccessible()) {SecurityManager sm = System.getSecurityManager();try {if (sm != null) {//如果基于当前有效的安全策略,不允许执行根据给定权限所指定的请求访问,则抛出 SecurityException。//反射操作的 Permission 类。ReflectPermission 是一种指定权限,没有动作sm.checkPermission(new ReflectPermission("suppressAccessChecks"));}//设定该字段的accessiblefield.setAccessible(true);} catch ( AccessControlException e ) {throw new DependencyException("Security manager in use, could not access field: "+ field.getDeclaringClass().getName() + "(" + field.getName() + ")", e);}}//创建一个基于field的key的实例Key<?> key = Key.newInstance(field.getType(), name);//从当前的factory中获取该key的工厂类factory = container.getFactory(key);//如果不存在则抛出异常if (factory == null) {throw new MissingDependencyException("No mapping found for dependency " + key + " in " + field + ".");}//实例化一个externalContextthis.externalContext = ExternalContext.newInstance(field, key, container);}/** * 将传入的对象的字段设置值 * @param context 内部上下文 * @param o 传入对象 */public void inject( InternalContext context, Object o ) {ExternalContext<?> previous = context.getExternalContext();context.setExternalContext(externalContext);try {field.set(o, factory.create(context));//对field进行赋值} catch ( IllegalAccessException e ) {throw new AssertionError(e);} finally {context.setExternalContext(previous);}}}/** * 获取参数的injectors * * @param member 参数所属的Member * @param annotations参数上面的Annotation * @param parameterTypes 参数类型 * * @return injections */<M extends AccessibleObject & Member> ParameterInjector<?>[]getParametersInjectors( M member, Annotation[][] annotations, Class[] parameterTypes, String defaultName ) throws MissingDependencyException {List<ParameterInjector<?>> parameterInjectors = new ArrayList<ParameterInjector<?>>();//创建一个新的ParameterInjector集合Iterator<Annotation[]> annotationsIterator = Arrays.asList(annotations).iterator();//把annotations参数转换成Iterator对象/** * 对Iterator对象进行遍历 */for ( Class<?> parameterType : parameterTypes ) {Inject annotation = findInject(annotationsIterator.next());//获取annotations参数中的Inject注解的AnnotationString name = annotation == null ? defaultName : annotation.value();//获取annotation的valueKey<?> key = Key.newInstance(parameterType, name);//将其组装成一个KEYparameterInjectors.add(createParameterInjector(key, member));}return toArray(parameterInjectors);}/** * 根据KEY从factories中获取该key的工厂类 * @param <T> * @param key * @param member * @return * @throws MissingDependencyException */<T> ParameterInjector<T> createParameterInjector( Key<T> key, Member member ) throws MissingDependencyException {InternalFactory<? extends T> factory = getFactory(key);//获取指定key的工厂类/** * 如果此工厂类不存在,则抛出异常 */if (factory == null) {throw new MissingDependencyException("No mapping found for dependency " + key + " in " + member + ".");}ExternalContext<T> externalContext = ExternalContext.newInstance(member, key, this);return new ParameterInjector<T>(externalContext, factory);//返回一个新的ParameterInjector对象}/** * 把parameterInjector的集合转换成一个ParameterInjector的数组 * @param parameterInjections * @return */@SuppressWarnings("unchecked")private ParameterInjector<?>[] toArray(List<ParameterInjector<?>> parameterInjections ) {return parameterInjections.toArray(new ParameterInjector[parameterInjections.size()]);}/** * 获取annotations参数中的Inject注解的Annotation */Inject findInject( Annotation[] annotations ) {for ( Annotation annotation : annotations ) {if (annotation.annotationType() == Inject.class) {return Inject.class.cast(annotation);}}return null;}/** * 方法注入器定义,负责以对象方法方式注入对象  * @author Administrator * */static class MethodInjector implements Injector {/** * 方法 */final Method method;/** * 参数注入器 */final ParameterInjector<?>[] parameterInjectors;/** * 默认构造方法,在该方法中初始化参数 * @param container * @param method * @param name * @throws MissingDependencyException */public MethodInjector( ContainerImpl container, Method method, String name ) throws MissingDependencyException {//初始化methodthis.method = method;/** * 对method进行包装 */if (!method.isAccessible()) {SecurityManager sm = System.getSecurityManager();try {if (sm != null) {sm.checkPermission(new ReflectPermission("suppressAccessChecks"));}method.setAccessible(true);} catch ( AccessControlException e ) {throw new DependencyException("Security manager in use, could not access method: "+ name + "(" + method.getName() + ")", e);}}//按照声明顺序返回 Class 对象的数组,这些对象描述了此 Method 对象所表示的方法的形参类型。Class<?>[] parameterTypes = method.getParameterTypes();//如果此Method的所有的方法的形参类型为0,则抛出异常if (parameterTypes.length == 0) {throw new DependencyException(method + " has no parameters to inject.");}/** * 获取形参的injector,该对象是ParameterInjector类型的数组 */parameterInjectors = container.getParametersInjectors(method, method.getParameterAnnotations(), parameterTypes, name);}/** * 采用反射机制对方法进行注入 */public void inject( InternalContext context, Object o ) {try {/** * 进行方法的依赖注入 */method.invoke(o, getParameters(method, context, parameterInjectors));} catch ( Exception e ) {throw new RuntimeException(e);}}}/** * 构造方法的注入 */Map<Class<?>, ConstructorInjector> constructors = new ReferenceCache<Class<?>, ConstructorInjector>() {@Override@SuppressWarnings("unchecked")protected ConstructorInjector<?> create( Class<?> implementation ) {return new ConstructorInjector(ContainerImpl.this, implementation);}};/** * 构造函数注入器 * @author Administrator * * @param <T> */static class ConstructorInjector<T> {/** * 要处理的类型 */final Class<T> implementation;/** * 需要注入的属性或者方法 */final List<Injector> injectors;/** * 构造器 */final Constructor<T> constructor;/** * 需要注入的参数数组 */final ParameterInjector<?>[] parameterInjectors;/** * 构造方法,在该方法中初始化implementation * @param container * @param implementation */ConstructorInjector( ContainerImpl container, Class<T> implementation ) {//初始化implementationthis.implementation = implementation;constructor = findConstructorIn(implementation);if (!constructor.isAccessible()) {SecurityManager sm = System.getSecurityManager();try {if (sm != null) {sm.checkPermission(new ReflectPermission("suppressAccessChecks"));}constructor.setAccessible(true);} catch ( AccessControlException e ) {throw new DependencyException("Security manager in use, could not access constructor: "+ implementation.getName() + "(" + constructor.getName() + ")", e);}}MissingDependencyException exception = null;Inject inject = null;ParameterInjector<?>[] parameters = null;try {//取得注解方式声明的注入依赖inject = constructor.getAnnotation(Inject.class);parameters = constructParameterInjector(inject, container, constructor);} catch ( MissingDependencyException e ) {exception = e;}parameterInjectors = parameters;if (exception != null) {if (inject != null && inject.required()) {throw new DependencyException(exception);}}injectors = container.injectors.get(implementation);}ParameterInjector<?>[] constructParameterInjector(Inject inject, ContainerImpl container, Constructor<T> constructor ) throws MissingDependencyException {return constructor.getParameterTypes().length == 0? null // default constructor.: container.getParametersInjectors(constructor,constructor.getParameterAnnotations(),constructor.getParameterTypes(),inject.value());}/** * 找到类implementation的构造器 * @param implementation 要处理的类型  * @return */@SuppressWarnings("unchecked")private Constructor<T> findConstructorIn( Class<T> implementation ) {Constructor<T> found = null;Constructor<T>[] declaredConstructors = (Constructor<T>[]) implementation.getDeclaredConstructors();/** * 对获取的构造函数进行遍历,查找出添加了Annotation的构造函数 */for ( Constructor<T> constructor : declaredConstructors ) {if (constructor.getAnnotation(Inject.class) != null) {if (found != null) {throw new DependencyException("More than one constructor annotated" + " with @Inject found in " + implementation + ".");}found = constructor;}}if (found != null) {return found;}// If no annotated constructor is found, look for a no-arg constructor// instead.try {return implementation.getDeclaredConstructor();} catch ( NoSuchMethodException e ) {throw new DependencyException("Could not find a suitable constructor"+ " in " + implementation.getName() + ".");}}/** * Construct an instance. Returns {@code Object} instead of {@code T} because it may return a proxy. */Object construct( InternalContext context, Class<? super T> expectedType ) {ConstructionContext<T> constructionContext =context.getConstructionContext(this);// We have a circular reference between constructors. Return a proxy.if (constructionContext.isConstructing()) {// TODO (crazybob): if we can't proxy this object, can we proxy the// other object?return constructionContext.createProxy(expectedType);}// If we're re-entering this factory while injecting fields or methods,// return the same instance. This prevents infinite loops.T t = constructionContext.getCurrentReference();if (t != null) {return t;}try {// First time through...constructionContext.startConstruction();try {Object[] parameters =getParameters(constructor, context, parameterInjectors);t = constructor.newInstance(parameters);constructionContext.setProxyDelegates(t);} finally {constructionContext.finishConstruction();}// Store reference. If an injector re-enters this factory, they'll// get the same reference.constructionContext.setCurrentReference(t);// Inject fields and methods.for ( Injector injector : injectors ) {injector.inject(context, t);}return t;} catch ( InstantiationException e ) {throw new RuntimeException(e);} catch ( IllegalAccessException e ) {throw new RuntimeException(e);} catch ( InvocationTargetException e ) {throw new RuntimeException(e);} finally {constructionContext.removeCurrentReference();}}}/** * 参数注入器,表示以对象方法方式注入时的一个方法注入形式 * @author Administrator * * @param <T> */static class ParameterInjector<T> {/** * 外部上下文 */final ExternalContext<T> externalContext;/** * 内部工厂 */final InternalFactory<? extends T> factory;public ParameterInjector( ExternalContext<T> externalContext, InternalFactory<? extends T> factory ) {this.externalContext = externalContext;this.factory = factory;}/** * 创建一个需要注入到方法参数的对象 * @param member 方法 * @param context 内部上下文 * @return 构造号的参数对象 */T inject( Member member, InternalContext context ) {ExternalContext<?> previous = context.getExternalContext();context.setExternalContext(externalContext);try {/** * 工厂类生成实例对象 */return factory.create(context);} finally {context.setExternalContext(previous);}}}/** * 取得对象的方法的参数数组 * @param member 方法 * @param context 内部上下文 * @param parameterInjectors 参数的注入器数组 * @return 构造号的方法参数数组 */private static Object[] getParameters( Member member, InternalContext context, ParameterInjector[] parameterInjectors ) {if (parameterInjectors == null) {return null;}Object[] parameters = new Object[parameterInjectors.length];/** * 遍历参数,生成对象 */for ( int i = 0; i < parameters.length; i++ ) {parameters[i] = parameterInjectors[i].inject(member, context);}return parameters;}/** * 给对象注入其依赖的值或者对象 * @param o 需要注入属性或者对象的对象 * @param context 内部上下文 */void inject( Object o, InternalContext context ) {List<Injector> injectors = this.injectors.get(o.getClass());for ( Injector injector : injectors ) {injector.inject(context, o);}}/** * 给对象注入其依赖的值或者对象 * @param <T> * @param implementation * @param context * @return */<T> T inject( Class<T> implementation, InternalContext context ) {try {ConstructorInjector<T> constructor = getConstructor(implementation);return implementation.cast(constructor.construct(context, implementation));} catch ( Exception e ) {throw new RuntimeException(e);}}/** * 依照给定的类型和名称以及内部上下文创建对象的实例 * @param <T> 参数类型 * @param type 类型 * @param name 对象名称 * @param context 内部上下文 * @return */@SuppressWarnings("unchecked")<T> T getInstance( Class<T> type, String name, InternalContext context ) {ExternalContext<?> previous = context.getExternalContext();Key<T> key = Key.newInstance(type, name);context.setExternalContext(ExternalContext.newInstance(null, key, this));try {InternalFactory o = getFactory(key);if (o != null) {return getFactory(key).create(context);} else {return null;}} finally {context.setExternalContext(previous);}}/** * 依照给定的类型和默认名称以及内部上下文创建对象的实例 * @param <T> 参数类型 * @param type 类型 * @param context 内部上下文 * @return */<T> T getInstance( Class<T> type, InternalContext context ) {return getInstance(type, DEFAULT_NAME, context);}/** * 注入依赖到已经存在的对象的字段和方法 */public void inject( final Object o ) {callInContext(new ContextualCallable<Void>() {public Void call( InternalContext context ) {inject(o, context);return null;}});}/** * 创建并且注入一个新的对应类型的实例 */public <T> T inject( final Class<T> implementation ) {return callInContext(new ContextualCallable<T>() {public T call( InternalContext context ) {return inject(implementation, context);}});}/** * 取得类型的实例对象 */public <T> T getInstance( final Class<T> type, final String name ) {return callInContext(new ContextualCallable<T>() {public T call( InternalContext context ) {return getInstance(type, name, context);}});}/** * 根据默认名称来取得类型的实例对象(适用于一个类型创建一个默认对象的情况) */public <T> T getInstance( final Class<T> type ) {return callInContext(new ContextualCallable<T>() {public T call( InternalContext context ) {return getInstance(type, context);}});}/** * 根据类型来取得该类型的实例对象名称集合(适用于同一个类型创建了多个不同名称的对象) */public Set<String> getInstanceNames( final Class<?> type ) {return factoryNamesByType.get(type);}/** * 本地线程上下文,保存内部上下文对象 */ThreadLocal<Object[]> localContext =new ThreadLocal<Object[]>() {@Overrideprotected Object[] initialValue() {return new Object[1];}};/** * 查找Thread Local的上下文。在必要的情况下,创建(或删除)一个上下文 * Looks up thread local context. Creates (and removes) a new context if necessary. */<T> T callInContext( ContextualCallable<T> callable ) {Object[] reference = localContext.get();//从localContext中获取此线程局部变量的当前线程副本中的值。/** * 如果其为空 */if (reference[0] == null) {reference[0] = new InternalContext(this);//创建一个新的InternalContext对象赋值给reference[0]try {/** * 调用callable中的call方法,并返回结果 */return callable.call((InternalContext) reference[0]);} finally {//如果reference[0]是新创建的话,则移除reference[0] = null;//同时情况localContextlocalContext.remove();}} else {//如果reference[0]不为空,则直接进行调用return callable.call((InternalContext) reference[0]);}}/** * 内部定义的接口 * @author Administrator * * @param <T> */interface ContextualCallable<T> {T call( InternalContext context );}/** * 根据给定的实现类来找到构造函数 * Gets a constructor function for a given implementation class. */@SuppressWarnings("unchecked")<T> ConstructorInjector<T> getConstructor( Class<T> implementation ) {return constructors.get(implementation);}/** * 作用域策略本地线程 */final ThreadLocal<Object> localScopeStrategy =new ThreadLocal<Object>();public void setScopeStrategy( Scope.Strategy scopeStrategy ) {this.localScopeStrategy.set(scopeStrategy);}public void removeScopeStrategy() {this.localScopeStrategy.remove();}/** * 定义一个向对象中注入字段或者方法属性接口 */interface Injector extends Serializable {void inject( InternalContext context, Object o );}static class MissingDependencyException extends Exception {MissingDependencyException( String message ) {super(message);}}}


 

原创粉丝点击