`
liwei113114
  • 浏览: 14200 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

Spring DM集成Strtus2(二)

    博客分类:
  • OSGi
阅读更多

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;
	}

}

 这样就大功告成了!

0
0
分享到:
评论
4 楼 wishingyo 2013-07-11  
你好 我最近一直在学习osgi 集成 SSH,但是没有成功,能请你把源码发一份给点指点么?不胜感激。邮箱: 360659387@qq.com
3 楼 lisiyu 2013-06-17  
你好,我也在学习osgi,但是把ssh集成时没有成功,麻烦把源码发一份,不胜感激.邮箱lisiyu4125@126.com
2 楼 liwei113114 2013-06-13  
cnrainbing 写道
你好,我也研究了很久osgi ,也想把struts2和spring dm整合但是一直没有弄好,希望楼主能提供一下源码分享一下多谢!

留一下邮箱嘛,我发给你!
1 楼 cnrainbing 2013-06-09  
你好,我也研究了很久osgi ,也想把struts2和spring dm整合但是一直没有弄好,希望楼主能提供一下源码分享一下多谢!

相关推荐

    Spring DM集成Strtus2(一)

    标题“Spring DM集成Struts2(一)”指出我们要探讨的主题是关于如何在OSGi(Spring DM,即Spring Dynamic Modules)环境中集成Struts2框架。这是一个关键的Java Web开发中的技术结合,因为它允许开发者利用Spring的...

    struts2笔记

    “Struts2相关信息.txt”可能包含了与Struts2相关的其他信息,如最佳实践、性能优化技巧或者框架与其他技术(如Spring、Hibernate)的集成方法。 “附 Struts1应用.txt”虽然不是直接关于Struts2,但可能对比了...

    Spring攻略(第二版 中文高清版).part2

    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...

    Spring攻略(第二版 中文高清版).part1

    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...

    ssh整合.rar

    SSH整合指的是将三个开源框架Struts2、Spring3和Hibernate3集成在一起,用于构建高效、稳定的企业级Web应用。这三种框架分别承担着MVC模式中的表现层、业务层和服务层的角色,协同工作以实现数据的持久化、业务逻辑...

    SSH精简包.rar

    SSH,全称是Struts2、Spring和Hibernate的组合,是一种在Java Web开发中常用的开源框架集成。这个"SSH精简包.rar"包含了这三种框架的核心库,旨在提供一个轻量级的解决方案,去除了不常用或者冗余的组件,以提高开发...

    IDEA教程中文版。

    - **Struts 1.x/Struts 2**: 分别支持 Struts 1 和 Struts 2 框架,包括 XML 和 Tag 提示。 - **Tapestry**: 支持 Tapestry 框架,这是一个结合了 MVC 和模板技术的 Java Web 框架。 - **Vaadin**: 支持 Vaadin 框架...

    基于OSGi的Web应用开发系列(全).pdf

    **SSH**脚手架是Struts、Spring和Hibernate的集成,它为Web应用提供了一个灵活的开发框架。Struts处理MVC模式中的视图和控制,Spring负责依赖注入和事务管理,Hibernate则作为ORM工具处理数据库交互。 **Spring-DM*...

    大学生程序员实习报告大全.docx

    3. **SSH 框架**: SSH 是 Struts、Spring 和 Hibernate 的集成框架,广泛应用于轻量级 Web 应用程序开发。Struts 提供 MVC 架构,Spring 实现了依赖注入(IoC)和面向切面编程(AOP),Hibernate 则是 ORM 工具,...

    Ssh多数据源.doc

    SSH(Spring、Struts、Hibernate)框架组合是Java后端开发的常用技术栈,而在SSH框架下实现多数据源支持,可以有效地处理来自不同数据库的数据,提高系统的灵活性和可扩展性。本文将详细介绍如何使用Spring 3的动态...

    webwork中文参考手册

    WebWork是一个开源的Java Web应用框架,主要用于构建企业级的Web应用程序。...此外,了解WebWork的进化历程和它如何与Struts2等其他框架融合也很有帮助,因为这能让你了解框架的发展趋势和技术选择的重要性。

    JAVA开源软件分类

    - **OSGi**:为Java平台定义了一个动态模块系统,Equinox 和 SpringDM 是其中两个实现。 - **SOA框架**:如Apache Tuscany,用于构建服务导向架构(SOA)应用。 - **P3:特定领域框架** - **Flex/Sliverlight**:...

    多媒体数据库技术.pdf

    - **Struts+Spring框架**:用于构建稳定、灵活的Web应用程序,提供良好的结构和组件。 - **XML与XSL**:XML用于数据交换和存储,XSL实现数据格式转换,可用于构建前后端分离的系统。 - **Flash与XML**:Flash通过...

Global site tag (gtag.js) - Google Analytics