OSGI企业应用开发(十四)整合Spring、Mybatis、Spring MVC
来源:互联网 发布:淘宝开网店用18 编辑:程序博客网 时间:2024/06/06 00:45
作为一个企业级的Web应用,MVC框架是必不可少的。Spring MVC目前使用也比较广泛,本文就来介绍一下如何在OSGI应用中实现Spring、Mybatis、Spring MVC框架的整合,其中Spring MVC的整合比较困难,原因是Spring整合到OSGI中后,每个Bundle都拥有一个孤立的ApplicationContext,也就是说不同Bundle中实例化的Bean之间的依赖注入就存在一定的问题,前面文章中提到过,这个问题可以通过Bean的注册和引用机制解决。
而实例化Spring MVC框架中的org.springframework.web.servlet.DispatcherServlet类时也需要指定Bean的配置文件,Spring MVC框架启动后会实例化配置文件中的Bean(例如Controller实例),Spring MVC框架启动后实例化的Bean与Bundle中实例化的Bean属于不同的类加载器,所以Bundle中实例化的Bean无法注入到Spring MVC框架启动时实例化的Bean,比较直接的例子就是Mybatis操作数据库的SqlSession实例无法注入到Spring MVC的Controller中,网上比较多的解决方案是使用Virgo,笔者经过一番钻研,解决了Spring MVC框架与OSGI应用的整合,如果发现有什么问题,可以一起探讨下^_^。
接下来就介绍OSGI应用中Spring、Mybatis、Spring MVC框架的整合,我们依然使用前面文章中已经搭建好的工作空间。
首先新建一个Bundle,名称为com.csdn.osgi.user.web,整个工作空间结构如下图所示:
由于OSGI应用中资源与Servlet都需要注册后才能被客户端访问,我们可以编写几个类专门用于注册Web资源。
首先是图片、CSS、JS等静态资源的注册,在com.csdn.osgi.user.web这个Bundle中新建一个类,名称为com.csdn.osgi.user.web.registry.ResourceRegistry,代码如下:
package com.csdn.osgi.user.web.registry;import java.util.Iterator;import java.util.Map;import java.util.Set;import org.eclipse.gemini.blueprint.context.BundleContextAware;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceReference;import org.osgi.service.http.HttpContext;import org.osgi.service.http.HttpService;import org.osgi.service.http.NamespaceException;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class ResourceRegistry implements ApplicationContextAware, BundleContextAware { Map resMapping; BundleContext bundleContext; ApplicationContext applicationContext; @Override public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void setResMapping(Map resMapping) { this.resMapping = resMapping; } public void init() { ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName()); HttpService httpService = (HttpService) bundleContext.getService(serviceReference); HttpContext commonContext = httpService.createDefaultHttpContext(); try { Set keySet = resMapping.keySet(); Iterator<String> it = keySet.iterator(); while(it.hasNext()){ String key = it.next(); String value = (String) resMapping.get(key); httpService.registerResources(key, value, commonContext); } } catch (NamespaceException e) { e.printStackTrace(); } }}
我们可以通过Spring来实例化这个类,Bean的配置如下:
<bean name="resourceRegistry" class="com.csdn.osgi.user.web.registry.ResourceRegistry" init-method="init"> <property name="resMapping"> <map> <entry key="/js" value="/WebContent/js"/> <entry key="/css" value="/WebContent/css"/> <entry key="/images" value="/WebContent/images"/> </map> </property> </bean>
这样就可以完成静态资源的注册,这种方式比较灵活,如果有新的资源类型,只需要在map标签中增加一个新的entry标签即可。
接下来是JSP的注册,我们在com.csdn.osgi.user.web这个Bundle中新建一个类,名称为 com.csdn.osgi.user.web.registry.JspRegistry,代码如下:
package com.csdn.osgi.user.web.registry;import java.util.Dictionary;import java.util.Hashtable;import javax.servlet.ServletException;import org.eclipse.equinox.jsp.jasper.JspServlet;import org.eclipse.gemini.blueprint.context.BundleContextAware;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceReference;import org.osgi.service.http.HttpContext;import org.osgi.service.http.HttpService;import org.osgi.service.http.NamespaceException;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;public class JspRegistry implements ApplicationContextAware, BundleContextAware { BundleContext bundleContext; ApplicationContext appContext; @Override public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } @Override public void setApplicationContext(ApplicationContext appContext) throws BeansException { this.appContext = appContext; } public void init() { ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName()); HttpService httpService = (HttpService) bundleContext.getService(serviceReference); HttpContext commonContext = httpService.createDefaultHttpContext(); Dictionary initparams = new Hashtable<String, String>(); JspServlet jspServlet = new JspServlet(bundleContext.getBundle(), "/WebContent/WEB-INF/jsp", "/jsp"); try { httpService.registerServlet("/jsp", jspServlet, initparams, commonContext); } catch (ServletException e) { e.printStackTrace(); } catch (NamespaceException e) { e.printStackTrace(); } }}
同样,也是在Spring中实例化JspRegistry,Bean的配置如下:
<bean name="jspRegistry" class="com.csdn.osgi.user.web.registry.JspRegistry" init-method="init"></bean>
最后就是Servlet资源的注册了,使用Spring MVC框架,我们需要实例化一个DispatcherServlet对象,需要注意的是,DispatcherServlet对象不能通过new关键字创建,应该由Spring框架实例化,在com.csdn.osgi.user.web这个Bundle中新建一个类,名称为com.csdn.osgi.user.web.registry.DispatcherServletRegistry,代码如下:
package com.csdn.osgi.user.web.registry;import java.util.Dictionary;import java.util.Hashtable;import javax.servlet.ServletException;import org.eclipse.gemini.blueprint.context.BundleContextAware;import org.osgi.framework.BundleContext;import org.osgi.framework.ServiceReference;import org.osgi.service.http.HttpContext;import org.osgi.service.http.HttpService;import org.osgi.service.http.NamespaceException;import org.springframework.beans.BeansException;import org.springframework.context.ApplicationContext;import org.springframework.context.ApplicationContextAware;import org.springframework.web.servlet.DispatcherServlet;public class DispatcherServletRegistry implements ApplicationContextAware, BundleContextAware { String urlPattern; String servletName; BundleContext bundleContext; ApplicationContext applicationContext; DispatcherServlet dispatcherServlet; @Override public void setBundleContext(BundleContext bundleContext) { this.bundleContext = bundleContext; } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public void setServletName(String servletName) { this.servletName = servletName; } public void setUrlPattern(String urlPattern) { this.urlPattern = urlPattern; } public void setDispatcherServlet(DispatcherServlet dispatcherServlet) { this.dispatcherServlet = dispatcherServlet; } public void init() { ServiceReference serviceReference = bundleContext.getServiceReference(HttpService.class.getName()); HttpService httpService = (HttpService) bundleContext.getService(serviceReference); HttpContext commonContext = httpService.createDefaultHttpContext(); Dictionary<String, String> initparams = new Hashtable<String, String>(); initparams.put("load-on-startup", "1"); initparams.put("servlet-name", servletName); try { httpService.registerServlet(urlPattern, dispatcherServlet, initparams, commonContext); } catch (ServletException e) { e.printStackTrace(); } catch (NamespaceException e) { e.printStackTrace(); } }}
DispatcherServletRegistry 类的实例化也是通过Spring来完成,Bean的配置如下:
<bean name="dispatcherServlet" class="org.springframework.web.servlet.DispatcherServlet"> <property name="contextConfigLocation"> <value>/META-INF/spring/*.xml</value> </property> </bean> <bean name="servletRegistry" class="com.csdn.osgi.user.web.registry.DispatcherServletRegistry" init-method="init"> <property name="urlPattern" value="/*.do"></property> <property name="servletName" value="dispatcherServlet"></property> <property name="dispatcherServlet" ref="dispatcherServlet"></property> </bean>
接下来在com.csdn.osgi.user.web这个Bundle中,新建META-INF/spring/registry.xml文件,用于配置注册Web资源的Bean,内容如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgix="http://www.springframework.org/schema/osgi-compendium" xmlns:ctx="http://www.springframework.org/schema/context" xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd http://www.eclipse.org/gemini/blueprint/schema/blueprint http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd"> <bean name="dispatcherServlet" class="org.springframework.web.servlet.DispatcherServlet"> <property name="contextConfigLocation"> <value>/META-INF/spring/*.xml</value> </property> </bean> <bean name="servletRegistry" class="com.csdn.osgi.user.web.registry.DispatcherServletRegistry" init-method="init"> <property name="urlPattern" value="/*.do"></property> <property name="servletName" value="dispatcherServlet"></property> <property name="dispatcherServlet" ref="dispatcherServlet"></property> </bean> <bean name="resourceRegistry" class="com.csdn.osgi.user.web.registry.ResourceRegistry" init-method="init"> <property name="resMapping"> <map> <entry key="/js" value="/WebContent/js"/> <entry key="/css" value="/WebContent/css"/> <entry key="/images" value="/WebContent/images"/> </map> </property> </bean> <bean name="jspRegistry" class="com.csdn.osgi.user.web.registry.JspRegistry" init-method="init"> </bean></beans>
然后新建一个META-INF/spring/dmconfig.xml文件,用于引用其他Bundle中注册的Bean,内容如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgix="http://www.springframework.org/schema/osgi-compendium" xmlns:ctx="http://www.springframework.org/schema/context" xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd http://www.eclipse.org/gemini/blueprint/schema/blueprint http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd"> <osgi:reference id="sqlMapService" interface="org.apache.ibatis.session.SqlSession" /></beans>
然后还需要新建一个META-INF/spring/controllers.xml文件,实例化Spring MVC中的Controller及ViewResolver等,配置如下:
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgix="http://www.springframework.org/schema/osgi-compendium" xmlns:ctx="http://www.springframework.org/schema/context" xmlns:osgi="http://www.eclipse.org/gemini/blueprint/schema/blueprint" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/osgi-compendium http://www.springframework.org/schema/osgi-compendium/spring-osgi-compendium.xsd http://www.eclipse.org/gemini/blueprint/schema/blueprint http://www.eclipse.org/gemini/blueprint/schema/blueprint/gemini-blueprint.xsd"> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="jsp/"/> <property name="suffix" value=".jsp"/> </bean> <bean name="/test.do" class="com.csdn.osgi.web.controllers.TestController"> </bean></beans>
上面配置中,我们实例化了一个TestController对象,用于测试Spring MVC框架是否整合成功,TestController代码如下:
package com.csdn.osgi.web.controllers;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpServletResponse;import org.springframework.web.servlet.ModelAndView;import org.springframework.web.servlet.mvc.Controller;public class TestController implements Controller{ @Override public ModelAndView handleRequest(HttpServletRequest req, HttpServletResponse resp) throws Exception { System.out.println("Test Controller"); ModelAndView mv = new ModelAndView(); mv.setViewName("test"); return mv; }}
接下来还需要增加一个WebContent/WEB-INF/jsp/test.jsp页面,代码如下:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%><!DOCTYPE html><html><head><title>Spring MVC测试页面</title></head><body><h1>这是Spring MVC测试页面!</h1></body></html>
到此为止Spring MVC框架已经整合完毕,同时我们实例化了一个用于测试的TestController对象,整个工程结构如下图所示:
最后,启动OSGI容器,打开浏览器,访问http://localhost:8080/test.do,如下图所示:
可以发现Spring MVC已经成功整合到OSGI应用中,下篇文章,笔者带领大家基于Spring、Mybatis、Spring MVC实现一个简单的登录功能。
注意:不需要启动前面文章演示使用的com.csdn.osgi.test.web这个Bundle,否则JSP注册时指定的URL会有冲突。
本文源码地址:http://download.csdn.net/detail/rongbo_j/9753640
转载请注明原文地址:http://blog.csdn.net/Rongbo_J/article/details/55000418
- OSGI企业应用开发(十四)整合Spring、Mybatis、Spring MVC
- OSGI企业应用开发(十五)基于Spring、Mybatis、Spring MVC实现一个登录应用
- OSGI企业应用开发(八)整合Spring和Mybatis框架(一)
- OSGI企业应用开发(九)整合Spring和Mybatis框架(二)
- OSGI企业应用开发(十)整合Spring和Mybatis框架(三)
- OSGI企业应用开发(八)整合Spring和Mybatis框架(一)
- OSGI企业应用开发(九)整合Spring和Mybatis框架(二)
- OSGI企业应用开发(十)整合Spring和Mybatis框架(三)
- OSGI企业应用开发(四)使用Blueprint整合Spring框架(一)
- OSGI企业应用开发(五)使用Blueprint整合Spring框架(二)
- OSGI企业应用开发(四)使用Blueprint整合Spring框架(一)
- OSGI企业应用开发(五)使用Blueprint整合Spring框架(二)
- MyBatis+Spring+Spring MVC整合开发
- Spring MVC、Spring、MyBatis、Maven整合开发
- Spring+Spring MVC+MyBatis(SSM)整合
- (spring mvc+spring+Mybatis)框架整合
- Spring MVC Mybatis 整合
- spring mvc mybatis 整合
- 242. Valid Anagram
- hadoop2.x单机搭建分布式集群超详细教程
- 瀑布流无法用<c:forEach>循环遍历
- 分布式多爬虫系统——架构设计
- Spring mvc:annotation-driven
- OSGI企业应用开发(十四)整合Spring、Mybatis、Spring MVC
- C语言------栈的初体验(数组实现)
- 为ubuntu添加有道词典翻译
- cxf Webservice
- 深入理解RunLoop
- 1039. Course List for Student (25)
- JsGrid入门教程及离线文档
- Hibernate一对多级联操作
- Docker学习笔记七:Docker网络