下面就是我们要讨论的问题: 在web应用根上下文建立的时候,是可以对它设置父上下文的,在ContextLoader中: [code] protected ApplicationContext loadParentContext(ServletContext servletContext) throws BeansException { ApplicationContext parentContext = null; //这里读取在web.xml中配置的参数 String locatorFactorySelector = servletContext.getInitParameter(LOCATOR_FACTORY_SELECTOR_PARAM); String parentContextKey = servletContext.getInitParameter(LOCATOR_FACTORY_KEY_PARAM); //这里得到一个Locator实际上是一个管理IOC容器的容器 if (locatorFactorySelector != null) { BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); if (logger.isInfoEnabled()) { logger.info("Getting parent context definition: using parent context key of '" + parentContextKey + "' with BeanFactoryLocator"); } //这里从Locator容器中得到需要的IOC容器作为根上下文的父上下文,这个IOC容器的取得通过配置LOCATOR_FACTORY_KEY_PARAM属性 this.parentContextRef = locator.useBeanFactory(parentContextKey); parentContext = (ApplicationContext) this.parentContextRef.getFactory(); } return parentContext; } [/code] 问题在这个BeanFactory的作用上,看到在reference guide和Java Doc中的说明: 在reference3.9中提到这个Selector的使用: [i]As another example, in a complex J2EE apps with multiple layers (various JAR files, EJBs, and WAR files packaged as an EAR), with each layer having its own Spring IoC container definition (effectively forming a hierarchy), the preferred approach when there is only one web-app (WAR) in the top hierarchy is to simply create one composite Spring IoC container from the multiple XML definition files from each layer. All of the various Spring IoC container implementations may be constructed from multiple definition files in this fashion. However, if there are multiple sibling web-applications at the root of the hierarchy, it is problematic to create a Spring IoC container for each web-application which consists of mostly identical bean definitions from lower layers, as there may be issues due to increased memory usage, issues with creating multiple copies of beans which take a long time to initialize (e.g. a Hibernate SessionFactory), and possible issues due to side-effects. As an alternative, classes such as ContextSingletonBeanFactoryLocator or SingletonBeanFactoryLocator may be used to demand-load multiple hierarchical (that is one container is the parent of another) Spring IoC container instances in a singleton fashion, which may then be used as the parents of the web-application Spring IoC container instances. The result is that bean definitions for lower layers are loaded only as needed, and loaded only once. [/i] 这里的大致意思是说如果在一个复杂的J2EE应用中怎样简化IOC配置的问题,可以通过这个Locator为多个web应用或者是多层IOC定义一个顶层的IOC容器,这样的话可以只用对多个配置文件读取一次,同时这个顶层IOC容器中管理的bean都是可以共享的 - 而且这个顶层的IOC容器是以单例形式被使用的。在JAVA Doc中给出了使用的例子: 首先配置在顶层IOC需要的定义文件,实际上是配置了一个IOC容器作为这个Locator的bean: [code] com/mycompany/myapp/util/applicationContext.xml com/mycompany/myapp/dataaccess/applicationContext.xml com/mycompany/myapp/dataaccess/services.xml [/code] 然后就是对这个Locator的使用,如果去看一下ContextLoader的代码也是这样使用的: [code] BeanFactoryLocator bfl = SingletonBeanFactoryLocator.getInstance(); BeanFactoryReference bf = bfl.useBeanFactory("com.mycompany.myapp"); // now use some bean from factory MyClass zed = bf.getFactory().getBean("mybean"); [/code] 在ContextLoader中的使用是这样的: [code] if (locatorFactorySelector != null) { BeanFactoryLocator locator = ContextSingletonBeanFactoryLocator.getInstance(locatorFactorySelector); if (logger.isInfoEnabled()) { logger.info("Getting parent context definition: using parent context key of '" + parentContextKey + "' with BeanFactoryLocator"); } //这里从Locator容器中得到需要的IOC容器作为根上下文的父上下文,这个IOC容器的取得通过配置LOCATOR_FACTORY_KEY_PARAM属性 this.parentContextRef = locator.useBeanFactory(parentContextKey); parentContext = (ApplicationContext) this.parentContextRef.getFactory(); } [/code] 从这点看,这个管理IOC容器的容器还是很方便的使用的 - 而且是单例的形式,这样为我们管理那些公用的bean提供了很多便利, 换句话说,如果灵活使用的话,我们可以通过这个管理容器的容器根据需要选择我们的需要到的容器,也就是选择需要的bean - 不一定在顶层去作为根上下文的父上下文。 但经过讨论,我还是不太明白这个Locator怎样能够在跨web应用做到一个单例的使用?因为一个web应用启动时就会维护一个自己的ContextLoader,这里就会有一个自己的Locator,也就是以后在这个应用的范围内使用这个Locator,所以难道这个Locator只能在一个Web应用中使用来管理IOC容器?但是reference guide中的这段话又怎么理解呢? [i] However, if there are multiple sibling web-applications at the root of the hierarchy, it is problematic to create a Spring IoC container for each web-application which consists of mostly identical bean definitions from lower layers,as there may be issues due to increased memory usage, issues with creating multiple copies of beans which take a long time to initialize (e.g. a Hibernate SessionFactory), and possible issues due to side-effects.[/i] 难道这个Locator的作用范围的确只能在一个web应用中为多层次的IOC定义提供服务?
评论
发表评论

您还没有登录,请登录后发表评论

jiwenke
搜索本博客
最近加入圈子
存档
最新评论
评论排行榜