Struts2.3.14分析-初期化1

12496 ワード


Web.xml
StrutsベースのWebプログラムでは、最初に構成する必要があるのはWebです.xmlは、すべての要求をStrutsPrepareAndExecuteFilterに渡してフィルタします.
<filter>
    <filter-name>struts2</filter-name>        
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
   <filter-name>struts2</filter-name>
   <url-pattern>/*</url-pattern>
</filter-mapping>

StrutsPrepareAndExecuteFilter初期化
StrutsPrepareAndExecuteFilterは実装されたFilterインタフェースのフィルタであり、init、doFilter、Destoryメソッドを実装する必要があります.Initメソッドの主なタスクはFilter関連パラメータを初期化し、構成パラメータをロードすることであり、Strutsに対して明らかである.xmlファイルの解析も、このメソッド呼び出しの過程で完了します.
次にinitメソッドを分析します
public class StrutsPrepareAndExecuteFilter implements StrutsStatics, Filter {
    protected PrepareOperations prepare;
    protected ExecuteOperations execute;
	protected List<Pattern> excludedPatterns = null;

public void init(FilterConfig filterConfig) throws ServletException {
        InitOperations init = new InitOperations();
        try {
			# FilterHostConfig FilterConfig      
            FilterHostConfig config = new FilterHostConfig(filterConfig);
            #     Struts    
init.initLogging(config);
# Dispatcher   ServletContext FilterConfig,    dispatcher init   
            Dispatcher dispatcher = init.initDispatcher(config);
            init.initStaticContentLoader(config, dispatcher);

            prepare = new PrepareOperations(filterConfig.getServletContext(), dispatcher);
            execute = new ExecuteOperations(filterConfig.getServletContext(), dispatcher);
			this.excludedPatterns = init.buildExcludedPatternsList(dispatcher);

            postInit(dispatcher, filterConfig);
        } finally {
            init.cleanup();
        }

}

InitOperationクラス
public class InitOperations {

    public InitOperations() {
    }

	//   Dispatch  
public Dispatcher initDispatcher( HostConfig filterConfig ) {
        Dispatcher dispatcher = createDispatcher(filterConfig);
        dispatcher.init();
        return dispatcher;
}

private Dispatcher createDispatcher( HostConfig filterConfig ) {
	//  Web.xml filter     
        Map<String, String> params = new HashMap<String, String>();
        for ( Iterator e = filterConfig.getInitParameterNames(); e.hasNext(); ) {
            String name = (String) e.next();
            String value = filterConfig.getInitParameter(name);
            params.put(name, value);
}
return new Dispatcher(filterConfig.getServletContext(), params);
}

//     
}

Dispatcherクラス
private ServletContext servletContext;
private Map<String, String> initParams;
private ConfigurationManager configurationManager;


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

//    ,          
public void init() {
    	if (configurationManager == null) {
    		configurationManager = createConfigurationManager(BeanSelectionProvider.DEFAULT_BEAN_NAME);
	#BeanSelectionProver.DEFAULT_BEAN_NAME   struts
    	}
     try {
		#      configurationManager.addContainerProvider  
     	init_FileManager();
     	init_DefaultProperties();
     	init_TraditionalXmlConfigurations(); //  struts-default.xml,struts-plugin.xml,struts.xml      ConfigurationProvider  ,    ConfigurationManager    ,                   
     	init_LegacyStrutsProperties(); 
     	init_CustomConfigurationProviders();
      	init_FilterInitParameters() ; 
    		init_AliasStandardObjects() ; 

  		Container container = init_PreloadConfiguration();//         
     	container.inject(this);
    		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);
        }
}

private void init_TraditionalXmlConfigurations() {
        String configPaths = initParams.get("config");
        if (configPaths == null) {
			# struts-default.xml,struts-plugin.xml,struts.xml
            configPaths = DEFAULT_CONFIGURATION_PATHS;
        }
        String[] files = configPaths.split("\\s*[,]\\s*");
        for (String file : files) {
            if (file.endsWith(".xml")) {
                if ("xwork.xml".equals(file)) {
                    configurationManager.addContainerProvider(createXmlConfigurationProvider(file, false));
                } else {
                #    createStrutsXmlConfigurationProvider configurationManager.addContainerProvider(createStrutsXmlConfigurationProvider(file, false, servletContext));
                }
            } else {
                throw new IllegalArgumentException("Invalid configuration file name");
            }
        }
    }

protected XmlConfigurationProvider createStrutsXmlConfigurationProvider(String filename, boolean errorIfMissing, ServletContext ctx) {
        return new StrutsXmlConfigurationProvider(filename, errorIfMissing, ctx);
    }

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

        ContainerHolder.store(container);
        return container;
    }

StrutsXmlConfigurationProviderクラス
init_TraditionalXmlConfigurationsメソッド呼び出しは、struts-defaultである3つのStrutsXmlConfigurationProviderオブジェクトを作成する.xml,struts-plugin.xml, struts.xml
public class StrutsXmlConfigurationProvider extends XmlConfigurationProvider {     
    private File baseDir = null;
    private String filename;      
    private ServletContext servletContext;

public StrutsXmlConfigurationProvider(String filename, boolean errorIfMissing, ServletContext ctx) {
        super(filename, errorIfMissing);
        this.servletContext = ctx;
        this.filename = filename;
        reloadKey = "configurationReload-"+filename;
        ……
        File file = new File(filename);
        if (file.getParent() != null) {
            this.baseDir = file.getParentFile();
        }
}
//       
}

XmlConfigurationProviderクラス
public class XmlConfigurationProvider implements ConfigurationProvider {     
    private String configFileName;   
    private boolean errorIfMissing;    

    public XmlConfigurationProvider(String filename, boolean errorIfMissing) {
        this.configFileName = filename;
        this.errorIfMissing = errorIfMissing;
        ……
        setDtdMappings(mappings);
}

ConfigurationProviderインタフェース
public interface ConfigurationProvider extends ContainerProvider, PackageProvider {
}

ContainerProviderインタフェース
public interface ContainerProvider {
    public void destroy();     
    public void init(Configuration configuration) throws ConfigurationException;     
    public boolean needsReload();    
    public void register(ContainerBuilder builder, LocatableProperties props) throws ConfigurationException;    
}

コンフィギュレーションマネージャクラス
public class ConfigurationManager {    
	    protected Configuration configuration;	   
	    private List<ContainerProvider> containerProviders = new CopyOnWriteArrayList<ContainerProvider>();
	    private List<PackageProvider> packageProviders = new CopyOnWriteArrayList<PackageProvider>();
	    protected String defaultFrameworkBeanName;

public synchronized Configuration getConfiguration() {
        		if (configuration == null) {
            		setConfiguration(new DefaultConfiguration(defaultFrameworkBeanName));
            		try {
				#   DefaultConfiguration reloadContainer  
                	configuration.reloadContainer(getContainerProviders());
            		} catch (ConfigurationException e) {
                		setConfiguration(null);
                		throw new ConfigurationException("Unable to load configuration.", e);
            		}
        		} else {
            		conditionalReload();
        		}
        			return configuration;
   		 }

    		public synchronized void setConfiguration(Configuration configuration) {
      		this.configuration = configuration;
    		}

	    //   List         ContainerProvider     
public void addContainerProvider(ContainerProvider provider) {
		if (!containerProviders.contains(provider)) {
   		containerProviders.add(provider);
}
   }

DefaultConfigurationクラス
public class DefaultConfiguration implements Configuration {

    protected static final Logger LOG = LoggerFactory.getLogger(DefaultConfiguration.class);


    // Programmatic Action Configurations
    protected Map<String, PackageConfig> packageContexts = new LinkedHashMap<String, PackageConfig>();
    protected RuntimeConfiguration runtimeConfiguration;
    protected Container container;
    protected String defaultFrameworkBeanName;
    protected Set<String> loadedFileNames = new TreeSet<String>();
protected List<UnknownHandlerConfig> unknownHandlerStack;

//       ConfigurationProvider   
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)
        {
			//    ,   containerProvider     ,      ,
# struts.xml            (  XmlConfigurationProvider init   StrutsXmlConfigurationProvider register  )
            containerProvider.init(this);
            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;
    }

紙面の都合でStrutsにxml解析プロセスは、strutsフレームワークを使用する主なプロファイルであり、strutsがどのようにロードされているかを理解する必要があります.