项目开发中遇到同一个tomcat下的多个应用之间会相互调用的问题,分享一下实现方法。
背景:
tomcat有project1,project2两个应用,在project2中需要调用project1中bean里的方法。
预置条件:
tomcat server.xml文件中两个应用的Context 分别增加 crossContext="true"属性。
project1代码实现:
servletContextListener,将spring里的bean写入到servlet容器中,方便project2中引用
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import org.springframework.context.ApplicationContext;
import org.springframework.web.context.WebApplicationContext;
public class ServiceExposer implements ServletContextListener {
public void contextInitialized(ServletContextEvent sce) {
//获取ServletContext对象
ServletContext context = sce.getServletContext();
//获取应用Context对象
ApplicationContext appContext = (ApplicationContext)context.getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
//将spring里的bean对象注入到web容器,方便project2中引用
exposeSearchHotWordsService(context, appContext);
}
private void exposeSearchHotWordsService(ServletContext context, ApplicationContext appContext){
SearchHotWordsService searchHotWordsService = appContext.getBean(SearchHotWordsService.class);
context.setAttribute("searchHotWordsService", searchHotWordsService);
}
public void contextDestroyed(ServletContextEvent sce) {
}
}
project2代码实现:
增加HttpSessionListener实现类,获取project1中的bean
import javax.servlet.ServletContext;
import javax.servlet.ServletContextEvent;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionEvent;
import javax.servlet.http.HttpSessionListener;
import org.apache.log4j.Logger;
public class ServiceListener implements HttpSessionListener {
private final static Logger logger = Logger.getLogger(ServiceListener.class);
public void contextDestroyed(ServletContextEvent sce) {
}
@Override
public void sessionCreated(HttpSessionEvent se) {
if(!StoreService.getInstance().isSearchHotWordsServiceReady()){
//获取project1中的bean实例
Object service = getBeanFromStoreContext(se, "searchHotWordsService");
StoreService.getInstance().setSearchHotWordsService(service);
}
}
private Object getBeanFromStoreContext(HttpSessionEvent se,String beanName){
ServletContext storeCtx = se.getSession().getServletContext().getContext("Project1");
if(storeCtx != null){
Object service = storeCtx.getAttribute(beanName);
return service;
}
return null;
}
}
调用project1 bean里的方法
package com.test;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
import javax.servlet.ServletContext;
import org.apache.log4j.Logger;
import org.springframework.beans.BeanUtils;
import com.yulong.coolcloud.coolstore.zsPush.ZeusisPushResponse;
public class StoreService {
private static Logger logger = Logger.getLogger(StoreService.class);
//单例
private static StoreService singleService = new StoreService();
//project1中的bean
private Object searchHotWordsService;
public boolean isSearchHotWordsServiceReady(){
return this.searchHotWordsService != null;
}
public void updateWeightFromStatic(){
if(searchHotWordsService!=null){
Method insertLog;
try{
//利用反射调用project1里searchHotWordsService bean的updateWeightFromStatic方法
insertLog = searchHotWordsService.getClass().getMethod("updateWeightFromStatic");
insertLog.invoke(searchHotWordsService);
}catch(Exception e){
throw new RuntimeException(e);
}
}
}
public static StoreService getInstance(){
return singleService;
}
public void setSearchHotWordsService(Object searchHotWordsService) {
this.searchHotWordsService = searchHotWordsService;
}
}
测试是否调用成功:
public class Test {
public static void main(String[] args) {
StoreService.getInstance().updateWeightFromStatic();
}
}