Spring DM与Struts2集成
上一篇文章已经将struts2集成到OSGi环境中了,但要在struts2中使用OSGi的服务还是很麻烦,要自己手动查找服务,而Spring DM则提供了相应的标签来支持查找OSGi服务,所以现在的目标就是让Struts2中的配置文件可以使用Spring DM中定义的Bean。
首先我们要搞清楚SpringDM的工作原理,SpringDM是将每个Bundle下面的/META-INF/Spring/*.xml文件加载进来,创建Spring的上下文,但bundle之间的上下文是隔离的,是存放在org.springframework.osgi.extender.internal.activator.LifecycleManager类中的一个成员变量managedContexts中,此为一个Map,键为Bundle的id,值为bundle对应的Spring上下文,只要我们把bundle对应的Spring上下文找到,要完成在struts2中使用Spring的Bean就容易了。我的做法是将这个map发布成一个服务,然后在Struts的bundle中引用。先将这个Map开放出来。先将org.springframework.osgi.extender以插件的形式导入到工程中来,然后把LifecycleManager的源代码放到src下,在LifecycleManager类中增加方法
public Map<Long, ConfigurableOsgiBundleApplicationContext> getManagedContexts() { return managedContexts; }
然后再编写一个自己的类,持有这个Map
/** * 用于存放Spring DM的上下文环境。 * @author Dream.Lee * @version 2013-6-6 */ public class SpringContextHolder { public SpringContextHolder( Map<Long, ConfigurableOsgiBundleApplicationContext> bundleContexts) { super(); this.bundleContexts = bundleContexts; } /** * key为bundle的id,value为bunlde对应的Spring上下文。 */ private Map<Long, ConfigurableOsgiBundleApplicationContext> bundleContexts; public Map<Long, ConfigurableOsgiBundleApplicationContext> getBundleContexts() { return bundleContexts; } public void setBundleContexts( Map<Long, ConfigurableOsgiBundleApplicationContext> bundleContexts) { this.bundleContexts = bundleContexts; } }
然后修改org.springframework.osgi.extender.internal.activator.ContextLoaderListener的start()方法,在最后加上
//将SpringContextHolder发布成服务,在其它bundle中可以通过bundleid来取得spring的上下文。 holderSF=context.registerService(SpringContextHolder.class.getName(), new SpringContextHolder(lifecycleManager.getManagedContexts()), null);
SpringDM的代码已经改造完成,下面是改造Struts2的代码
由于Struts2中并不能在运行过程中取得自己所在的Bundle,所以我们只有将action所在的bundle保存起来,我的办法是,在解析配置文件的时候在package的标签中加上bundleid,然后在addPackage的方法中,有一个全局变量把action所有的bundle保存下来,以namespace.action为键,bundleid为值,相应的代码如下
if ("package".equals(nodeName)) { if(!configuration.getPackageConfigNames().contains(child.getAttribute("name"))){ PackageConfig cfg = addPackage(child); //FIXME 将action的全路径名与对应的bundle存储到map中。 if(child.getAttribute("bundleid")!=null&&child.getAttribute("bundleid").length()!=0){ for(Entry<String, ActionConfig> entry:cfg.getActionConfigs().entrySet()){ actionNameMapping.put(cfg.getNamespace()+"."+entry.getValue().getName(), Long.parseLong(child.getAttribute("bundleid"))); } } if (cfg.isNeedsRefresh()) { reloads.add(child); } } }
if ("package".equals(nodeName)) { PackageConfig cfg = addPackage(child); //FIXME 将action的全路径名与对应的bundle存储到map中。 if(child.getAttribute("bundleid")!=null&&child.getAttribute("bundleid").length()!=0){ for(Entry<String, ActionConfig> entry:cfg.getActionConfigs().entrySet()){ actionNameMapping.put(cfg.getNamespace()+"."+entry.getValue().getName(), Long.parseLong(child.getAttribute("bundleid"))); } } if (cfg.isNeedsRefresh()) { reloads.add(child); } }
就是上一篇文章提供的那个xmlProvider文件中的方法,
然后是修改ObjectFactory这个类,原来的ObjectFactory在从buildAction调用buildBean的时候,虽然namespace和actionname都传给了buildAction,但buildAction并没有把namespace传给buildBean,所以我们要加一个四个参数的buildBean方法,并设置成protected,默认返回null,这样不会影响其它调用。
public Object buildAction(String actionName, String namespace, ActionConfig config, Map<String, Object> extraContext) throws Exception { //FIXME 先调用增加的四个参数的buildBean方法,如果返回null,再调用原来的buildBean方法 Object retObj=buildBean(actionName, namespace, config.getClassName(), extraContext); if(retObj==null) retObj=buildBean(config.getClassName(), extraContext); return retObj; }
/** * 用于集成Spring DM,默认实现将直接返回空,这样不影响以前的调用。 * @param actionName * @param namespace * @param className * @param extraContext * @return */ protected Object buildBean(String actionName,String namespace,String className,Map<String, Object> extraContext) throws Exception{ return null; }
然后增加自己的ObjectFactory实现,这儿是实现我们刚才增加的那个四个参数的buildBean方法
/** * Struts2集成Spring DM所用的对象工厂。 * @author Dream.Lee * @version 2013-6-4 */ public class SpringOSGiObjectFactory extends StrutsObjectFactory { private static final long serialVersionUID = -6286345242515916560L; @Override protected Object buildBean(String actionName, String namespace, String className, Map<String, Object> extraContext) throws Exception { Object obj=null; BundleContext context =Activator.getContext(); ServiceTracker<SpringContextHolder, SpringContextHolder> st=new ServiceTracker<SpringContextHolder, SpringContextHolder>(context,SpringContextHolder.class.getName(),null); st.open(); SpringContextHolder holder=st.getService(); long bundleid=OSGiXmlConfigurationProvider.actionNameMapping.get(namespace+"."+actionName); ConfigurableOsgiBundleApplicationContext appcontext=holder.getBundleContexts().get(bundleid); if(appcontext!=null){ try{ obj=appcontext.getBean(className); injectInternalBeans(obj); }catch(Exception e){ buildBean(className, extraContext, true); } } st.close(); return obj; } }
这样就大功告成了!
相关推荐
三大框架集成及两两集成的jar包,spring集成hibernate的jar包以及spring集成struts2的jar包已经单独打包
Spring整合集成Struts1.2最简单例子
struts2+spring+springstruts2+spring+springstruts2+spring+spring
struts2 spring hibernate集成 介绍上传下载。。
Spring 2.0集成Struts 2.0
包含Spring4 jar包和Struts2 jar包和整合之后的完整jar包。还有web.xml,struts.xml和applicationContext.xml文件,导入工程后可直接进行基于Spring4和Struts2上的开发。
struts spring集成 struts spring集成 struts spring集成
SSH集成 Struts+spring+hibernate集成SSH集成 Struts+spring+hibernate集成
Spring集成struts以及hibernate jar包 所有的都在里面 需要的可以下载
spring3+struts2+ibatis工程demo;
NULL 博文链接:https://1194867672-qq-com.iteye.com/blog/1294435
spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 spring webmvc struts 2.5 ...
整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6。 此外,还有:log4j、slf4j、junit4、ehcache等知识点。 项目...
struts2入门教程及struts2集成spring。
通过简单了实例 并提供代码 指导初学者学会spring和struts2的集成 并实现简单的登录功能
CXF+spring+struts实现WebService
NULL 博文链接:https://liwei113114.iteye.com/blog/1884260
spring3、struts2、mybatis和tiles结合的一个简单java web实现(XX学园管理系统),意在这几个框架的结合配置,供初学者学习参考。附件包含完成的代码和数据库脚本。
Maven搭建spring_struts2_Hibernate项目源码,包括数据库,博客地址:http://blog.csdn.net/fengshizty/article/details/43794911
ssh的包spring4+struts2+hibernate5。自己使用的框架包