`

Struts2依赖注入关联的类

 
阅读更多

 // ContainerImpl  中定义的静态内部类

  

  /**
   * Injects a field or method in a given object.
   */
  interface Injector extends Serializable {
    void inject(InternalContext context, Object o);
  }

  static class MissingDependencyException extends Exception {

     MissingDependencyException(String message) {
       super(message);
     }
  }

   // 一些Injector 的实现类

static class FieldInjector implements Injector {

    final Field field;
    final InternalFactory<?> factory;
    final ExternalContext<?> externalContext;

    public FieldInjector(ContainerImpl container, Field field, String name)
        throws MissingDependencyException {
      this.field = field;
      field.setAccessible(true);// 此处貌似都是有必要的

                           //不使用构造函数是因为 Key类中构造函数定义为private
      Key<?> key = Key.newInstance(field.getType(), name);
      factory = container.getFactory(key);//注意传入ContainerImpl呀!
      if (factory == null) {
        throw new MissingDependencyException(
            "No mapping found for dependency " + key + " in " + field + ".");
      }
                           //不使用构造函数不知道为何了?????
      this.externalContext = ExternalContext.newInstance(field, key, container);
    }

   // 此处是核心关键调用的方法
    public void inject(InternalContext context, Object o) {
      ExternalContext<?> previous = context.getExternalContext();
      context.setExternalContext(externalContext);
      try {
         // 将指定对象变量上(o)此 Field 对象表示的字段设置为指定的新值(param2)。
        field.set(o, factory.create(context));

      } catch (IllegalAccessException e) {
        throw new AssertionError(e);
      } finally {
        // 此处谁能告诉我是干什么的?
        context.setExternalContext(previous);
      }
    }
  }

  //

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;
    }

     //member 反映有关单个成员(字段或方法)或构造方法的标识信息。 
    T inject(Member member, InternalContext context) {
      ExternalContext<?> previous = context.getExternalContext();
      context.setExternalContext(externalContext);
      try {
        return factory.create(context);
      } finally { // 此处又来了 
        context.setExternalContext(previous);
      }
    }
  }

   

static class ConstructorInjector<T> {

    final Class<T> implementation;
    final List<Injector> injectors;
    final Constructor<T> constructor;
    final ParameterInjector<?>[] parameterInjectors;

    ConstructorInjector(ContainerImpl container, Class<T> implementation) {
      this.implementation = implementation;
                          //内部类提供的内部方法
      constructor = findConstructorIn(implementation);
      constructor.setAccessible(true); //也来了

      try {
        Inject inject = constructor.getAnnotation(Inject.class);
        parameterInjectors = inject == null
            ? null // default constructor.
            : container.getParametersInjectors(
                constructor,
                constructor.getParameterAnnotations(),
                constructor.getParameterTypes(),
                inject.value()
              );
      } catch (MissingDependencyException e) {
        throw new DependencyException(e);
      }
      injectors = container.injectors.get(implementation);
    }

    //内部类中提供的方法
    @SuppressWarnings("unchecked")
    private Constructor<T> findConstructorIn(Class<T> implementation) {
      Constructor<T> found = null;
      Constructor<T>[] declaredConstructors = (Constructor<T>[]) implementation.getDeclaredConstructors();
      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();
      }
    }
  }

 // Container接口实现类中需要 重要的变量定义和方法定义

 ThreadLocal<Object[]> localContext = new ThreadLocal<Object[]>() {
          protected InternalContext[] initialValue() {
                return new InternalContext[1];
          }
      };

  /**
   * Looks up thread local context. Creates (and removes) a new context if
   * necessary.
   */
  <T> T callInContext(ContextualCallable<T> callable) {
    InternalContext[] reference = (InternalContext[]) localContext.get();
    if (reference[0] == null) {
      reference[0] = new InternalContext(this);
      try {
         return callable.call(reference[0]);
      } finally {
        // Only remove the context if this call created it.
         reference[0] = null;
      }
    } else {
      // Someone else will clean up this context.
       return callable.call(reference[0]);
    }
  }
  // 注意此处的接口定义
  interface ContextualCallable<T> {
         T call(InternalContext context);
   }

 

 

分享到:
评论

相关推荐

    张龙圣思园struts2学习笔记word

    例如,通过Struts2-Spring-plugin,可以实现Action的依赖注入,增强应用的可测试性和可维护性。 总的来说,张龙圣思园的Struts2学习笔记是全面了解和掌握Struts2框架的宝贵资源,无论你是初学者还是有经验的开发者...

    struts2-spring-plugin-2.2.1.jar

    这个插件的主要目的是简化在基于Struts2的应用程序中整合Spring的功能,如依赖注入(DI)、AOP(面向切面编程)以及事务管理等。下面我们将深入探讨Struts2、Spring框架以及它们之间的集成。 **Struts2框架** ...

    struts2基本类库

    Struts2可以很好地与Spring框架集成,实现依赖注入(DI)和AOP(面向切面编程),提高代码的可测试性和可维护性。 以上就是Struts2基本类库中涉及的关键知识点。学习和理解这些内容,可以帮助开发者有效地利用...

    Struts2 jar包

    1. **Spring集成**:Struts2可以无缝集成Spring,使得Action可以直接从Spring容器获取依赖,实现依赖注入,有利于解耦和测试。 2. **Hibernate集成**:Struts2提供了Hibernate插件,简化了数据访问层的操作,可以...

    struts2 配置JSP时需要的jar

    9. **Action类和结果**:Action类是业务逻辑的载体,它可以是简单的Java类,通过注解或者XML配置与Struts2关联。结果定义了Action执行后跳转的目标,可以是JSP、Freemarker模板或其他结果类型。 10. **Interceptor...

    Struts2入门小程序

    最后,Struts2与Spring框架的集成也是常见的应用场景,可以实现依赖注入,方便管理Action的生命周期。如果这个入门程序包含Spring的集成,那么你还会了解到如何配置Spring和Struts2之间的协作。 总的来说,"Struts2...

    Struts2小demo

    它在原有的Struts1基础上进行了很多改进,引入了更多现代化的开发理念和技术,如依赖注入(DI)、面向切面编程(AOP)以及插件架构等。这个"Struts2小demo"是一个基础的学习资源,旨在帮助开发者开启SSH(Spring、...

    struts2学习心得

    8. **Action的属性注入与调用**:在Struts2中,Action的属性可以通过配置文件进行注入,而Action的调用则依赖于配置的拦截器。拦截器会负责调用Action的execute方法,以及处理请求参数的设置和返回结果的解析。 9. ...

    spring+struts2整合源码

    Spring以其强大的依赖注入(DI)和面向切面编程(AOP)能力,而Struts2则以其优秀的MVC设计模式著称,两者结合可以构建出高效、可维护的Web应用。本文将基于"spring+struts2整合源码"的标题和描述,详细讲解Spring和...

    struts2

    结合Spring框架,可以实现依赖注入,提高代码的可测试性和可维护性。 五、学习资源 本教材《Struts2》将深入讲解上述概念,并通过实例演示如何创建一个简单的Struts2应用,包括Action的编写、配置文件的设置、拦截...

    spring-struts2-maven

    Struts2与Spring集成,可以实现Action类的依赖注入,提高代码的可测试性和可维护性。 **Maven** Maven是一个项目管理和综合工具,主要用于构建、文档生成、报告、依赖管理和项目信息管理。通过POM(Project Object ...

    Struts2 2.3.24开发文档

    关于依赖注入,Struts2可以与Spring框架结合使用,通过Spring管理Action的依赖,实现更高级别的控制反转和依赖注入。这增强了代码的可测试性和模块化。 在安全性方面,Struts2提供了一套安全相关的拦截器,如...

    struts2留言板

    Struts2的核心是Action类,每个Action对应一个特定的用户操作,通过配置Struts2的配置文件(通常为struts.xml),我们可以定义这些操作的映射路径,以及它们与视图之间的关联。 Spring3则是一个全面的企业级应用...

    struts2拆分页面的所用的jar包(7个)

    - **struts2-spring-plugin.jar**(如果使用Spring):整合Spring框架,提供依赖注入功能。 - **struts2-struts1-plugin.jar**(如果需要与Struts1兼容):提供与Struts1的兼容性。 5. **模板引擎**:在"struts2...

    Struts2开发详解

    Struts2可以方便地与Spring、Hibernate等其他框架集成,实现依赖注入、持久化等功能,构建完整的MVC应用。 **9. 异常处理** Struts2提供了一套完善的异常处理机制,允许开发者自定义错误页面和错误处理策略,确保...

    struts2+spring+mybatis+easyui的实现

    **Spring** 是一个全面的Java企业级应用框架,它的核心特性包括依赖注入(DI)和面向切面编程(AOP)。在本项目中,Spring主要负责管理Bean,如数据库连接池、事务管理、DAO和Service等。通过Spring的AOP,我们可以...

    struts2整合hibernate

    Struts2和Hibernate是两种非常重要的Java开源框架,它们分别在Web应用的MVC(Model-View-Controller)架构和...在实际项目中,我们还可以进一步优化,比如引入Spring框架进行依赖注入,提高代码的可维护性和灵活性。

    struts2+spring2+ibatis

    通过这种方式,Struts2负责接收请求并调用Spring管理的业务逻辑组件,Spring则负责依赖注入和事务管理,iBatis则在后台默默地处理数据库交互。这样的架构使得代码更加模块化,降低了耦合度,便于维护和扩展。 总的...

    Struts2整合Spring、JPA

    在整合Spring时,我们通常会利用Spring的Action代理来替代Struts2默认的Action实例化方式,这样可以将Action的创建和依赖注入交给Spring容器来管理。具体实现包括在Struts配置文件中声明Spring插件,并在Spring的...

    Struts2 工作原理 Struts2框架 有图

    ObjectFactory遵循依赖注入(Dependency Injection)原则,确保了对象的生命周期管理和依赖关系的自动装配,使得框架更加轻量级且易于扩展。 ### 三、总结 Struts2框架通过精巧的设计和组件化的实现,提供了高效、...

Global site tag (gtag.js) - Google Analytics