1 准备开发工具

a) SpringSource Tool Suite 2.9.2.REALEASE:解压即可
http://download.springsource.com/release/STS/2.9.2/dist/e3.7/springsource-tool-suite-2.9.2.RELEASE-e3.7.2-win32-x86_64.zip

b) Virgo Tomcat Server 3.5.0.RELEASE:解压即可
http://eclipse.stu.edu.tw//virgo/release/VTS/3.5.0.RELEASE/virgo-tomcat-server-3.5.0.RELEASE.zip

c) Virgo插件:通过Update site安装
http://download.eclipse.org/virgo/milestone/tooling

2 运行SpringSource Tool Suite

a)  进入SpringSource安装目录/sts-2.9.2.RELEASE,点击STS.exe

3 创建Virgo Runtime

a) Window->Preferences->Server->Runtime Environment->add

b) 输入vi过滤,选中EclicpseRT下的Virgo Runtime,勾选Create a new local server,点击Next

c) 点击browse,选中Virgo Tomcat Server安装目录确定

4 管理Bundle依赖

a) 打开Server视图
Window->Show View->Server

b) 打开Server编辑器
在Server view中双击已创建好的Virgo Server

c) 进入Repository标签页
在Server编辑器下方点击Repository


d) 下载hibernate相关bundle
Repository标签页左上侧输入框输入antlr->点击search,勾选输入框下方搜索结果中的bundles:com.springsource.antlr,点击Repository标签页中间下方的download按钮,依次下载如下bundle
com.springsource.antlr-2.7.6.jar
com.springsource.com.mysql.jdbc-5.1.6.jar
com.springsource.javassist-3.3.0.ga.jar
com.springsource.net.sf.cglib-2.1.3.jar
com.springsource.org.apache.commons.collections-3.2.1.jar
com.springsource.org.apache.commons.dbcp-1.2.2.osgi.jar
com.springsource.org.apache.commons.pool-1.4.0.jar
com.springsource.org.dom4j-1.6.1.jar
com.springsource.org.hibernate.annotations.common-3.3.0.ga.jar
com.springsource.org.hibernate.annotations-3.4.0.GA.jar
com.springsource.org.hibernate-3.3.1.GA.jar
com.springsource.org.jgroups-2.5.1.jar

e) 查看下载完毕的bundle
下载的bundle存放在Virgo服务器安装目录/Repository/usr目录下,如果不可见,尝试点击右侧Refresh按钮或右下方Update the bundle and library index链接,Virgo服务器安装目录/Repository/ext目录下存放的是服务器自带的bundle

5 开发Bundle

5.1 com.dw.test.datasource

a) 创建bundle项目
File->new->project,输入bun过滤,选中Virgo下的bundle项目->next,输入com.dw.test.datasource->next,勾选Enable Bundle Classpath Container,Target runtime下拉框选择Virgo Runtime->finish

b) 导入依赖包
双击src/META-INF/MANIFEST.MF->点击下方dependencies标签页->在Import Package区域点击Add按钮->输入com.mysql.jdbc,点击OK。按此步骤依次导入以下依赖包
com.mysql.jdbc,javax.sql,org.apache.commons.dbcp

c) 定义Spring bean
src/META-INF/spring/appContext.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3    xmlns="http://www.springframework.org/schema/beans"
 4    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"
 5    xmlns:p="http://www.springframework.org/schema/p">
 6
 7    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
 8        p:driverClassName="com.mysql.jdbc.Driver"
 9        p:url="jdbc:mysql://localhost:3306/test?autoReconnect=true"
10        p:username="root" p:password="" init-method="createDataSource"
11        destroy-method="close" />
12
13</beans>


d) 定义Spring OSGi bean
src/META-INF/spring/osgiContext.xml

 1<?xml version="1.0" encoding="UTF-8"?>
 2<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 3    xmlns="http://www.springframework.org/schema/beans" xmlns:osgi="http://www.springframework.org/schema/osgi"
 4    xsi:schemaLocation="http://www.springframework.org/schema/beans
 5        http://www.springframework.org/schema/beans/spring-beans.xsd
 6        http://www.springframework.org/schema/osgi
 7        http://www.springframework.org/schema/osgi/spring-osgi.xsd">
 8
 9    <osgi:service ref="dataSource" interface="javax.sql.DataSource" />
