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; } }
这样就大功告成了!
相关推荐
标题“Spring DM集成Struts2(一)”指出我们要探讨的主题是关于如何在OSGi(Spring DM,即Spring Dynamic Modules)环境中集成Struts2框架。这是一个关键的Java Web开发中的技术结合,因为它允许开发者利用Spring的...
“Struts2相关信息.txt”可能包含了与Struts2相关的其他信息,如最佳实践、性能优化技巧或者框架与其他技术(如Spring、Hibernate)的集成方法。 “附 Struts1应用.txt”虽然不是直接关于Struts2,但可能对比了...
6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4 将Spring与JSF集成 226 6.4.1 问题 226 6.4.2 解决方案 226 6.4.3 工作原理 227 6.5 将Spring与DWR...
在Web层,Spring提供了SpringMVC作为强大的MVC框架,与Struts、Struts2、GWT、JSF等其他框架相比,SpringMVC提供了更为灵活和高效的解决方案。而在持久层,Spring支持多种ORM框架,如Hibernate、iBatis、JDO、...
6.3 将Spring与Struts 1.x集成 220 6.3.1 问题 220 6.3.2 解决方案 220 6.3.3 工作原理 220 6.4 将Spring与JSF集成 226 6.4.1 问题 226 6.4.2 解决方案 226 6.4.3 工作原理 227 6.5 将Spring与DWR...
2. **案例分析**:在实际应用中,开发者可以利用Spring DM将现有的Spring应用程序迁移到OSGi环境中,同时利用OSGi的模块化能力提高系统的可维护性和灵活性。 综上所述,Spring框架通过其丰富的模块和特性为开发者...
SSH整合指的是将三个开源框架Struts2、Spring3和Hibernate3集成在一起,用于构建高效、稳定的企业级Web应用。这三种框架分别承担着MVC模式中的表现层、业务层和服务层的角色,协同工作以实现数据的持久化、业务逻辑...
SSH,全称是Struts2、Spring和Hibernate的组合,是一种在Java Web开发中常用的开源框架集成。这个"SSH精简包.rar"包含了这三种框架的核心库,旨在提供一个轻量级的解决方案,去除了不常用或者冗余的组件,以提高开发...
- **Struts 1.x/Struts 2**: 分别支持 Struts 1 和 Struts 2 框架,包括 XML 和 Tag 提示。 - **Tapestry**: 支持 Tapestry 框架,这是一个结合了 MVC 和模板技术的 Java Web 框架。 - **Vaadin**: 支持 Vaadin 框架...
**SSH**脚手架是Struts、Spring和Hibernate的集成,它为Web应用提供了一个灵活的开发框架。Struts处理MVC模式中的视图和控制,Spring负责依赖注入和事务管理,Hibernate则作为ORM工具处理数据库交互。 **Spring-DM*...
3. **SSH 框架**: SSH 是 Struts、Spring 和 Hibernate 的集成框架,广泛应用于轻量级 Web 应用程序开发。Struts 提供 MVC 架构,Spring 实现了依赖注入(IoC)和面向切面编程(AOP),Hibernate 则是 ORM 工具,...
SSH(Spring、Struts、Hibernate)框架组合是Java后端开发的常用技术栈,而在SSH框架下实现多数据源支持,可以有效地处理来自不同数据库的数据,提高系统的灵活性和可扩展性。本文将详细介绍如何使用Spring 3的动态...
WebWork是一个开源的Java Web应用框架,主要用于构建企业级的Web应用程序。...此外,了解WebWork的进化历程和它如何与Struts2等其他框架融合也很有帮助,因为这能让你了解框架的发展趋势和技术选择的重要性。
- **OSGi**:为Java平台定义了一个动态模块系统,Equinox 和 SpringDM 是其中两个实现。 - **SOA框架**:如Apache Tuscany,用于构建服务导向架构(SOA)应用。 - **P3:特定领域框架** - **Flex/Sliverlight**:...
- **Struts+Spring框架**:用于构建稳定、灵活的Web应用程序,提供良好的结构和组件。 - **XML与XSL**:XML用于数据交换和存储,XSL实现数据格式转换,可用于构建前后端分离的系统。 - **Flash与XML**:Flash通过...