Strust2 internal Container

       使用Struts作为mvc模式框架,需要在web.xml 文件中申明org.apache.struts2.dispatcher.FilterDispatcher 这个拦截器作为dispatcher来使用。

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

在FilterDispather类中有很多成员对象是依赖annotation注入的,但是奇怪的是FilterDispatcher并不是配置在容器中的,那是如何让容器来将他所依赖的对象注入进来的呢?

    原来是通过Filter的init方法,调用dispatcher的init方法,在该方法中会初始化一个container,让后利用该容器将filter所依赖的成员对象注入进来。

 public void init(FilterConfig filterConfig) throws ServletException {
    	 this.filterConfig = filterConfig;
    	 
        dispatcher = createDispatcher(filterConfig);
        dispatcher.init();
       
        String param = filterConfig.getInitParameter("packages");
        String packages = DEFAULT_STATIC_PACKAGES;
        if (param != null) {
            packages = param + " " + packages;
        }
        this.pathPrefixes = parse(packages);
    }

 

在init方法中会调用到com.opensymphony.xwork2.config.impl.DefaultConfiguration 的reload方法,最重要的是container = builder.create(false);这个调用,在这个调用方法中它会将在类中有静态依赖的对象注入

 public synchronized void reload(List<ConfigurationProvider> 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<Configuration>() {
            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);
        }
    }

 调用次序是:

  1. Dispatch 的init_PreloadConfiguration方法
  2. ConfigurationManager的getConfiguration方法
  3. DefaultConfiguration的reload方法

你可能感兴趣的:(apache,Web,mvc,框架,struts)