10
11</beans>


5.2 com.dw.test.domain

a) 创建
bundle项目,名为com.dw.test.domain,参考5.1 a

b)
导入依赖包javax.persistence,javassist.util.proxy,org.hibernate.proxy,参考5.1 b

c) 创建并导出共享包
创建包com.dw.test.domain,打开src/META-INF/MANIFEST.MF编辑器->点击runtime标签页->在Exported Packages区域点击Add按钮->输入com.dw.test.domain,点击OK

d) 创建entity
src/com.dw.test.domain.User.java

 1package com.dw.test.domain;
 2
 3import java.io.Serializable;
 4
 5import javax.persistence.Basic;
 6import javax.persistence.Entity;
 7import javax.persistence.GeneratedValue;
 8import javax.persistence.GenerationType;
 9import javax.persistence.Id;
10import javax.persistence.Table;
11
12@Entity
13@Table(name = "user")
14public class User implements Serializable {
15
16    private static final long serialVersionUID = 1L;
17
18    @Id
19    @GeneratedValue(strategy = GenerationType.AUTO)
20    private Long id;
21    @Basic
22    private String username;
23    @Basic
24    private String password;
25
26    public Long getId() {
27        return id;
28    }

29
30    public void setId(Long id) {
31        this.id = id;
32    }

33
34    public String getUsername() {
35        return username;
36    }

37
38    public void setUsername(String username) {
39        this.username = username;
40    }

41
42    public String getPassword() {
43        return password;
44    }

45
46    public void setPassword(String password) {
47        this.password = password;
48    }

49
50}

51

5.3 com.dw.test.dao

a) 创建bundle项目,名为com.dw.test.dao,参考5.1 a

b) 引入项目com.dw.test.domain
右键项目->点击Properties->选中Project References->勾选com.dw.test.domain->点击OK

c) 导入依赖包com.dw.test.domain,参考5.1 b

d) 创建并导出共享包com.dw.test.dao,参考5.2 c

e) 创建IBaseDao基类接口
src/com.dw.test.dao.IBaseDao
 1package com.dw.test.dao;
 2
 3import java.io.Serializable;
 4
 5public interface IBaseDao<T> {
 6
 7    void save(T entity);
 8    
 9    void update(T entity);
10    
11    void delete(T entity);
12
13    T findById(Serializable id);
14
15}

f) 创建IUserDao业务接口
src/com.dw.test.dao.IUserDao
1package com.dw.test.dao;
2
3import com.dw.test.domain.User;
4
5
6public interface IUserDao extends IBaseDao<User>{
7
8}

5.4 com.dw.test.dao.impl

a) 创建bundle项目,名为com.dw.test.dao.impl,参考5.1 a

b) 引入项目com.dw.test.domain,com.dw.test.dao,参考5.3 b

c) 导入依赖包com.dw.test.domain,com.dw.test.dao,javax.sql,参考5.1 b

d) 导入Hibernate bundle
双击src/META-INF/MANIFEST.MF->点击下方dependencies标签页->在Import Bundle区域点击Add按钮->输入com.springsource.org.hibernate,点击OK。

e) 导入Spring库
双击src/META-INF/MANIFEST.MF->点击下方dependencies标签页->在Import Library区域点击Add按钮->输入org.springframework.spring,点击OK。

f) 实现IBaseDao接口
src/com.dw.test.dao.impl.BaseDaoImpl.java
 1package com.dw.test.dao.impl;
 2
 3import java.io.Serializable;
 4import java.lang.reflect.ParameterizedType;
 5import java.lang.reflect.Type;
 6
 7import org.springframework.orm.hibernate3.support.HibernateDaoSupport;
 8
 9import com.dw.test.dao.IBaseDao;
10
11public abstract class BaseDaoImpl<T> extends
12        HibernateDaoSupport implements IBaseDao<T> {
13
14    protected Class<T> entityclass;
15
16    public BaseDaoImpl() {
17        entityclass = getEntityClass();
18    }

19
20    @Override
21    public void save(T entity) {
22        getHibernateTemplate().save(entity);
23    }

24
25    @Override
26    public void update(T entity) {
27        getHibernateTemplate().update(entity);
28    }

29
30    @Override
31    public void delete(T entity) {
32        getHibernateTemplate().delete(entity);
33    }
;
34    
35    @Override
36    public T findById(Serializable id) {
37        T entity = getHibernateTemplate().get(entityclass, id);
38        return entity;
39    }

40
41    @SuppressWarnings("unchecked")
42    protected Class<T> getEntityClass() {
43        Type type = getClass().getGenericSuperclass();
44        Class<T> result = null;
45        if (type instanceof ParameterizedType) {
46            ParameterizedType parameterizedType = (ParameterizedType) type;
47            result = (Class<T>) parameterizedType.getActualTypeArguments()[0];
48        }

49        return result;
50    }

51
52}

