`
zddava
  • 浏览: 240402 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

Struts2的配置文件读取(一)

阅读更多
struts2利用FilterDispatcher来拦截请求,然后进行请求的分发,在FilterDispatcher的#init()方法里,实现了配置文件的读入。

代码如下:

    public void init(FilterConfig filterConfig) throws ServletException {
        this.filterConfig = filterConfig;
        
        dispatcher = createDispatcher(filterConfig);
        dispatcher.init();
        
        String param = filterConfig.getInitParameter("packages");
        String packages = "org.apache.struts2.static template org.apache.struts2.interceptor.debugging";
        if (param != null) {
            packages = param + " " + packages;
        }
        this.pathPrefixes = parse(packages);
    }


-------------------------------------------------------------------------------------------------

先调用#createDispatcher()来创建一个Dispatcher对象,并将FilterConfig中的属性读出,代码如下:

    protected Dispatcher createDispatcher(FilterConfig filterConfig) {
        Map params = new HashMap();
        for (Enumeration e = filterConfig.getInitParameterNames(); e.hasMoreElements(); ) {
            String name = (String) e.nextElement();
            String value = filterConfig.getInitParameter(name);
            params.put(name, value);
        }
        return new Dispatcher(filterConfig.getServletContext(), params);
    }


在#createDispatcher()中,将Filter的配置中的所有属性都写入一个HashMap并作为参数传递给Dispatcher的构造函数。

-------------------------------------------------------------------------------------------------

再回到#init()函数中,创建完Dispatcher对象后,紧接着调用Dispatcher的#init()方法。代码如下:

    public void init() {

        if (configurationManager == null) {
            configurationManager = new ConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
        }

        init_DefaultProperties(); // [1]
        init_TraditionalXmlConfigurations(); // [2]
        init_LegacyStrutsProperties(); // [3]
        init_ZeroConfiguration(); // [4]
        init_CustomConfigurationProviders(); // [5]
        init_MethodConfigurationProvider();
        init_FilterInitParameters(); // [6]
        init_AliasStandardObjects(); // [7]

        Container container = init_PreloadConfiguration();
        init_CheckConfigurationReloading(container);
        init_CheckWebLogicWorkaround(container);

    }


首先实例化一个ConfigurationManager对象。

然后就是调用一系列的#init_*()方法了。

-------------------------------------------------------------------------------------------------

●第一个是

    private void init_DefaultProperties() {
        configurationManager.addConfigurationProvider(new DefaultPropertiesProvider());
    }


这个方法中是将一个DefaultPropertiesProvider对象追加到ConfigurationManager对象内部的ConfigurationProvider队列中。
DefaultPropertiesProvider的#register()方法可以载入org/apache/struts2/default.properties中定义的属性。

-------------------------------------------------------------------------------------------------

●第二个是

    private void init_TraditionalXmlConfigurations() {
        String configPaths = initParams.get("config");
        if (configPaths == null) {
            configPaths = DEFAULT_CONFIGURATION_PATHS;
        }
        String[] files = configPaths.split("[url=file://\\s*[,]\\s]\\s*[,]\\s[/url]*");
        for (String file : files) {
            if (file.endsWith(".xml")) {
                if ("xwork.xml".equals(file)) {
                    configurationManager.addConfigurationProvider(new XmlConfigurationProvider(
                            file, false));
                } else {
                    configurationManager
                            .addConfigurationProvider(new StrutsXmlConfigurationProvider(file,
                                    false, servletContext));
                }
            } else {
                throw new IllegalArgumentException("Invalid configuration file name");
            }
        }
    }


这里负责载入的是FilterDispatcher的配置中所定义的config属性。
如果用户没有定义config属性,struts默认会载入DEFAULT_CONFIGURATION_PATHS这个值所代表的xml文件。
它的值为"struts-default.xml,struts-plugin.xml,struts.xml"。也就是说框架默认会载入这三个项目xml文件。

下一步框架会逐个判断每个config属性中定义的文件。如果文件名为"xwork.xml",框架会用XmlConfigurationProvider类去处理,反之则用StrutsXmlConfigurationProvider类去处理。

-------------------------------------------------------------------------------------------------

●第三个是

    private void init_LegacyStrutsProperties() {
        configurationManager.addConfigurationProvider(new LegacyPropertiesConfigurationProvider());
    }


向ConfigurationManager加入了一个LegacyPropertiesConfigurationProvider。

-------------------------------------------------------------------------------------------------

●第四个是

    private void init_ZeroConfiguration() {
        String packages = initParams.get("actionPackages");
        if (packages != null) {
            String[] names = packages.split("[url=file://\\s*[,]\\s]\\s*[,]\\s[/url]*");
            // Initialize the classloader scanner with the configured packages
            if (names.length > 0) {
                ClasspathConfigurationProvider provider = new ClasspathConfigurationProvider(names);
                provider.setPageLocator(new ServletContextPageLocator(servletContext));
                configurationManager.addConfigurationProvider(provider);
            }
        }
    }


这次处理的是FilterDispatcher的配置中所定义的actionPackages属性。传说中的Struts 2 零配置。
该参数的值是一个以英文逗号(,)隔开的字符串,每个字符串都是一个包空间,Struts 2框架将扫描这些包空间下的Action类。

-------------------------------------------------------------------------------------------------

●第五个是

    private void init_CustomConfigurationProviders() {
        String configProvs = initParams.get("configProviders");
        if (configProvs != null) {
            String[] classes = configProvs.split("[url=file://\\s*[,]\\s]\\s*[,]\\s[/url]*");
            for (String cname : classes) {
                try {
                    Class cls = ClassLoaderUtils.loadClass(cname, this.getClass());
                    ConfigurationProvider prov = (ConfigurationProvider) cls.newInstance();
                    configurationManager.addConfigurationProvider(prov);
                } catch (InstantiationException e) {
                    throw new ConfigurationException("Unable to instantiate provider: " + cname, e);
                } catch (IllegalAccessException e) {
                    throw new ConfigurationException("Unable to access provider: " + cname, e);
                } catch (ClassNotFoundException e) {
                    throw new ConfigurationException("Unable to locate provider class: " + cname, e);
                }
            }
        }
    }


此方法处理的是FilterDispatcher的配置中所定义的configProviders属性。负责载入用户自定义的ConfigurationProvider。

-------------------------------------------------------------------------------------------------

●第六个是

    private void init_FilterInitParameters() {
        configurationManager.addConfigurationProvider(new ConfigurationProvider() {
            public void destroy() {
            }

            public void init(Configuration configuration) throws ConfigurationException {
            }

            public void loadPackages() throws ConfigurationException {
            }

            public boolean needsReload() {
                return false;
            }

            public void register(ContainerBuilder builder, LocatableProperties props)
                    throws ConfigurationException {
                props.putAll(initParams);
            }
        });
    }


此方法用来处理FilterDispatcher的配置中所定义的所有属性。

-------------------------------------------------------------------------------------------------

●第七个是

	private void init_AliasStandardObjects() {
		configurationManager.addConfigurationProvider(new BeanSelectionProvider());
	}


-------------------------------------------------------------------------------------------------

执行完七个init_*方法后,Dispatcher的#init()会接着调用#init_PreloadConfiguration(),构建一个用于依赖注射的Container对象。

    private Container init_PreloadConfiguration() {
        Configuration config = configurationManager.getConfiguration();
        Container container = config.getContainer();

        boolean reloadi18n = Boolean.valueOf(container.getInstance(String.class,
                StrutsConstants.STRUTS_I18N_RELOAD));
        LocalizedTextUtil.setReloadBundles(reloadi18n);

        ObjectTypeDeterminer objectTypeDeterminer = container
                .getInstance(ObjectTypeDeterminer.class);
        ObjectTypeDeterminerFactory.setInstance(objectTypeDeterminer);

        return container;
    }


此方法首先获取到ConfigurationManager中的Configuration对象,在#getConfiguration()内部,调用上边6步添加到ConfigurationManager的ConfigurationProviders的#register()方法。

    public synchronized Configuration getConfiguration() {
        if (configuration == null) {
            setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
            try {
              configuration.reload(getConfigurationProviders());
            } catch (ConfigurationException e) {
              setConfiguration(null);
              throw e;
            }
        } else {
            conditionalReload();
        }

        return configuration;
    }


其中的重点就是DefaultConfiguration的#reload()方法。

    public synchronized void reload(List providers) throws ConfigurationException {
        packageContexts.clear();
        loadedFileNames.clear();

        ContainerProperties props = new ContainerProperties();
        ContainerBuilder builder = new ContainerBuilder();
        for (ConfigurationProvider configurationProvider : providers)
        {
            configurationProvider.init(this);
            configurationProvider.register(builder, props);
        }
        props.setConstants(builder);
        
        builder.factory(Configuration.class, new Factory() {
            public Configuration create(Context context) throws Exception {
              return DefaultConfiguration.this;
            }
        });
        
        try {
            // Set the object factory for the purposes of factory creation
            ObjectFactory.setObjectFactory(new ObjectFactory());
            
            container = builder.create(false);
            objectFactory = container.getInstance(ObjectFactory.class);
            ObjectFactory.setObjectFactory(objectFactory);
            
            for (ConfigurationProvider configurationProvider : providers)
            {
              container.inject(configurationProvider);
              configurationProvider.loadPackages();
            }
    
            rebuildRuntimeConfiguration();
        } finally {
            ObjectFactory.setObjectFactory(null);
        }
    }
分享到:
评论

相关推荐

    struts2配置文件传值中文乱码

    struts2配置文件传值中文乱码

    struts2实现多文件上传下载

    2.能够对上传路径进行配置文件指定(upload.properties),使用了一些类似单例模式的静态代码块 3.Struts2进行下载处理,能对上传的所有文件进行下载(多个) 4.文件保存的名称UUID生成,不过显示并下载的名称都是原...

    struts2 properties配置详解

    自己学会的,保存的学习网页,给大家分享 struts2 国际化

    利用Java的Properties 类读取配置文件信息

    利用Java的Properties 类读取配置文件信息! 读取Properties文件的例子

    读取src下的文件及自己包下的配置文件

    将此项目生成一个jar 就可以动态的读取src及文件包下的配置文件了。类似于strust2中的读取default.properties文件,然后,如果,我们的项目中引入了struts.properties文件了,就以struts.properties为主。

    Struts配置详解.doc

    Struts配置文件详解 web.xml、struts-cofig.xml以及struts-cofig.xml中各个标签的作用。 Struts应用采用两个基于XML的配置文件来配置,分别是web.xml和struts-cofig.xml文件.web.xml文件是配置所有web应用的,而...

    Dom4j解析struts2框架的struts.xml

    Dom4j解析struts2框架的struts.xml,自定义struts框架需要解析配置文件

    02_张孝祥09年Struts视频_文件上传单元

    struts文件上传单元目录列表: 01.文件上传的网页设置与数据格式分析 02.阐释软件分层的设计思想 03.文件上传组件的实现原理与应用分析 04.用struts获取上传文件名和解决...15.修正从配置文件中读取文件存储目录的缺陷

    11_张孝祥09年Struts视频_文件上传单元

    struts文件上传单元目录列表: 01.文件上传的网页设置与数据格式分析 02.阐释软件分层的设计思想 03.文件上传组件的实现原理与应用分析 04.用struts获取上传文件名和解决...15.修正从配置文件中读取文件存储目录的缺陷

    深入浅出Struts2(附源码)

    2.5.1 部署描述文件和Struts配置文件 27 2.5.2 动作类 28 2.5.3 运行app02a程序 29 2.6 依赖注入 29 2.6.1 概述 29 2.6.2 依赖注入的几种方式 31 2.7 小结 31 第3章动作与结果 32 3.1 动作类 32 3.2 如何...

    Struts2简单的购物车

    eclipse开发工程包 基于Struts2的简单购物车 非常简单一共只有4个跳转页面 JDBC访问MySQL数据库存储读取数据 需要配置一下dao文件中的JDBC配置运行其中main[]建立数据库就 关联下tomcat中的外链可以使用了

    JavaBean实体类 配置文件 代码一键自动生成工具

    *.table后缀文件:是金蝶BOS中的一个字段属性映射文件 *PDM:Powerdesigner物理逻辑图,选择PDM时会读取物理逻辑图中的所有表,从里面选择需要生成的目标表就行了 *config文件夹中提供测试的.table文件和PDM文件

    Struts2下多文件的上传与下载

    在网络上,对于Java处理文件上传和下载的技术比较多,而Struts作为一款优秀的框架也提供了非常方便的文件上传和下载,而网上的一些例程都非常的不全面,概括来: 1) 文件上传比较多,多文件上传少一点 2) 文件下载很...

    struts2+MySQL分页.zip

    1. 设置自己的分页器的基本参数(可以从配置文件中读取)  ■每页显示的记录条数  ■每次最多显示多少页 2. 编写设置分页器其他参数的函数  主要参数有以下几个:  总记录条数  总页数  当前页号:现在显示的...

    自己写的struts2+hibernate+spring实例

    注:本代码为个人所写.全当练习使用.愿所有人能够更好地学习软件.愿意与所有软件爱好者成为好友. 邮箱:menxin32@163.com<br>当前版本...数据库连接配置文件是/s2sh/src/目录下面的jdbc.properties文件.直接配置即可.

    JSP程序设计课件包含Hibernate,Struts的介绍

    15. Struts程序启动时,首先从配置文件struts-config.xml文件中读取相关信息,根据这些信息,控制器可以知道把视图中的请求转发给那个业务逻辑处理。视图组件,控制器,业务逻辑组件之间没有代码的联系。 16. Struts...

    深入浅出Struts 2 .pdf(原书扫描版) part 1

    2.5.1 部署描述文件和Struts配置文件 27 2.5.2 动作类 28 2.5.3 运行app02a程序 29 2.6 依赖注入 29 2.6.1 概述 29 2.6.2 依赖注入的几种方式 31 2.7 小结 31 第3章 动作与结果 32 3.1 动作类 32 3.2 如何访问资源 ...

    struts2笔记

    很详细的struts2框架的添加,配置文件的编写,注解方式,HTTP解耦合,通配符,动态结果读取,有详细的案例。

Global site tag (gtag.js) - Google Analytics