由于非技術(shù)原因,公司的專(zhuān)門(mén)成立的支付部,招一批Java程序員,做了支付系統;又由于非技術(shù)原因,兩個(gè)月內,這個(gè)部門(mén)從領(lǐng)導到程序員全走光了。然后這個(gè)支付系統就移交給我們這幫受苦受難的兄弟們維護了。在看他們代碼的時(shí)候發(fā)現了很有趣的東西,就是在tomcat內共享Spring context。
<Resource auth="Container"
contextConfigLocation="/com/test/application-context.xml"
factory="com.test.TomcatWebApplicationContextResourceFactory"
name="bean/RootApplicationContextFactory"
type="org.springframework.context.ApplicationContext"/>
上面這段配置的意思就是,當有人通過(guò)jndi名稱(chēng)”bean/RootApplicationContextFactory”來(lái)查找對象時(shí),容器就新建一個(gè)TomcatWebApplicationContextResourceFactory類(lèi)實(shí)例,并調用它的getObjectInstance方法來(lái)獲得資源對象。這個(gè)工廠(chǎng)類(lèi)要是想javax.naming.spi.ObjectFactory接口。代碼如下:
package com.test;
import java.util.Hashtable;
import javax.naming.Context;
import javax.naming.Name;
import javax.naming.RefAddr;
import javax.naming.Reference;
import javax.naming.spi.ObjectFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TomcatWebApplicationContextResourceFactory implements
ObjectFactory {
private static final String PARAM = "contextConfigLocation";
private static final String DEFAULT = "application-context.xml";
private static ApplicationContext context; //被共享的spring上下文
private void init(String confFile) {
context = new ClassPathXmlApplicationContext(confFile);
}
public Object getObjectInstance(Object obj,
Name name, Context nameCtx,
Hashtable<?, ?> environment) throws Exception {
if (null == context) {
// Customize the bean properties from our attributes
Reference ref = (Reference) obj;
//從xml配置文件里取得contextConfigLocation元素的值
RefAddr addr = ref.get(PARAM);
if (null != addr) {
String value = (String) addr.getContent();
init(value);
} else {
init(DEFAULT);
}
}
return context;
}
}
1.2 在web應用中引用上面定義的資源
修改tomcat/conf/web.xml,添加以下的內容,這樣在這個(gè)tomcat下的所有的web應用就都可以訪(fǎng)問(wèn)共享的spring上下文了。
<resource-env-ref>
<description>Object factory for Root applicationcontext</description>
<resource-env-ref-name> bean/RootApplicationContextFactory
</resource-env-ref-name>
<resource-env-ref-type> org.springframework.context.ApplicationContext
</resource-env-ref-type>
</resource-env-ref>
1.3 加入依賴(lài)的包
從第一步可以看出,tomcat容器需要訪(fǎng)問(wèn)spring的一些類(lèi),需要初始化上下文,所以要把初始化上下文時(shí)用到的類(lèi)共享給tomcat。最簡(jiǎn)單的方法是把所有相關(guān)的類(lèi)和jar包復制到tomcat/lib目錄。還可以修改catalina.properties實(shí)現,如下:
shared.loader=/usr/local/jars/*.jar
上面的代碼讓tomcat載入自定目錄里面所有的jar文件。
2 我的看法
一個(gè)龐大的spring上下文是要占用很多內存的,所有應用共享一個(gè)上下文,而不是每個(gè)web應用一份,就可以節省不少的內存。但是由此卻帶來(lái)了部署和配置的麻煩。如果有人利用這種機制,讓多個(gè)web應用通過(guò)共享spring bean來(lái)實(shí)現一些奇怪的功能,結果導致這些應用間相互耦合,那么以后想拆分開(kāi)也不容易了??傮w來(lái)說(shuō),我不喜歡這樣方案,但是如果真的很窮很缺內存的話(huà),這也不失一個(gè)好方法。
本站僅提供存儲服務(wù),所有內容均由用戶(hù)發(fā)布,如發(fā)現有害或侵權內容,請
點(diǎn)擊舉報。