- 浏览: 8216 次
- 性别:
- 来自: 上海
最新评论
-
zdh:
楼主,你所说的tuscany1.6 Eclipse Plugi ...
SCA(Tascany)环境搭建和使用范例 -
zyp731:
全是代码,没啥内涵~
SCA(Tascany)+Spring+Hibernate开发与使用范例 -
hamlzf:
寻找很久了
SCA(Tascany)+Spring+Hibernate开发与使用范例 -
hamlzf:
入门文章,可以试试!
SCA(Tascany)环境搭建和使用范例
1. 概述
本文档描述了基于Eclipse3.5和Apache Tascany基础之上的Spring快速入门的使用范例。感兴趣的朋友MSN:huangyungang@hotmail.com交流,也可mail说明。
本文将着手了解或解决如下内容:
Spring 开发 SCA 组件时需要掌握的一些基本设计原则。
如何将 Spring beans 公开为 SCA 服务,
如何在 Spring 应用程序中访问 SCA 服务和属性。
如何使用 Spring Framework 和 Apache Tuscany SCA Java 运行时来设计和开发 SCA 组件。。
如何结合 SCA 与 Spring 来创建分布式服务应用程序。
2. 开发环境
2.1. 环境准备
为了在实践中完成下面文中描述的内容,您需要以下工具:
表1-开发环境要素
2.2. 环境搭建(参考SCA(Tascany)环境搭建和使用范例)
3. SCA 与 Spring 两者相结合的优势
Spring Framework 与 SCA 采用许多相同的设计原则。SCA 将 Spring 视为其组件的一种实现技术。SCA Sprig Component Implementation Specification 定义了如何采用这种方式来使用 Spring。
与 Spring bean 类似,SCA 组件可以包含到其他组件所提供的服务的引用,并且有一些属性可供配置。
与 Spring 形成对比的是,SCA 是一种跨语言的分布式组件架构,它支持多种组件通信机制。通过将 Spring beans 发布为可由其他组件访问的服务并为 Spring beans 提供关联到其他(可能为远程)组件的服务的引用,SCA 可以扩展 Spring 组件的功能。
4. SCA与Spring 结合的原则
要将 SCA 与 Spring 相结合,一种有效的方法是使用 Spring 来构建 “粗粒度” 的服务组件实现,并引入到 SCA 中以便公开服务、关联服务组件以及处理异构和分布式系统。SCA 可以在使用 Spring 实现的应用程序中添加一些有用的功能,比如说:
对远程组件以及多种协议的扩展支持
支持使用不受 JVM 支持的各种编程语言来编写组件
支持 WS-Policy 针对安全性和事务等活动指定的策略
易于测试组件是 Spring 的一项优异的特性。
缺少 API 和注入技术导致您只能使用简单的模拟对象进行测试。SCA 在服务方面对此进行了补充,因为关于服务组件的 SCA 复合集可以方便地切换到模拟配置以进行测试。
5. Tuscany SCA与Spring结合的步骤
5.1. 将 Spring 应用程序定义为 SCA 组件
创建一个包含一个 Spring 组件的 SCA 复合集
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
targetNamespace="http://calc"
xmlns:c="http://calc"
name="Calculator">
<component name="CalculatorServiceComponent">
<implementation.spring location="targetURI"/>
</component>
</composite>
其中:
<implementation.spring> 元素的位置属性可以指定目标 URI 指向某个存档文件 (.jar) 或 目标,或者 直接指向 Spring 应用程序上下文。
以下列表给出了指定 <implementation.spring> 位置属性的目标 URI 的可能方法。
一个 Spring 应用程序可被定义为 SCA 复合集(即 SCDL:SCDL is used to describe SCA elements such as modules, references, imports, and exports)内的一个 SCA 组件。其形式如下图所示:
其中<implementation.spring>用于指定实现component的Spring bean配置文件。而location则指定的bean文件的位置或目录(关于目录下面的示例中包含)。
6. 示例程序(WebService+SCA+Spring+Hibernate)
下面我们来开发一个示例程序。在本示例中,您将看到如何利用SCA集成现有的Spring组件,并对其进行向外发布。
6.1. 创建工程
首先我们在d:\TuscanyWorkspace\工作区下,创建一个名为SpringDemo “Dynamic Web Project”的工程。加载TuscanyLibrary(在开发环境建立一文中已经指出)。并将apache-tuscany-sca-1.6.zip的lib目录中的.jar文件COPY到工程的lib目录中。
以上是一个Java Application中对OSOA包的使用。当然对于Java Web Application需要将这些包加到Web Application的lib目录下。同时本示例还需要将hibernate和c3p0的JAR包加入到lib目录下。
6.2. 代码
下面的我们要实现的是基于Apache Tomcat来发布一个tuscany的SCA组件。
程序代码的包结构如下图所示:
图6-示例程序的包结构
6.2.1. 创建基于Hibernate的数据访问程序
6.2.1.1. 创建Hibernate工具类—HibernateUtil.java
此类主要用于实现对数据库的CRUD基本操作,需要注意的是hibernate.cfg.xml文件是通过注入的方式来实现的。
package net.jite.waf.persistent.util;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
/**
* desc: Hibernate的通用类 <br/>
* 用于对Hibernate SessionFactory的初始化以及Hibernate Session的管理
* @author <a href="mailto:huangyungang@hotmail.com">huangyungang </a>
*
*/
public class HibernateUtil {
private SessionFactory _sf;
private static final ThreadLocal session = new ThreadLocal();
private String configFile;
/**
* 设置默认的配置文件名
*
* @param cfgFile
*/
public void setConfigFile(String cfgFile){
configFile=cfgFile;
}
/**
* 初始化此对象
*
*/
public void init(){
try {
Configuration config = new Configuration().configure(configFile);
if ("true".equals(config.getProperty("createtable"))) {
new SchemaExport(config).create(true, true);
}
if ("true".equals(config.getProperty("updatetable"))) {
new SchemaUpdate(config).execute(true, true);
}
_sf = config.buildSessionFactory();
} catch (HibernateException e) {
throw new RuntimeException("初始化Hibernate SessionFactory失败", e);
}
}
/**
* 获取一个Session
* @return Session
* @throws HibernateException
*/
public Session currentSession() throws HibernateException {
Session s = (Session) session.get();
if (s == null) {
s = _sf.openSession();
session.set(s);
}
return s;
}
/**
* 关闭Session
*
* @throws Exception
*/
public void closeSession() throws HibernateException {
Session s = (Session) session.get();
if (s != null)
s.close();
session.set(null);
}
}
6.2.1.2. 创建一个CommonDao类
CommonDao实现了基本的数据访问操作,这里的CommonDao可以被Service层去调用。代码如下:
import java.io.Serializable;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import user.util.HibernateUtil;
public class CommonDao {
private Session _session;
private HibernateUtil util;
public Session get_session() {
return _session;
}
public void set_session(Session session) {
_session = session;
}
public HibernateUtil getUtil() {
return util;
}
private boolean isOSIV;
//***********************增加的内容********************************
/**
* 根据主键ID删除obj
*
* @throws Exception
* 删除时出错则抛出
*/
public void deleteById(Class po, String id) throws Exception {
// Object obj = getById(po, id);
// delete(obj);
_session=getSession();
Transaction tx = _session.beginTransaction();
try
{
_session.delete(_session.get(po,id));
tx.commit();
}
catch (HibernateException e) {
// 在目前的HRibernate版本中当无对应的id的主键记录存在时抛出的异常
tx.rollback();
} finally {
closeSession();
}
}
/**
*
* desc:新添加的方法,用于匹配CMS数据库中的字符串主键
* @author huangyg
*
**/
public Object getById(Class po,String id) throws Exception {
_session = getSession();
try {
//return _session.load(po,id);
return _session.get(po, id);
} catch (HibernateException e) {
// 在目前的Hibernate版本中当无对应的id的主键记录存在时抛出的异常
return null;
} finally {
closeSession();
}
}
//***************************end*************************************
//***************************************************************
/**
* 设置获取Hibernate Session的通用类
*/
public void setUtil(HibernateUtil util) {
this.util = util;
}
/**
* 持久化obj
*
* @throws Exception
* 持久化过程时出错则抛出
*/
public void save(Object obj) throws Exception {
_session = getSession();
Transaction tx = _session.beginTransaction();
try {
_session.save(obj);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
// log.error("Hibernate进行持久化Object时错误", e);
throw new Exception("Hibernate进行持久化Object时错误");
} finally {
closeSession();
}
}
/**
* 更新obj
*
* @throws Exception
* 更新时出错则抛出
*/
public void update(Object obj) throws Exception {
_session = getSession();
Transaction tx = _session.beginTransaction();
try {
_session.update(obj);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
// log.error("Hibernate更新Object时错误", e);
throw new Exception("Hibernate更新Object时错误");
} finally {
closeSession();
}
}
/**
* 删除obj
*
* @throws Exception
* 删除时出错则抛出
*/
public void delete(Object obj) throws Exception {
_session = getSession();
Transaction tx = _session.beginTransaction();
try {
_session.delete(obj);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
// log.error("Hibernate删除Object时错误", e);
throw new Exception("Hibernate删除Object时错误");
} finally {
closeSession();
}
}
/**
* 根据主键ID删除obj
*
* @throws Exception
* 删除时出错则抛出
*/
public void deleteById(Class po, int id) throws Exception {
Object obj = getById(po, new Integer(id));
delete(obj);
}
/**
* 清空某po所有的数据 强烈建议尽量不要使用此方法,一般来说不要物理删除数据,置状态比较合适
*
* @param po
* @throws Exception
*/
public void deleteAll(Class po) throws Exception {
_session = getSession();
Transaction tx = _session.beginTransaction();
try {
_session.createQuery("delete from " + po.getName()).executeUpdate();
tx.commit();
} catch (HibernateException e) {
tx.rollback();
// log.error("Hibernate清空PO中数据时错误", e);
throw new Exception( "Hibernate清空PO中数据时错误");
} finally {
closeSession();
}
}
/**
* 根据为int型的主键ID获取对应的Object
*
* @param obj
* @param id
* @return Object
* @throws Exception
*/
public Object getById(Object obj, int id) throws Exception {
return getById(obj.getClass(), new Integer(id));
}
/**
* 根据主键ID获取对应的Object
*
* @param obj
* @param id
* @return Object
* @throws Exception
*/
public Object getById(Object obj, Serializable id) throws Exception {
return getById(obj.getClass(), id);
}
/**
* 根据为int型的主键ID获取对应的Object
*
* @param obj
* @param id
* @return Object
* @throws Exception
*/
public Object getById(Class po, int id) throws Exception {
return getById(po, new Integer(id));
}
/**
* 根据主键ID获取对应的Object
*
* @param obj
* @param id
* @return Object
* @throws Exception
*/
public Object getById(Class po, Serializable id) throws Exception {
_session = getSession();
try {
return _session.get(po, id);
} catch (HibernateException e) {
// 在目前的Hibernate版本中当无对应的id的主键记录存在时抛出的异常
return null;
} finally {
closeSession();
}
}
// For Business Method
/**
* 根据需执行的hql返回List <br>
* 建议对于数据量小或一次进行频繁查询的使用
*
* @param hql
* @return java.util.List
* @throws Exception
*/
public List getListByHql(String hql) throws Exception {
return null;
}
/**
* 获取Session
*
* @throws Exception
*/
public Session getSession() {
return util.currentSession();
}
/**
* 关闭Session
*
* @throws Exception
*/
public void closeSession() {
// Use Open Session In View,so we don't close session
if (!isOSIV) {
util.closeSession();
}
}
// ============================== get/set
public void setOSIV(boolean isOSIV) {
this.isOSIV = isOSIV;
}
}
6.2.1.3. 创建一个POJO类和Hibernate的.hbm.xml映射文件
POJO类代码如下:
package user.domain;
public class User {
private Integer id;
private String username;
private String password;
private int sex;
private String address;
public String toString(){
return null;
}
public Integer getId(){
return this.id;
}
public void setId(Integer id){
this.id=id;
}
public String getUsername(){
return this.username;
}
public void setUsername(String username){
this.username=username;
}
public String getPassword(){
return this.password;
}
public void setPassword(String password){
this.password=password;
}
public void setSex(int sex){
this.sex=sex;
}
public int getSex(){
return this.sex;
}
public void setAddress(String address){
this.address=address;
}
public String getAddress(){
return this.address;
}
}
User.hbm.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="user.domain.User"
table="userinfo"
>
<id
name="id"
column="ID"
type="java.lang.Integer"
length="10"
unsaved-value="0"
>
<generator class="increment" />
</id>
<property
name="username"
type="java.lang.String"
update="true"
insert="true"
column="username"
not-null="false"
unique="false"
/>
<property
name="password"
type="java.lang.String"
update="true"
insert="true"
column="password"
not-null="false"
unique="false"
/>
<property
name="address"
type="java.lang.String"
update="true"
insert="true"
column="address"
not-null="false"
unique="false"
/>
</class>
</hibernate-mapping>
6.2.1.4. 创建hibernate.cfg.xml文件
hibernate.cfg.xml内容如下:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/soademo?useUnicode=true&
characterEncoding=GBK</property>
<property name="connection.username">root</property>
<property name="connection.password">admin</property>
<!-- org.hibernate.dialect.OracleDialect -->
<!-- org.hibernate.dialect.MySQLDialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="jdbc.fetch_size">50</property>
<property name="show_sql">true</property>
<property name="createtable">false</property>
<property name="updatetable">true</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.max_statements">100</property>
<property name="c3p0.idle_test_period">5000</property>
<!--浮标管理-->
<mapping resource="user/domain/User.hbm.xml" />
<!--缓存配置-->
</session-factory>
</hibernate-configuration>
6.2.2. 创建基于SCA容器并集成Spring的Composite
6.2.2.1. 在web.xml中添加tuscany过滤器
<filter>
<filter-name>tuscany</filter-name>
<filter-class>org.apache.tuscany.sca.host.webapp.TuscanyServletFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>tuscany</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
需要注意的是,这里不需要添加Spring ContextLoaderListener,SCA具备自已独立的容器,直接访问Spring容器内部的Beans比较困难,因为它们不在同一容器内。下面的代码我们是不需要加到web.xml文件中的。
<!--
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
-->
6.2.2.2. 创建Spring Bean配置
Spring bean的配置共包括三部分内容:
Bean的自身定义
供外部调用Service定义
聚合其它Service的引用定义
在WebContent/spring-context目录下创建beans-user.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:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/sca http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd"
>
<sca:service name="UserService"
type="user.service.UserService"
target="userServiceBean"/>
<bean id="userServiceBean" class="user.service.UserServiceImpl">
<property name="dao" ref="CommonDaoService"/>
</bean>
<sca:reference name="CommonDaoService" type="user.dao.CommonDao" ></sca:reference>
</beans>
创建beans-commondao.xml,内容如下:
<?xml version="1.0" encoding="gbk"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/sca http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd"
>
<!--Bean对外提供 -->
<sca:service name="CommonDaoService"
type="user.dao.CommonDao"
target="commonDaoBean"/>
<!--Bean自身定义 -->
<bean id="commonDaoBean" class="user.dao.CommonDao">
<property name="util" ref="HibernateUtilService"></property>
</bean>
<!--Bean引用别的 -->
<sca:reference name="HibernateUtilService" type="user.util.HibernateUtil" ></sca:reference>
</beans>
创建beans-hibernate-util.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:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/sca http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd"
>
<sca:service name="HibernateUtilService"
type="user.util.HibernateUtil"
target="HibernateUtilBean"/>
<bean id="HibernateUtilBean" class="user.util.HibernateUtil" init-method="init">
<property name="configFile" value="/hibernate.cfg.xml"/>
</bean>
</beans>
6.2.2.3. 创建SCA包装
User.composite文件
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
xmlns:c="http://User"
targetNamespace="http://User"
name="User">
<service name="UserService" promote="UserServiceComponent">
<binding.ws></binding.ws>
</service>
<component name="UserServiceComponent">
<implementation.spring location="spring-context/beans-user.xml"/>
<reference name="CommonDaoService" target="CommonDaoServiceComponent"></reference>
</component>
</composite>
其中:
spring-context/beans-user.xml的完全路径是WebContent/Spring-context/beans-user.xml
此处使用<binding.ws></binding.ws>将UserService发布成了一个WebService
Component的引用关系注意描述,由于UserService中需要使用CommonDao的内容,在SCA的Component层面也需要进行定义。例如<reference name="CommonDaoService" target=
"CommonDaoServiceComponent"></reference>。
CommonDao.composite
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
xmlns:c="http://User"
targetNamespace="http://User"
name="CommonDao">
<service name="CommonDaoService" promote="CommonDaoServiceComponent">
</service>
<component name="CommonDaoServiceComponent">
<implementation.spring location="spring-context/beans-commondao.xml"/>
<reference name="HibernateUtilService" target="HibernateUtilServiceComponent"></reference>
</component>
</composite>
HibernateUtil.composite
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
xmlns:c="http://User"
targetNamespace="http://User"
name="HibernateUtil">
<service name="HibernateUtilService" promote="HibernateUtilServiceComponent">
</service>
<component name="HibernateUtilServiceComponent">
<implementation.spring location="spring-context/beans-hibernate-util.xml"/>
</component>
</composite>
6.2.2.4. 创建MySQL数据表
在本机的MySQL数据库soademo中,建一张userinfo表。
/*
Navicat MySQL Data Transfer
Source Host : localhost:3306
Source Database : soademo
Target Host : localhost:3306
Target Database : soademo
Date: 2010-04-19 17:35:13
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for userinfo
-- ----------------------------
DROP TABLE IF EXISTS `userinfo`;
CREATE TABLE `userinfo` (
`id` int(11) NOT NULL default '0',
`username` varchar(200) default NULL,
`password` varchar(100) default NULL,
`sex` int(2) default NULL,
`address` varchar(200) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of userinfo
-- ----------------------------
INSERT INTO `userinfo` VALUES ('1', '1', '1', null, '1');
6.2.3. 执行情况
在SOAPUI工具中调用已经发布的WebService,运行http://localhost:8080/springdemo/UserService?wsdl得到如下结果:
SOAPUI调用情况如下(SOAPUI工具可从网络中下载):
Tomcat结果如下图所示:
最终显示Hibernate完成了向MySQL数据库添加一行记录。
本文档描述了基于Eclipse3.5和Apache Tascany基础之上的Spring快速入门的使用范例。感兴趣的朋友MSN:huangyungang@hotmail.com交流,也可mail说明。
本文将着手了解或解决如下内容:
Spring 开发 SCA 组件时需要掌握的一些基本设计原则。
如何将 Spring beans 公开为 SCA 服务,
如何在 Spring 应用程序中访问 SCA 服务和属性。
如何使用 Spring Framework 和 Apache Tuscany SCA Java 运行时来设计和开发 SCA 组件。。
如何结合 SCA 与 Spring 来创建分布式服务应用程序。
2. 开发环境
2.1. 环境准备
为了在实践中完成下面文中描述的内容,您需要以下工具:
表1-开发环境要素
2.2. 环境搭建(参考SCA(Tascany)环境搭建和使用范例)
3. SCA 与 Spring 两者相结合的优势
Spring Framework 与 SCA 采用许多相同的设计原则。SCA 将 Spring 视为其组件的一种实现技术。SCA Sprig Component Implementation Specification 定义了如何采用这种方式来使用 Spring。
与 Spring bean 类似,SCA 组件可以包含到其他组件所提供的服务的引用,并且有一些属性可供配置。
与 Spring 形成对比的是,SCA 是一种跨语言的分布式组件架构,它支持多种组件通信机制。通过将 Spring beans 发布为可由其他组件访问的服务并为 Spring beans 提供关联到其他(可能为远程)组件的服务的引用,SCA 可以扩展 Spring 组件的功能。
4. SCA与Spring 结合的原则
要将 SCA 与 Spring 相结合,一种有效的方法是使用 Spring 来构建 “粗粒度” 的服务组件实现,并引入到 SCA 中以便公开服务、关联服务组件以及处理异构和分布式系统。SCA 可以在使用 Spring 实现的应用程序中添加一些有用的功能,比如说:
对远程组件以及多种协议的扩展支持
支持使用不受 JVM 支持的各种编程语言来编写组件
支持 WS-Policy 针对安全性和事务等活动指定的策略
易于测试组件是 Spring 的一项优异的特性。
缺少 API 和注入技术导致您只能使用简单的模拟对象进行测试。SCA 在服务方面对此进行了补充,因为关于服务组件的 SCA 复合集可以方便地切换到模拟配置以进行测试。
5. Tuscany SCA与Spring结合的步骤
5.1. 将 Spring 应用程序定义为 SCA 组件
创建一个包含一个 Spring 组件的 SCA 复合集
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:tuscany="http://tuscany.apache.org/xmlns/sca/1.0"
targetNamespace="http://calc"
xmlns:c="http://calc"
name="Calculator">
<component name="CalculatorServiceComponent">
<implementation.spring location="targetURI"/>
</component>
</composite>
其中:
<implementation.spring> 元素的位置属性可以指定目标 URI 指向某个存档文件 (.jar) 或 目标,或者 直接指向 Spring 应用程序上下文。
以下列表给出了指定 <implementation.spring> 位置属性的目标 URI 的可能方法。
一个 Spring 应用程序可被定义为 SCA 复合集(即 SCDL:SCDL is used to describe SCA elements such as modules, references, imports, and exports)内的一个 SCA 组件。其形式如下图所示:
其中<implementation.spring>用于指定实现component的Spring bean配置文件。而location则指定的bean文件的位置或目录(关于目录下面的示例中包含)。
6. 示例程序(WebService+SCA+Spring+Hibernate)
下面我们来开发一个示例程序。在本示例中,您将看到如何利用SCA集成现有的Spring组件,并对其进行向外发布。
6.1. 创建工程
首先我们在d:\TuscanyWorkspace\工作区下,创建一个名为SpringDemo “Dynamic Web Project”的工程。加载TuscanyLibrary(在开发环境建立一文中已经指出)。并将apache-tuscany-sca-1.6.zip的lib目录中的.jar文件COPY到工程的lib目录中。
以上是一个Java Application中对OSOA包的使用。当然对于Java Web Application需要将这些包加到Web Application的lib目录下。同时本示例还需要将hibernate和c3p0的JAR包加入到lib目录下。
6.2. 代码
下面的我们要实现的是基于Apache Tomcat来发布一个tuscany的SCA组件。
程序代码的包结构如下图所示:
图6-示例程序的包结构
6.2.1. 创建基于Hibernate的数据访问程序
6.2.1.1. 创建Hibernate工具类—HibernateUtil.java
此类主要用于实现对数据库的CRUD基本操作,需要注意的是hibernate.cfg.xml文件是通过注入的方式来实现的。
package net.jite.waf.persistent.util;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.hbm2ddl.SchemaUpdate;
/**
* desc: Hibernate的通用类 <br/>
* 用于对Hibernate SessionFactory的初始化以及Hibernate Session的管理
* @author <a href="mailto:huangyungang@hotmail.com">huangyungang </a>
*
*/
public class HibernateUtil {
private SessionFactory _sf;
private static final ThreadLocal session = new ThreadLocal();
private String configFile;
/**
* 设置默认的配置文件名
*
* @param cfgFile
*/
public void setConfigFile(String cfgFile){
configFile=cfgFile;
}
/**
* 初始化此对象
*
*/
public void init(){
try {
Configuration config = new Configuration().configure(configFile);
if ("true".equals(config.getProperty("createtable"))) {
new SchemaExport(config).create(true, true);
}
if ("true".equals(config.getProperty("updatetable"))) {
new SchemaUpdate(config).execute(true, true);
}
_sf = config.buildSessionFactory();
} catch (HibernateException e) {
throw new RuntimeException("初始化Hibernate SessionFactory失败", e);
}
}
/**
* 获取一个Session
* @return Session
* @throws HibernateException
*/
public Session currentSession() throws HibernateException {
Session s = (Session) session.get();
if (s == null) {
s = _sf.openSession();
session.set(s);
}
return s;
}
/**
* 关闭Session
*
* @throws Exception
*/
public void closeSession() throws HibernateException {
Session s = (Session) session.get();
if (s != null)
s.close();
session.set(null);
}
}
6.2.1.2. 创建一个CommonDao类
CommonDao实现了基本的数据访问操作,这里的CommonDao可以被Service层去调用。代码如下:
import java.io.Serializable;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import user.util.HibernateUtil;
public class CommonDao {
private Session _session;
private HibernateUtil util;
public Session get_session() {
return _session;
}
public void set_session(Session session) {
_session = session;
}
public HibernateUtil getUtil() {
return util;
}
private boolean isOSIV;
//***********************增加的内容********************************
/**
* 根据主键ID删除obj
*
* @throws Exception
* 删除时出错则抛出
*/
public void deleteById(Class po, String id) throws Exception {
// Object obj = getById(po, id);
// delete(obj);
_session=getSession();
Transaction tx = _session.beginTransaction();
try
{
_session.delete(_session.get(po,id));
tx.commit();
}
catch (HibernateException e) {
// 在目前的HRibernate版本中当无对应的id的主键记录存在时抛出的异常
tx.rollback();
} finally {
closeSession();
}
}
/**
*
* desc:新添加的方法,用于匹配CMS数据库中的字符串主键
* @author huangyg
*
**/
public Object getById(Class po,String id) throws Exception {
_session = getSession();
try {
//return _session.load(po,id);
return _session.get(po, id);
} catch (HibernateException e) {
// 在目前的Hibernate版本中当无对应的id的主键记录存在时抛出的异常
return null;
} finally {
closeSession();
}
}
//***************************end*************************************
//***************************************************************
/**
* 设置获取Hibernate Session的通用类
*/
public void setUtil(HibernateUtil util) {
this.util = util;
}
/**
* 持久化obj
*
* @throws Exception
* 持久化过程时出错则抛出
*/
public void save(Object obj) throws Exception {
_session = getSession();
Transaction tx = _session.beginTransaction();
try {
_session.save(obj);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
// log.error("Hibernate进行持久化Object时错误", e);
throw new Exception("Hibernate进行持久化Object时错误");
} finally {
closeSession();
}
}
/**
* 更新obj
*
* @throws Exception
* 更新时出错则抛出
*/
public void update(Object obj) throws Exception {
_session = getSession();
Transaction tx = _session.beginTransaction();
try {
_session.update(obj);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
// log.error("Hibernate更新Object时错误", e);
throw new Exception("Hibernate更新Object时错误");
} finally {
closeSession();
}
}
/**
* 删除obj
*
* @throws Exception
* 删除时出错则抛出
*/
public void delete(Object obj) throws Exception {
_session = getSession();
Transaction tx = _session.beginTransaction();
try {
_session.delete(obj);
tx.commit();
} catch (HibernateException e) {
tx.rollback();
// log.error("Hibernate删除Object时错误", e);
throw new Exception("Hibernate删除Object时错误");
} finally {
closeSession();
}
}
/**
* 根据主键ID删除obj
*
* @throws Exception
* 删除时出错则抛出
*/
public void deleteById(Class po, int id) throws Exception {
Object obj = getById(po, new Integer(id));
delete(obj);
}
/**
* 清空某po所有的数据 强烈建议尽量不要使用此方法,一般来说不要物理删除数据,置状态比较合适
*
* @param po
* @throws Exception
*/
public void deleteAll(Class po) throws Exception {
_session = getSession();
Transaction tx = _session.beginTransaction();
try {
_session.createQuery("delete from " + po.getName()).executeUpdate();
tx.commit();
} catch (HibernateException e) {
tx.rollback();
// log.error("Hibernate清空PO中数据时错误", e);
throw new Exception( "Hibernate清空PO中数据时错误");
} finally {
closeSession();
}
}
/**
* 根据为int型的主键ID获取对应的Object
*
* @param obj
* @param id
* @return Object
* @throws Exception
*/
public Object getById(Object obj, int id) throws Exception {
return getById(obj.getClass(), new Integer(id));
}
/**
* 根据主键ID获取对应的Object
*
* @param obj
* @param id
* @return Object
* @throws Exception
*/
public Object getById(Object obj, Serializable id) throws Exception {
return getById(obj.getClass(), id);
}
/**
* 根据为int型的主键ID获取对应的Object
*
* @param obj
* @param id
* @return Object
* @throws Exception
*/
public Object getById(Class po, int id) throws Exception {
return getById(po, new Integer(id));
}
/**
* 根据主键ID获取对应的Object
*
* @param obj
* @param id
* @return Object
* @throws Exception
*/
public Object getById(Class po, Serializable id) throws Exception {
_session = getSession();
try {
return _session.get(po, id);
} catch (HibernateException e) {
// 在目前的Hibernate版本中当无对应的id的主键记录存在时抛出的异常
return null;
} finally {
closeSession();
}
}
// For Business Method
/**
* 根据需执行的hql返回List <br>
* 建议对于数据量小或一次进行频繁查询的使用
*
* @param hql
* @return java.util.List
* @throws Exception
*/
public List getListByHql(String hql) throws Exception {
return null;
}
/**
* 获取Session
*
* @throws Exception
*/
public Session getSession() {
return util.currentSession();
}
/**
* 关闭Session
*
* @throws Exception
*/
public void closeSession() {
// Use Open Session In View,so we don't close session
if (!isOSIV) {
util.closeSession();
}
}
// ============================== get/set
public void setOSIV(boolean isOSIV) {
this.isOSIV = isOSIV;
}
}
6.2.1.3. 创建一个POJO类和Hibernate的.hbm.xml映射文件
POJO类代码如下:
package user.domain;
public class User {
private Integer id;
private String username;
private String password;
private int sex;
private String address;
public String toString(){
return null;
}
public Integer getId(){
return this.id;
}
public void setId(Integer id){
this.id=id;
}
public String getUsername(){
return this.username;
}
public void setUsername(String username){
this.username=username;
}
public String getPassword(){
return this.password;
}
public void setPassword(String password){
this.password=password;
}
public void setSex(int sex){
this.sex=sex;
}
public int getSex(){
return this.sex;
}
public void setAddress(String address){
this.address=address;
}
public String getAddress(){
return this.address;
}
}
User.hbm.xml内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="user.domain.User"
table="userinfo"
>
<id
name="id"
column="ID"
type="java.lang.Integer"
length="10"
unsaved-value="0"
>
<generator class="increment" />
</id>
<property
name="username"
type="java.lang.String"
update="true"
insert="true"
column="username"
not-null="false"
unique="false"
/>
<property
name="password"
type="java.lang.String"
update="true"
insert="true"
column="password"
not-null="false"
unique="false"
/>
<property
name="address"
type="java.lang.String"
update="true"
insert="true"
column="address"
not-null="false"
unique="false"
/>
</class>
</hibernate-mapping>
6.2.1.4. 创建hibernate.cfg.xml文件
hibernate.cfg.xml内容如下:
<?xml version="1.0" encoding="gb2312"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/soademo?useUnicode=true&
characterEncoding=GBK</property>
<property name="connection.username">root</property>
<property name="connection.password">admin</property>
<!-- org.hibernate.dialect.OracleDialect -->
<!-- org.hibernate.dialect.MySQLDialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="jdbc.fetch_size">50</property>
<property name="show_sql">true</property>
<property name="createtable">false</property>
<property name="updatetable">true</property>
<property name="c3p0.min_size">1</property>
<property name="c3p0.max_size">30</property>
<property name="c3p0.max_statements">100</property>
<property name="c3p0.idle_test_period">5000</property>
<!--浮标管理-->
<mapping resource="user/domain/User.hbm.xml" />
<!--缓存配置-->
</session-factory>
</hibernate-configuration>
6.2.2. 创建基于SCA容器并集成Spring的Composite
6.2.2.1. 在web.xml中添加tuscany过滤器
<filter>
<filter-name>tuscany</filter-name>
<filter-class>org.apache.tuscany.sca.host.webapp.TuscanyServletFilter
</filter-class>
</filter>
<filter-mapping>
<filter-name>tuscany</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
需要注意的是,这里不需要添加Spring ContextLoaderListener,SCA具备自已独立的容器,直接访问Spring容器内部的Beans比较困难,因为它们不在同一容器内。下面的代码我们是不需要加到web.xml文件中的。
<!--
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener
</listener-class>
</listener>
-->
6.2.2.2. 创建Spring Bean配置
Spring bean的配置共包括三部分内容:
Bean的自身定义
供外部调用Service定义
聚合其它Service的引用定义
在WebContent/spring-context目录下创建beans-user.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:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/sca http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd"
>
<sca:service name="UserService"
type="user.service.UserService"
target="userServiceBean"/>
<bean id="userServiceBean" class="user.service.UserServiceImpl">
<property name="dao" ref="CommonDaoService"/>
</bean>
<sca:reference name="CommonDaoService" type="user.dao.CommonDao" ></sca:reference>
</beans>
创建beans-commondao.xml,内容如下:
<?xml version="1.0" encoding="gbk"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/sca http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd"
>
<!--Bean对外提供 -->
<sca:service name="CommonDaoService"
type="user.dao.CommonDao"
target="commonDaoBean"/>
<!--Bean自身定义 -->
<bean id="commonDaoBean" class="user.dao.CommonDao">
<property name="util" ref="HibernateUtilService"></property>
</bean>
<!--Bean引用别的 -->
<sca:reference name="HibernateUtilService" type="user.util.HibernateUtil" ></sca:reference>
</beans>
创建beans-hibernate-util.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:sca="http://www.springframework.org/schema/sca"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/sca http://www.osoa.org/xmlns/sca/1.0/spring-sca.xsd"
>
<sca:service name="HibernateUtilService"
type="user.util.HibernateUtil"
target="HibernateUtilBean"/>
<bean id="HibernateUtilBean" class="user.util.HibernateUtil" init-method="init">
<property name="configFile" value="/hibernate.cfg.xml"/>
</bean>
</beans>
6.2.2.3. 创建SCA包装
User.composite文件
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
xmlns:c="http://User"
targetNamespace="http://User"
name="User">
<service name="UserService" promote="UserServiceComponent">
<binding.ws></binding.ws>
</service>
<component name="UserServiceComponent">
<implementation.spring location="spring-context/beans-user.xml"/>
<reference name="CommonDaoService" target="CommonDaoServiceComponent"></reference>
</component>
</composite>
其中:
spring-context/beans-user.xml的完全路径是WebContent/Spring-context/beans-user.xml
此处使用<binding.ws></binding.ws>将UserService发布成了一个WebService
Component的引用关系注意描述,由于UserService中需要使用CommonDao的内容,在SCA的Component层面也需要进行定义。例如<reference name="CommonDaoService" target=
"CommonDaoServiceComponent"></reference>。
CommonDao.composite
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
xmlns:c="http://User"
targetNamespace="http://User"
name="CommonDao">
<service name="CommonDaoService" promote="CommonDaoServiceComponent">
</service>
<component name="CommonDaoServiceComponent">
<implementation.spring location="spring-context/beans-commondao.xml"/>
<reference name="HibernateUtilService" target="HibernateUtilServiceComponent"></reference>
</component>
</composite>
HibernateUtil.composite
<?xml version="1.0" encoding="UTF-8"?>
<composite xmlns="http://www.osoa.org/xmlns/sca/1.0"
xmlns:t="http://tuscany.apache.org/xmlns/sca/1.0"
xmlns:c="http://User"
targetNamespace="http://User"
name="HibernateUtil">
<service name="HibernateUtilService" promote="HibernateUtilServiceComponent">
</service>
<component name="HibernateUtilServiceComponent">
<implementation.spring location="spring-context/beans-hibernate-util.xml"/>
</component>
</composite>
6.2.2.4. 创建MySQL数据表
在本机的MySQL数据库soademo中,建一张userinfo表。
/*
Navicat MySQL Data Transfer
Source Host : localhost:3306
Source Database : soademo
Target Host : localhost:3306
Target Database : soademo
Date: 2010-04-19 17:35:13
*/
SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for userinfo
-- ----------------------------
DROP TABLE IF EXISTS `userinfo`;
CREATE TABLE `userinfo` (
`id` int(11) NOT NULL default '0',
`username` varchar(200) default NULL,
`password` varchar(100) default NULL,
`sex` int(2) default NULL,
`address` varchar(200) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
-- ----------------------------
-- Records of userinfo
-- ----------------------------
INSERT INTO `userinfo` VALUES ('1', '1', '1', null, '1');
6.2.3. 执行情况
在SOAPUI工具中调用已经发布的WebService,运行http://localhost:8080/springdemo/UserService?wsdl得到如下结果:
SOAPUI调用情况如下(SOAPUI工具可从网络中下载):
Tomcat结果如下图所示:
最终显示Hibernate完成了向MySQL数据库添加一行记录。
相关推荐
在这个实例中,我们将探讨如何将Tuscany SCA与两大主流框架——**Spring**和**Hibernate**进行整合,以实现更加简洁高效的应用开发。 **Spring框架**是Java领域最知名的依赖注入(DI)和面向切面编程(AOP)框架之...
dubbo-sca Dubbo-2.7.6 + Spring Boot.2.0.x + Spring Cloud.F nacos nacos-spring-boot-example Nacos + Spring Boot 简单入门 nacos-spring-cloud-example Nacos + Spring Cloud 简单入门 sentinel sentinel-...
- **Spring构件实现规范**:详细介绍了如何使用Spring框架来实现SCA服务构件的具体方法。 **2. 版权与许可** 文档中明确指出了版权持有者,并提供了使用该文档的许可条件。用户需要遵循这些条件才能合法地使用和...
Spring可以通过注解或XML配置来定义构件,例如,使用`@Component`注解标记一个类为Spring Bean,这与SCA中的构件概念相吻合。Spring还提供了`@Service`和`@Endpoint`注解,用于标记服务接口和暴露服务,这与SCA的...
"SCA_ClientAndImplementationModelforJava_V09.pdf"和"SCA_BuildingYourFirstApplication_V09.pdf"可能提供了使用SCA进行Java开发的指导;"SOAProgrammingModelBusinessValue.pdf"则可能阐述了SOA编程模型为企业...
1.正余弦优化算法是一种随机优化算法,具有高度的灵活性,原理简单,易于实现,可以方便地应用于不同领域的优化问题。... 到了开发阶段,随机解会逐渐发生变化,且随机解的变化速度会低于探索阶段的速度。
基于卷积神经网络的隐写分析 Matlab SRM、SCA隐写分析+源代码+文档说明,含有代码注释,满分大作业资源,新手也可看懂,期末大作业、课程设计、高分必看,下载下来,简单部署,就可以使用。该项目可以作为课程设计...
此外,Spring还支持多种集成选项,包括与JDBC、Hibernate、JMS等技术的集成。 ### Axis简介 Axis是另一个用于构建Web服务的开源工具包。它最初由Apache软件基金会发起,主要用于创建和调用SOAP Web服务。Axis提供...
Fortify SCA(Source Code Analysis)安装及使用手册 Fortify SCA 是一款功能强大的源代码分析工具,旨在帮助开发者和安全专家检测和修复代码中的安全漏洞。本文档提供了 Fortify SCA 的安装和使用指南,旨在帮助...
6. **优化工具与算法**:在实现SCA时,可能会用到MATLAB等编程语言,其中的`xiao_power_beizeng100.m`和`sca.m`可能是实现SCA算法的具体代码。`xiao_power_beizeng100.m`可能是一个特定问题的示例,而`sca.m`可能...
- **特性说明**:Fortify SCA 提供了多种特性,如深度源代码分析、自动漏洞分类、自定义规则、实时扫描、以及与各种开发工具和持续集成/持续部署(CI/CD)系统的集成。它还支持多种编程语言,包括Java、C++、C#、...
这个实例可能是关于如何使用Apache Tuscany来开发、部署和管理SCA组件的一个教程或者案例研究。 在SCA中,应用程序被分解为可重用的服务组件,这些组件可以通过不同的通信机制相互交互,如HTTP、JMS或CORBA。SCA的...
这里的"SCA_sca算法_SCA_sca程序代码_sca算法代码"标题和描述提示我们,这个压缩包包含的是关于SCA算法的源程序代码,供学习和研究使用。 SCA算法主要分为几个关键步骤: 1. 数据收集:这是侧信道分析的第一步,...
10. **持续改进**:使用Fortify 5.1 SCA rules 应结合持续的代码审查和安全培训,提升整个团队的安全意识和技能,从而逐步减少新引入的安全问题。 总之,Fortify 5.1 SCA rules是保障软件安全的关键工具,它通过...
在现代软件开发中,开源组件的广泛使用使得SCA成为保障代码安全的重要工具。通过SCA,开发者可以了解项目中依赖的开源库、框架和组件的详细信息,包括版本、许可证和潜在的安全漏洞。 SCA工作的核心是构建软件的...