本文是<<struts2 技术内幕>>的学习笔记

在进行面向对象编程的时候,我们不可避免地要使用继承实现等等java提供的语法支持。但是复杂的对象关系也为对象生命周期的管理带来了至少以下两个问题。

1 程序运行时,应如何双肩我们所需要的对象。

2 当创建一个对象后,如何保证与其相关联的依赖关系也正确的被创建处理。

好在先辈们已经给我们想好了出路------在程序中引入一个额外的编程元素:容器(Container)

对象的生命管理周期

首先我们得引入一个概念-----控制反转(Inverse of Control)

什么是控制反转?从字面上来说大概就是

本来应该由我控制的事情,不再需要我来控制了。至于交给谁来控制,我不需要知道。

举个例子。

public class Person{
    private Car car;

    public Person(Car c){
    this.car=c;
    }
    public void drive(){
    car.drive();
    }
}

上面的例子很简单吧,一个人能开车。对于车的产生,需要person自己来创造。

那什么是ioc呢?

public class Person{
    private Car car;

    public Person(){
    //其他代码
    }
    public void setCar(Car c){
    this.car=c;
    }
    public void drive(){
    car.drive();
    }
}

就这么简单

本来需要person控制的车的创建,现在不由person来控制了。就是控制反转。

XWork容器的定义

刚才一直再说容器,现在我们就说说strtus2中的容器。

public interface Container extends Serializable {

  /**
   * Default dependency name.
   */
  String DEFAULT_NAME = "default";

  /**
   * 创建类的实例,并进行注入 在上面说的person与car的例子中
   * injcet的参数就应该是person
   * object内部声明有@inject的字段和方法都将被注
   * 入容器所托管的对象(例如上面说的car)
   */
  void inject(Object o);

  <T> T inject(Class<T> implementation);

  /**
   * 根据type与name获得容器中的java类实例
   */
  <T> T getInstance(Class<T> type, String name);

  /**
   * 根据type和默认的name(default)获得容器中的java类实例
   */
  <T> T getInstance(Class<T> type);

  /**
   * 根据type获得所有注册这个type的name
   */
  Set<String> getInstanceNames(Class<?> type);

  /**
   * Sets the scope strategy for the current thread.
   */
  void setScopeStrategy(Scope.Strategy scopeStrategy);

  /**
   * Removes the scope strategy for the current thread.
   */
  void removeScopeStrategy();
}

接口中的方法可以分为三类

获取对象实例 getInstance,getInstacneNames

处理对象依赖关系 inject

处理对象的作用范围策略 setScopeStrategy,removeScopeStrategy

并且,容器是一个辅助的编程元素,它在系统中被设计为一个全局的单例的对象。

XWork容器的管辖范围

刚才我们已经初步认识了XWork容器,现在我们看看:XWork到底能管理哪些东西。

1 获取对象实例

  getInstance可以获得被容器托管的对象。那么到底哪些对象是容器所托管的呢?

  看struts-default.xml里面有三类元素,是容器所托管的

  1在bean节点中声明的框架内部的对象

  2在bean节点中声明的自定义对象

  3在constant节点中声明的系统运行参数

  另外还有

  在Properties文件里什么歌的系统运行参数

  再换句话说,想把自定义的对象纳入容器的管理范围,只需在Sturs/XWork的配置文件里声明即可。

2 对象的依赖注入

  就像我们上面说的people与car的关系,people里面需要一个car,而car是通过容器所管理的,那么对people的注入就是container.inject(people)。

  inject方法的参数都可以使什么呢?

  调用XWork容器的inject方法,能够帮助我们将容器所管理的对象(包括框架的内部元素及系统运行参数)注入到任意的对象实例中。从而建立起任意对象与框架元素沟通的桥梁。

  那么系统怎么知道people这个对象里面就需要一个car呢?

 

public class Person{
    @Inject
    private Car car;

    public Person(){
    //其他代码
    }
    @Inject
    public void setCar(Car c){
    this.car=c;
    }
    public void drive(){
    car.drive();
    }
}

在person里面的car参数或者setCar方法上加上 @Inject标签

