struts2 源码阅读笔记 - FilterDispatcher

本文只是自己看源码的一些记录。

要使用struts2 首先要在web.xml里面配置struts2的过滤器。

    <filter>
        <filter-name>struts2</filter-name>
        <filter-class>
            org.apache.struts2.dispatcher.FilterDispatcher
        </filter-class>
    </filter>
    <filter-mapping>
        <filter-name>struts2</filter-name>
        <url-pattern>*.do</url-pattern>
    </filter-mapping>

(不过在新版本里面已经不推荐配置FilterDispatcher,而是StrutsPrepareFilter和StrutsExecuteFilter,不过我还是看的FilterDispathcher,原理我想应该是差不多的。)

FilterDispatcher实现了Filter接口。

a.init()方法 。 下面是源码

public void init(FilterConfig filterConfig) throws ServletException {
        try {
            this.filterConfig = filterConfig;
            initLogging();
            dispatcher = createDispatcher(filterConfig);  //1.创建dispatcher 对象。
            dispatcher.init();
            dispatcher.getContainer().inject(this);
            staticResourceLoader.setHostConfig(new FilterHostConfig(filterConfig));
        } finally {
            ActionContext.setContext(null);
        }
    }

1. dispatcher 是struts2 最重要的对象,我理解为struts2的分派器。这个方法可以理解为将ServletContext 全部交给dispatcher管理。

dispatcher对象包含一个私有的属性:private ServletContext servletContext; 下面是Dispatcher的构造方法。

    public Dispatcher(ServletContext servletContext, Map<String, String> initParams) {
        this.servletContext = servletContext;
        this.initParams = initParams;
    }

2.  dispatcher.init(); 完成dispatcher的初始化。

   public void init() {

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

        try {
            init_DefaultProperties(); // [1]
            init_TraditionalXmlConfigurations(); // [2]
            init_LegacyStrutsProperties(); // [3]
            init_CustomConfigurationProviders(); // [5]
            init_FilterInitParameters() ; // [6]
            init_AliasStandardObjects() ; // [7]

            Container container = init_PreloadConfiguration();
            container.inject(this);
            init_CheckConfigurationReloading(container);
            init_CheckWebLogicWorkaround(container);

            if (!dispatcherListeners.isEmpty()) {
                for (DispatcherListener l : dispatcherListeners) {
                    l.dispatcherInitialized(this);
                }
            }
        } catch (Exception ex) {
            if (LOG.isErrorEnabled())
                LOG.error("Dispatcher initialization failed", ex);
            throw new StrutsException(ex);
        }
    }

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

a.)  configurationManager = createConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);

         构造一个配置管理器configurationManager ,并将属性 defaultFrameworkBeanName 设置为“struts”;

b.)   init_DefaultProperties(); // [1]

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

初始化一个DefaultPropertiesProvider对象,并将它加入configurationManager对象中的containerProviders队列中。

DefaultPropertiesProvider 我理解为 默认配置文件提供者,指的是 default.properties

c.) init_TraditionalXmlConfigurations();

初始化 StrutsXmlConfigurationProvider对象,并将它加入configurationManager对象中的containerProviders队列中。这里会分别针对

struts-default.xml ,  struts-plugin.xml  ,  struts.xml 构造3个对象。

d.) init_LegacyStrutsProperties();

将LegacyPropertiesConfigurationProvider 对象加入containerProviders队列中。主要是针对本地的配置文件 struts.properties 

e.)init_CustomConfigurationProviders();

我们一般不会在configFilter 配置configProviders参数。所以这里暂时忽略掉了。

f.)init_FilterInitParameters().

针对ConfigFilter 的initParams。

g.) init_AliasStandardObjects() 

BeanSelectionProvider 对象加入containerProviders队列中

f.)

Container container = init_PreloadConfiguration();

struts2 容器的产生就是在这个方法里面。

我们进入这个方法后,有一段这样的代码。  Configuration config = configurationManager.getConfiguration();

再次进入getConfiguration()方法中,可以看到代码

    public synchronized Configuration getConfiguration() {
        if (configuration == null) {
            setConfiguration(createConfiguration(defaultFrameworkBeanName));
            try {

               //重点就是在这里, 这就是处理所有我们刚才containerProviders队列 中加入的所有对象
                configuration.reloadContainer(getContainerProviders());
            } catch (ConfigurationException e) {
                setConfiguration(null);
                throw new ConfigurationException("Unable to load configuration.", e);
            }
        } else {
            conditionalReload();
        }
        return configuration;
    }

我们再进入 reloadContainer 方法。

  

public synchronized List<PackageProvider> reloadContainer(List<ContainerProvider> providers) throws ConfigurationException {
        packageContexts.clear();
        loadedFileNames.clear();
        List<PackageProvider> packageProviders = new ArrayList<PackageProvider>();

        ContainerProperties props = new ContainerProperties();
        ContainerBuilder builder = new ContainerBuilder();
        for (final ContainerProvider containerProvider : providers)
        {

          // 循环读入配置文件 例如struts.xml

           containerProvider.init(this);

           //循环调用 之前的containerProviders队列中 对象的register方法
            containerProvider.register(builder, props);
        }
        props.setConstants(builder);

        builder.factory(Configuration.class, new Factory<Configuration>() {
            public Configuration create(Context context) throws Exception {
                return DefaultConfiguration.this;
            }
        });

        ActionContext oldContext = ActionContext.getContext();
        try {
            // Set the bootstrap container for the purposes of factory creation
            Container bootstrap = createBootstrapContainer();
            setContext(bootstrap);
            container = builder.create(false);
            setContext(container);
            objectFactory = container.getInstance(ObjectFactory.class);

            // Process the configuration providers first
            for (final ContainerProvider containerProvider : providers)
            {
                if (containerProvider instanceof PackageProvider) {
                    container.inject(containerProvider);
                    ((PackageProvider)containerProvider).loadPackages();
                    packageProviders.add((PackageProvider)containerProvider);
                }
            }

            // Then process any package providers from the plugins
            Set<String> packageProviderNames = container.getInstanceNames(PackageProvider.class);
            if (packageProviderNames != null) {
                for (String name : packageProviderNames) {
                    PackageProvider provider = container.getInstance(PackageProvider.class, name);
                    provider.init(this);
                    provider.loadPackages();
                    packageProviders.add(provider);
                }
            }

            rebuildRuntimeConfiguration();
        } finally {
            if (oldContext == null) {
                ActionContext.setContext(null);
            }
        }
        return packageProviders;
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值