g) 实现IUserDao接口
src/com.dw.test.dao.impl.UserDaoImpl.java
1package com.dw.test.dao.impl;
2
3import org.springframework.stereotype.Repository;
4
5import com.dw.test.dao.IUserDao;
6import com.dw.test.domain.User;
7
8
9@Repository("userDao")
10public class UserDaoImpl extends BaseDaoImpl<User> implements IUserDao{
11
12}

h) 定义Spring Bean
src/META-INF/spring/appContext.xml
1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
4 xsi:schemaLocation="http://www.springframework.org/schema/beans
5 http://www.springframework.org/schema/beans/spring-beans.xsd
6 http://www.springframework.org/schema/context
7 http://www.springframework.org/schema/context/spring-context.xsd" default-autowire="byName">
8
9 <context:annotation-config />
10
11 <context:component-scan base-package="com.dw.test" />
12
13 <bean id="sessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
14 <property name="dataSource" ref="dataSource" />
15 <property name="schemaUpdate" value="false" />
16 <property name="hibernateProperties">
17 <props>
18 <prop key="hibernate.dialect">
19 org.hibernate.dialect.MySQLDialect
20 </prop>
21 <prop key="hibernate.show_sql">true</prop>
22 <prop key="cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
23 </props>
24 </property>
25 <property name="annotatedClasses">
26 <list>
27 <value>com.dw.test.domain.User</value>
28 </list>
29 </property>
30 </bean>
31
32 <bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager">
33 <property name="sessionFactory" ref="sessionFactory" />
34 </bean>
35</beans>

i) 定义OSGi bean

src/META-INF/spring/osgiContext.xml
 1<?xml version="1.0" encoding="UTF-8"?>
 2<beans xmlns="http://www.springframework.org/schema/beans"
 3    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 5        http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi.xsd"
 6    xmlns:osgi="http://www.springframework.org/schema/osgi">
 7
 8    <osgi:reference id="dataSource" interface="javax.sql.DataSource" />
 9    
10    <osgi:service ref="sessionFactory" interface="org.hibernate.SessionFactory" />
11
12    <osgi:service ref="transactionManager" interface="org.springframework.transaction.PlatformTransactionManager" context-class-loader="service-provider" />
13
14    <osgi:service ref="userDao" interface="com.dw.test.dao.IUserDao" />
15
16</beans>

5.5 com.dw.test.service

a) 创建bundle项目,名为com.dw.test.service,参考5.1 a

b) 引入项目com.dw.test.domain,com.dw.test.dao,参考5.3 b

c) 导入依赖包com.dw.test.domain,com.dw.test.dao,参考5.1 b

d) 创建并导出共享包com.dw.test.service,参考5.2 c

e) 创建IBaseService类接口
src/com.dw.test.service.IBaseService
 1package com.dw.test.service;
 2
 3import java.io.Serializable;
 4
 5
 6public interface IBaseService<T> {
 7
 8    void create(T entity);
 9
10    void modify(T entity);
11
12    void remove(T entity);
13
14    T getById(Serializable id);
15    
16}

f) 创建IUserService业务接口
src/com.dw.test.service.IUserService
1package com.dw.test.service;
2
3import com.dw.test.domain.User;
4
5public interface IUserService extends IBaseService<User> {
6
7}

5.6 com.dw.test.service.impl
a) 创建bundle项目,名为com.dw.test.service.impl,参考5.1 a

b) 引入项目com.dw.test.domain,com.dw.test.dao,com.dw.test.service参考5.3 b

c) 导入依赖包,com.dw.test.dao,com.dw.test.domain,com.dw.test.service,org.aopalliance.aop,参考5.1 b

d) 导入Hibernate bundle,参考5.4 d

e) 导入Spring库,参考5.4 e

