Spring再强大也要面对降临的问题因为Spring不是WeblogicTomcat般的顶层容器Servlet和EJB对象不由它创建所以它必须要降临到WeblogicTomcat所在的位面
初学者一般不用管那么多照着Spring+hibernate+Struts之类的Sample就做了但慢慢的也许就要开始在jsp+javabean体系土制框架Singleton类等环境下使用Spring了
《Professional Java Development with the Spring Framework》第章有Managing the Containe一节讲这个问题一般可以分为直接召唤系与IoC fashion两类
直接召唤系Singleton的Application Context
最简单的就像在UnitTest里那样直接构造Application Context
ApplicationContext ctx = new ClasspathXmlApplicationContext(ApplicationContextxml);
在Web环境里会使用ContextLoader构造ApplicationContext后压进Servlet Context
由ContextLoaderListener或ContextLoaderServlet在Web应用启动时完成
然后在Jsp/Servelet中可以通过Servlet Context取得ApplicationContext ApplicationContext context = WebApplicationContextUtilsgetWebApplicationContext(application);
但像Singleton类或者EJB中就没有Servlet Context可用了
如果全部像UnitTest那样直接构造速度就会很不堪自然的就想到把ApplicationContext做成单例
Spring提供了ContextSingletonBeanFactoryLocator这样的物体
先搞一个beanRefFactoryxml里面写上所有的applcationContext*xml文件名并把Context命名为defaultcontext <beans>
<bean id=defaultcontext class=orgntextsupportClassPathXmlApplicationContext>
<constructorarg>
<list> <value>applicationContextxml</value></list>
</constructorarg>
</bean>
</beans>
然后让loactor去找它但代码有点长 BeanFactoryReference bfr = DefaultLocatorFactorygetInstance()useBeanFactory(defaultcontext);
BeanFactory factory = bfrgetFactory();
MyService myService = factorygetBean(myService);
bfrrelease();
// now use myService
上面的代码实在是太灵活太麻烦了
还不如自己实现一个简单的Singleton扩展ContextLoaderListener类在Web系统启动时压入Singleton
新的ContextLoaderListener类重载如下ContextUtil中包含一个静态的ApplicationContext变量
public void contextInitialized(ServletContextEvent event)
{
ntextInitialized(event);
ServletContext context = eventgetServletContext();
ApplicationContext ctx = WebApplicationContextUtilsgetRequiredWebApplicationContext(context);
ContextUtilsetContext(ctx);
}
用家可直接取用
ApplicationContext context = ContextUtilgetContext();
IoC fashion
如果所有地方都使用直接召唤系那就反而是在打Rod的耳光了因为他一直都反对代码与框架深耦合的
所以更好的方法是写一些glue codebase class来完成Spring的降临而不让应用代码察觉Spring Application Context的存在
不过因为各个框架的结构不同Rod也没办法讲出一个通用的整合方法所以建议大家尽量学习已整合的各种框架如Spring MVCStruts的种种方式写出自己的简单整合代码来
只有不确定的调用某些Singleton类不适合过早ioc的情况可以使用直接召唤系