我们看看Inject标签的定义

@Target({METHOD, CONSTRUCTOR, FIELD, PARAMETER})
@Retention(RUNTIME)
public @interface Inject {

  /**
   * Dependency name. Defaults to {@link Container。DEFAULT_NAME}.
   */
  String value() default DEFAULT_NAME;

  /**
   * Whether or not injection is required. Applicable only to methods and
   * fields (not constructors or parameters).
   */
  boolean required() default true;
}

关于Annotation的使用参见

http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html

通过容器接口进行对象操作

1  getInstance

public class DefaultUnknownHandlerManager implements UnknownHandlerManager {
    protected ArrayList<UnknownHandler> unknownHandlers;
    private Configuration configuration;
    private Container container;

    @Inject
    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
        build();
    }

    @Inject
    public void setContainer(Container container) {
        this.container = container;
        build();
    }

    /**
     * Builds a list of UnknowHandlers in the order specified by the configured "unknown-handler-stack".
     * If "unknown-handler-stack" was not configured, all UnknowHandlers will be returned, in no specific order
     */
    protected void build() {
        if (configuration != null && container != null) {
            List<UnknownHandlerConfig> unkownHandlerStack = configuration.getUnknownHandlerStack();
            unknownHandlers = new ArrayList<UnknownHandler>();

            if (unkownHandlerStack != null && !unkownHandlerStack.isEmpty()) {
                //get UnknownHandlers in the specified order
        // 根据一定顺序获取UnknownHandler实例
                for (UnknownHandlerConfig unknownHandlerConfig : unkownHandlerStack) {
            //通过容器的getInstance方法获得容器内部脱光光的type为UnknownHandler.class
            //name为传入的参数的UnknownHandler
                    UnknownHandler uh = container.getInstance(UnknownHandler.class, unknownHandlerConfig.getName());
                    unknownHandlers.add(uh);
                }
            } else {
                //add all available UnknownHandlers
                Set<String> unknowHandlerNames = container.getInstanceNames(UnknownHandler.class);
                for (String unknowHandlerName : unknowHandlerNames) {
                    UnknownHandler uh = container.getInstance(UnknownHandler.class, unknowHandlerName);
                    unknownHandlers.add(uh);
                }
            }
        }
    }
    .....
}

当然build方法的调用一定是在setContainer与setConfiguration调用之后。



2 inject

public class ActionSupport implements Action, Validateable, ValidationAware, TextProvider, LocaleProvider, Serializable {

    private TextProvider getTextProvider() {
        if (textProvider == null) {
            TextProviderFactory tpf = new TextProviderFactory();
            if (container != null) {
                container.inject(tpf);
            }
            textProvider = tpf.createInstance(getClass(), this);
        }
        return textProvider;
    }

    @Inject
    public void setContainer(Container container) {
        this.container = container;
    }
}

我们在下面可以看到container.inject(tpf)的参数,也就是TextProviderFactory里面有一个 @Inject标签。

当然getTextProvider之前得先调用setContainer。

public class TextProviderFactory {

    private TextProvider textProvider;

    @Inject
    public void setTextProvider(TextProvider textProvider) {
        this.textProvider = textProvider;
    }
    .....
}

感谢glt

参考资料

http://www.cnblogs.com/peida/archive/2013/04/24/3036689.html