f) 实现IBaseService接口
src/com.dw.test.service.impl.BaseServiceImpl.java
 1package com.dw.test.service.impl;
 2
 3import java.io.Serializable;
 4
 5import com.dw.test.dao.IBaseDao;
 6import com.dw.test.service.IBaseService;
 7
 8public abstract class BaseServiceImpl<T> implements IBaseService<T>{
 9    
10    @Override
11    public void create(T entity) {
12        System.out.println(getBaseDao() == null);
13        getBaseDao().insert(entity);
14    }

15
16    @Override
17    public void modify(T entity) {
18        getBaseDao().update(entity);
19    }

20
21    @Override
22    public void remove(T entity) {
23        getBaseDao().delete(entity);
24    }

25
26    @Override
27    public T getById(Serializable id) {
28        return getBaseDao().findById(id);
29    }

30
31    protected abstract IBaseDao<T> getBaseDao();
32}

33

f) 实现IUserService接口
src/com.dw.test.service.impl.UserServiceImpl.java

 1
package com.dw.test.service.impl;
 2
 3import org.springframework.beans.factory.annotation.Autowired;
 4import org.springframework.stereotype.Service;
 5import org.springframework.transaction.annotation.Transactional;
 6
 7import com.dw.test.dao.IBaseDao;
 8import com.dw.test.dao.IUserDao;
 9import com.dw.test.domain.User;
10import com.dw.test.service.IUserService;
11
12@Service("userService")
13@Transactional
14public class UserServiceImpl extends BaseServiceImpl<User> implements
15        IUserService {
16
17    @Autowired
18    private IUserDao userDao;
19
20    @Override
21    public IBaseDao<User> getBaseDao() {
22        return userDao;    
23    }

24
25}

26

g) 定义Spring Bean
src/META-INF/spring/appContext.xml
 1<?xml version="1.0" encoding="UTF-8"?>
 2<beans xmlns="http://www.springframework.org/schema/beans"
 3    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
 4    xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
 5    xsi:schemaLocation="http://www.springframework.org/schema/beans
 6        http://www.springframework.org/schema/beans/spring-beans.xsd
 7        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
 8        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd
 9        http://www.springframework.org/schema/context
10        http://www.springframework.org/schema/context/spring-context.xsd">
11
12
13    <context:annotation-config />
14    
15    <context:component-scan base-package="com.dw.test" />
16
17    <tx:annotation-driven transaction-manager="transactionManager" />
18
19    <tx:advice id="txAdvice" transaction-manager="transactionManager">
20        <tx:attributes>
21            <tx:method name="search*" read-only="true" />
22            <tx:method name="*" rollback-for="Exception" />
23        </tx:attributes>
24    </tx:advice>
25    
26    <aop:config>
27        <aop:pointcut id="serviceCut" expression="execution(* com.dw.test..service..*.*(..))" />
28        <aop:advisor pointcut-ref="serviceCut" advice-ref="txAdvice" />
29    </aop:config>
30    
31    
32</beans>
33

h) 定义OSGi bean
src/META-INF/spring/osgiContext.xml
<?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:osgi="http://www.springframework.org/schema/osgi"
    xmlns:context
="http://www.springframework.org/schema/context"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/osgi
        http://www.springframework.org/schema/osgi/spring-osgi.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">


    
<osgi:reference id="userDao" interface="com.dw.test.dao.IUserDao" />
    
    
<osgi:reference id="transactionManager"    interface="org.springframework.transaction.PlatformTransactionManager" />

    
<osgi:service ref="userService" interface="com.dw.test.service.IUserService" />

</beans>


5.7 com.dw.test.web

a) 创建bundle项目,名为com.dw.test.web,参考5.1 a(创建过程中记得勾选Web Application Bundle,源码编译输出目录设置为WEB-INF/classes)

b) 引入项目com.dw.test.domain,com.dw.test.service,参考5.3 b

c) 导入依赖包,com.dw.test.domain,com.dw.test.service,org.eclipse.virgo.web.dm,org.slf4j,参考5.1 b

d) 导入Hibernate bundle,参考5.4 d

e) 导入Spring库,参考5.4

f) 创建控制器
src/com.dw.test.web.controller.UserController.java
 1package com.dw.test.web.controller;
 2
 3import javax.annotation.Resource;
 4
 5import org.slf4j.Logger;
 6import org.slf4j.LoggerFactory;
 7import org.springframework.stereotype.Controller;
 8import org.springframework.web.bind.annotation.RequestMapping;
 9
