webx 容器初始化
来源:互联网 发布:淘宝上比较好的女鞋店 编辑:程序博客网 时间:2024/06/06 09:08
webx扩展了spring的容器加载机制,首先在结构上扩展了component层,构造出不同应用模块bean之间的隔离机制。
1.解析web.xml
和spring web程序一样,容器的加载是通过在web.xml中配置的listener实现的。servlet容器在实例化servlet context的时候会触发contextInitialized方法从而开启实例化容器的流程。
根据servlet规范,listener按照观察者模式设计,一旦监听到某个事件就执行某个方法。而web.xml文件中有WebxContextLoaderListener继承了ServletContextListener接口,就会调用contextInitialized方法。
2.分析WebxContextLoaderListener
该类的功能:监听ServletContext事件,加载Spring容器;
类的继承结构:
@Overrideprotected final ContextLoader createContextLoader() { return new WebxComponentsLoader() { @Override protected Class<? extends WebxComponentsContext> getDefaultContextClass() { Class<? extends WebxComponentsContext> defaultContextClass = WebxContextLoaderListener.this .getDefaultContextClass(); if (defaultContextClass == null) { defaultContextClass = super.getDefaultContextClass(); } return defaultContextClass; } };}
ContextLoaderListener中调用上面创建的contextLoader进行初始化webx容器
public void contextInitialized(ServletContextEvent event) { this.contextLoader = createContextLoader(); if (this.contextLoader == null) { this.contextLoader = this; } this.contextLoader.initWebApplicationContext(event.getServletContext());}
3.应用上下文结构
相对于Spring上下文中以bean为单位进行加载,webx新增加了组件的结构。在容器加载的时候webx默认会扫描web-info目录下的webx.xml 文件和webx-*xml文件,进行资源加载,创建容器。
webx将一个web应用分解成多个小应用模块:app1,app2等。将一个大的应用变成若干个小应用模块,并且配置文件相互隔离。
- 所有小应用模块共享一个Spring Root Context( 根容器 ),对应 webx.xml ,根容器的bean可以被注入到子容器中;反过来不行。
- 每个小应用独享一个Spring Sub Context( 子容器 ),对应 webx-*.xml ,子容器之间相互隔离,不可相互注入bean。
需要注意的是,即使web应用很简单,也至少配置一个子容器。
如何实现刚才所说的组件容器加载的呢?WebxComponentsContext继承了AbstractApplicationContext并对 postProcessBeanFactory 方法和 finishRefresh方法进行了覆写,也正是这两个方法实现了webx独特的component。这一点非常重要!
在配置文件中,例如webx-*.xml中导入其他的xml加载bean的时候,从根上下文中是加载不到这些bean的,要通过获取该模块的component对应的上下文才能获取。
WebApplicationContext context = WebApplicationContextUtils .getWebApplicationContext(getServletContext());WebxComponentsContext webxComponentsContext = (WebxComponentsContext)context;WebxComponents components = webxComponentsContext.getWebxComponents();WebxComponent component = components.getComponent("home"); playService = (PlayService) component.getApplicationContext().getBean("playServiceImpl");
扩展加载component的结构图:
1)覆写postProcessBeanFactory方法,实际上是实例化WebxComponentsCreator内部类,用于初始化root component和sub component,并且将所有的sub component的父容器设置成root component,形成级联结构。
/** 初始化components。 */private WebxComponentsImpl createComponents(WebxConfiguration parentConfiguration, ConfigurableListableBeanFactory beanFactory) { ComponentsConfig componentsConfig = getComponentsConfig(parentConfiguration); // 假如isAutoDiscoverComponents==true,试图自动发现components Map<String, String> componentNamesAndLocations = findComponents(componentsConfig, getServletContext()); // 取得特别指定的components Map<String, ComponentConfig> specifiedComponents = componentsConfig.getComponents(); // 实际要初始化的comonents,为上述两种来源的并集 Set<String> componentNames = createTreeSet(); componentNames.addAll(componentNamesAndLocations.keySet()); componentNames.addAll(specifiedComponents.keySet()); // 创建root controller WebxRootController rootController = componentsConfig.getRootController(); if (rootController == null) { rootController = (WebxRootController) BeanUtils.instantiateClass(componentsConfig.getRootControllerClass()); } // 创建并将components对象置入resolvable dependencies,以便注入到需要的bean中 WebxComponentsImpl components = new WebxComponentsImpl(componentsContext, componentsConfig.getDefaultComponent(), rootController, parentConfiguration); beanFactory.registerResolvableDependency(WebxComponents.class, components); // 初始化每个component for (String componentName : componentNames) { ComponentConfig componentConfig = specifiedComponents.get(componentName); String componentPath = null; WebxController controller = null; if (componentConfig != null) { componentPath = componentConfig.getPath(); controller = componentConfig.getController(); } if (controller == null) { controller = (WebxController) BeanUtils.instantiateClass(componentsConfig.getDefaultControllerClass()); } WebxComponentImpl component = new WebxComponentImpl(components, componentName, componentPath, componentName.equals(componentsConfig.getDefaultComponent()), controller, getWebxConfigurationName()); components.addComponent(component); prepareComponent(component, componentNamesAndLocations.get(componentName)); } return components;}
2)- 覆写finishRefresh方法,遍历地所有的sub component,通过wcc.refresh方法初始化每个sub component中的bean。
/** 初始化所有components。 */public void finishRefresh() { components.getWebxRootController().onFinishedProcessContext(); for (WebxComponent component : components) { logInBothServletAndLoggingSystem("Initializing Spring sub WebApplicationContext: " + component.getName()); WebxComponentContext wcc = (WebxComponentContext) component.getApplicationContext(); WebxController controller = component.getWebxController(); wcc.refresh(); controller.onFinishedProcessContext(); } logInBothServletAndLoggingSystem("WebxComponents: initialization completed");}
0 0
- webx 容器初始化
- Webx日志系统初始化
- note2.Webx 2.x初始化之webxLoader
- webX
- Webx
- webx
- 容器初始化
- 容器 初始化
- 初始化容器
- spring初始化容器
- 容器ArrayList的初始化.
- 静态容器变量初始化
- 容器通过数组初始化
- Spring初始化容器
- Spring初始化容器
- Spring获得初始化容器
- 顺序容器:初始化
- vector顺序容器初始化
- Android官方开发文档Training系列课程中文版:后台服务之IntentService的创建
- Light OJ:1058Parallelogram Counting(几何数学+技巧排序)
- Linux常用命令 ---- grep命令
- Android官方开发文档Training系列课程中文版:后台服务之IntentService的使用
- 递归逆序打印字符串
- webx 容器初始化
- Android Studio 多环境打包(测试,开发,生产)
- 2016.8.14
- html5 audio,video 操作方法
- HDU 1393 Weird Clock
- 实现链表的反转
- 面向对象的三大特征
- Light OJ:1104 Birthday Paradox(数学概率+思维)
- 每天00:00,MySQL定时弹出一个taskeng.exe