Struts2(XWork)中的Container 一的更多相关文章

  1. struts2.0中struts.xml配置文件详解

    先来展示一个配置文件 <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration ...

  2. Struts2/XWork 安全漏洞及解决办法

    exploit-db网站在7月14日爆出了一个Struts2的远程执行任意代码的漏洞. 漏洞名称:Struts2/XWork < 2.2.0 Remote Command Execution V ...

  3. ueditor1.3.6jsp版在struts2应用中上传图片报"未找到上传文件"解决方案

    摘要: ueditor1.3.6jsp版在struts2应用中上传图片报"未找到上传文件"解决方案 在struts2应用中使用ueditor富文本编辑器上传图片或者附件时,即使配置 ...

  4. 请求在Struts2框架中的处理步骤

    上图来源于Struts2官方站点,是Struts 2 的整体结构. 一个请求在Struts2框架中的处理大概分为以下几个步骤 1 客户端初始化一个指向Servlet容器(例如Tomcat)的请求 2 ...

  5. struts2配置文件中action的name属性

    struts2配置文件中action的name属性的第一个字符不要加斜杠 <action name="see" class="baoxiuManage_seeAct ...

  6. Struts2项目中使用Ajax报错

    在Struts2项目中使用Ajax向后台请求数据,当添加了json-lib-2.3-jdk15.jar和struts2-json-plugin-2.3.4.1.jar两个包时,在result中配置ty ...

  7. bootstrap中的.container类定义

    bootstrap中的.container类定义 .container{ padding-right:15px; padding-left:15px; margin-right:auto; margi ...

  8. Struts2框架中使用Servlet的API示例

    1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的 ...

  9. 在Struts2框架中使用Servlet的API

    1. 在Action类中也可以获取到Servlet一些常用的API * 需求:提供JSP的表单页面的数据,在Action中使用Servlet的API接收到,然后保存到三个域对象中,最后再显示到JSP的 ...

随机推荐

  1. Spring常用配置(二)

    OK,上篇博客我们介绍了Spring中一些常见的配置,上篇博客中介绍到的都是非常常见的注解,但是在Spring框架中,常见的注解除了上篇博客提到的之外,还有许多其他的注解,只不过这些注解相对于上文提到 ...

  2. Apache shiro集群实现 (八) web集群时session同步的3种方法

    Apache shiro集群实现 (一) shiro入门介绍 Apache shiro集群实现 (二) shiro 的INI配置 Apache shiro集群实现 (三)shiro身份认证(Shiro ...

  3. springMVC源码分析--HandlerInterceptor拦截器调用过程(二)

    在上一篇博客springMVC源码分析--HandlerInterceptor拦截器(一)中我们介绍了HandlerInterceptor拦截器相关的内容,了解到了HandlerInterceptor ...

  4. 19 Handler 子线程向主线程发送信息

    案例一 Message创建三种方法: package com.example.day19_handler_demo1; import android.os.Bundle; import android ...

  5. 由源代码编译SpriteBuilder最新版本1.5.0搭配最新的Cocos2D 3.4.9

    大熊猫猪·侯佩原创或翻译作品.欢迎转载,转载请注明出处. 如果觉得写的不好请多提意见,如果觉得不错请多多支持点赞.谢谢! hopy ;) 大家知道SpriteBuilder版本停留在1.4.9已经很久 ...

  6. ExpandableListView简单应用及listview模拟ExpandableListView

    首先我们还是来看一些案例,还是拿搜狐新闻客户端,因为我天天上下班没事爱看这个东东,上班又没时间看新闻,上下班路途之余浏览下新闻打发时间嘛.           看这个效果挺棒吧,其实实现起来也不难,我 ...

  7. Dynamics CRM 2015Online Update1 new feature之 插件跟踪日志

     在最新的CRM2015Online Update1版本中加入了一个新功能-插件跟踪日志,与其说是新功能更应该说是对原有功能的加强,因为ITracingService这个接口在2013中已经引入了, ...

  8. MTK机器原始OTA更新方法

    在源码中编译完成后会生成各类.img的文件,这时候make otapackage生成ota包 一般ota包在源码工程的out/target/...目录下 一.通过线刷模式 将生成OTA包拷贝到Wind ...

  9. 匿名内部类使用外面的类为什么要用final型

    从程序设计语言的理论上:局部内部类(即:定义在方法中的内部类),由于本身就是在方法内部(可出现在形式参数定义处或者方法体处),因而访问方法中的局部变量(形式参数或局部变量)是天经地义的.是很自然的 为 ...

  10. 《C语言点滴》书评

    说起C语言方面的书,你最先想到的是哪一本?不论图书本身是好是坏,反正我想到的是谭浩强的<C程序设计>--它已然是一部"圣经"了.那么,为什么赵岩老师还要写一本<C ...