10import com.dw.test.domain.User;
11import com.dw.test.service.IUserService;
12
13@Controller
14@RequestMapping("/user")
15public class UserController {
16
17    Logger logger = LoggerFactory.getLogger(UserController.class);
18    
19    @Resource
20    private IUserService userService;
21    
22    @RequestMapping(value="/create")
23    public String create(){
24        logger.info("创建用户:");
25        User user = new User();
26        user.setUsername("osmos");
27        user.setPassword("123456");
28        userService.create(user);
29        return null;
30    }

31}

32

g) 定义web配置
WEB-INF/web.xml
1<?xml version="1.0" encoding="UTF-8"?>
2<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
4 xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
5 id="WebApp_ID" version="2.5">
6
7 <display-name>test</display-name>
8
9 <context-param>
10 <param-name>webAppRootKey</param-name>
11 <param-value>test.root</param-value>
12 </context-param>
13
14
15 <context-param>
16 <param-name>contextClass</param-name>
17 <param-value>org.eclipse.virgo.web.dm.ServerOsgiBundleXmlWebApplicationContext</param-value>
18 </context-param>
19 <listener>
20 <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
21 </listener>
22
23
24 <servlet>
25 <servlet-name>app</servlet-name>
26 <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
27 </servlet>
28 <servlet-mapping>
29 <servlet-name>app</servlet-name>
30 <url-pattern>/</url-pattern>
31 </servlet-mapping>
32
33</web-app>

h) 定义Spring MVC配置
WEB-INF/app-servlet.xml
1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
4 xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
5 xmlns:util="http://www.springframework.org/schema/util" xmlns:mvc="http://www.springframework.org/schema/mvc"
6 xmlns:tx="http://www.springframework.org/schema/tx"
7 xsi:schemaLocation="
8 http://www.springframework.org/schema/beans
9 http://www.springframework.org/schema/beans/spring-beans.xsd
10 http://www.springframework.org/schema/context
11 http://www.springframework.org/schema/context/spring-context.xsd
12 http://www.springframework.org/schema/aop
13 http://www.springframework.org/schema/aop/spring-aop.xsd
14 http://www.springframework.org/schema/tx
15 http://www.springframework.org/schema/tx/spring-tx.xsd
16 http://www.springframework.org/schema/util
17 http://www.springframework.org/schema/util/spring-util.xsd
18 http://www.springframework.org/schema/mvc
19 http://www.springframework.org/schema/mvc/spring-mvc.xsd">
20
21 <context:component-scan base-package="com.dw.test" />
22
23 <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
24
25 <mvc:interceptors>
26 <bean id="openSessionInViewInterceptor"    class="org.springframework.orm.hibernate3.support.OpenSessionInViewInterceptor">
27 <property name="sessionFactory" ref="sessionFactory" />
28 </bean>
29 </mvc:interceptors>
30
31 <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
32 <property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
33 <property name="prefix" value="/WEB-INF/views/" />
34 <property name="suffix" value=".jsp" />
35 </bean>
36
37</beans>
38

i) 定义服务引用
WEB-INF/applicationContext.xml
1<?xml version="1.0" encoding="UTF-8"?>
2<beans xmlns="http://www.springframework.org/schema/beans"
3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:osgi="http://www.springframework.org/schema/osgi"
4 xmlns:context="http://www.springframework.org/schema/context"
5 xsi:schemaLocation="http://www.springframework.org/schema/beans
6 http://www.springframework.org/schema/beans/spring-beans.xsd
7 http://www.springframework.org/schema/osgi
8 http://www.springframework.org/schema/osgi/spring-osgi.xsd
9 http://www.springframework.org/schema/context
10 http://www.springframework.org/schema/context/spring-context.xsd">
11
12 <osgi:reference id="sessionFactory" interface="org.hibernate.SessionFactory" />
13
14 <osgi:reference id="userService" interface="com.dw.test.service.IUserService"/>
15
16</beans>
17
18

j) 注意事项
com.dw.test.web项目的MANIFEST.MF文件内容有如下头信息,否则会有无法访问以及注解无效等问题
Web-ContextPath: /test
Bundle-ClassPath: WEB-INF/classes