osgi实战项目(osmp)一步一步玩转osgi之第一个服务(7)
前面几篇文章已经讲了一些组件了,今天我们就开始实实在在的动手三分钟完成我们的第一个业务bundle,写一个服务提供对数据的CRUD功能。
我们写一个demo完成学生信息的crud功能。
1、进入osmp下载目录,复制粘贴osmp-utils 并改名为 osmp-demo
2、进入osmp-demo目录,修改pom.xml为以下内容
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.osmp.baseweb</groupId> <artifactId>osmp-parent</artifactId> <version>1.0.0</version> </parent> <artifactId>osmp-demo</artifactId> <packaging>bundle</packaging> <name>osmp-demo</name> <build> <plugins> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Export-Package></Export-Package> <Import-Package> org.springframework.aop, org.springframework.aop.framework, org.springframework.cglib, org.springframework.cglib.proxy, org.springframework.cglib.core, org.springframework.cglib.reflect, org.aopalliance.aop, org.aopalliance.intercept, *;resolution:=optional </Import-Package> </instructions> </configuration> </plugin> </plugins> </build> <dependencies> <dependency> <groupId>com.osmp.baseweb</groupId> <artifactId>osmp-intf-define</artifactId> <version>${osmp.version}</version> </dependency> <dependency> <groupId>com.osmp.baseweb</groupId> <artifactId>osmp-jdbc</artifactId> <version>${osmp.version}</version> </dependency> <dependency> <groupId>org.springframework.osgi</groupId> <artifactId>spring-osgi-core</artifactId> </dependency> <dependency> <groupId>org.osgi</groupId> <artifactId>org.osgi.core</artifactId> </dependency> </dependencies> </project>
- osmp-inf-define 组件是我们基础服务定义接口,业务开发需要实现里面的BaseDataService接口
- osmp-jdbc 是我们需要用到OSMP提供的数据源和封装好的dao模板功能。
- spring-osgi-core,org.osgi.core 照抄,springDM必须依赖。
- maven-bundle-plugin 插件是maven提供的在osgi环境下编译bundle的插件。先暂时照抄,以后再解释。
3、删除utils组件里类和配置,并修改包名,最后包结构如下:
osmp-demo
|src |main | java | com/osmp/demo/service
| resources | META-INF/spring
|test | java
| resources
|pom.xml
4、在osmp根目录下的父 pom.xml里 <modules></modules> 新增 <module>osmp-demo</module>
5、打开 eclipse 右键 import -> Existing Maven Projects -> Browse... 选择 osmp 目录后。在下面的 Projects: 把osmp-demo勾取起后点 Finish
6、数据库新建表 demo_user
CREATE TABLE `demo` ( `id` varchar(50) NOT NULL, `name` varchar(255) DEFAULT NULL, `age` int(11) DEFAULT NULL, `remark` varchar(255) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
7、新建实体对象User.java
/* * Project: OSMP * FileName: User.java * version: V1.0 */ package com.osmp.demo.service.user.entity; import com.osmp.jdbc.define.Column; /** * Description: * @author: wangkaiping * @date: 2016年8月25日 下午8:32:47上午10:51:30 */ public class User { @Column(mapField="id",name="id") private String id; @Column(mapField="name",name="name") private String name; @Column(mapField="age",name="age") private int age; @Column(mapField="remark",name="remark") private String remark; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getId() { return id; } public void setId(String id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getRemark() { return remark; } public void setRemark(String remark) { this.remark = remark; } }
@Column( mapField=数据库字段名称,name=实体对象名称)如果两者一致的话可以省略括号内的内容
8、新建用户接口和实现类(UserService.java,UserServiceImpl)
/* * Project: OSMP * FileName: UserService.java * version: V1.0 */ package com.osmp.demo.service.user; import java.util.List; import java.util.Map; import com.osmp.demo.service.user.entity.User; import com.osmp.jdbc.define.Page; /** * Description: * * @author: wangkaiping * @date: 2014年11月28日 下午5:27:33 */ public interface UserService { public String getUserName(String name); public int getUserAge(int age); public int cudUser(Map<String,Object> map); public List<User> queryList(Map<String, Object> map); public Page<User> queryListByPage(Map<String, Object> map); }
/* * Project: OSMP * FileName: UserServiceImpl.java * version: V1.0 */ package com.osmp.demo.service.user.impl; import java.util.Date; import java.util.List; import java.util.Map; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.osmp.jdbc.define.Page; import com.osmp.jdbc.support.JdbcDao; import com.osmp.cache.define.annotation.Cacheable; import com.osmp.demo.service.user.UserService; import com.osmp.demo.service.user.entity.User; /** * Description: * * @author: wangkaiping * @date: 2014年11月28日 下午5:28:39 */ @Service public class UserServiceImpl implements UserService { private Logger logger = LoggerFactory.getLogger(UserServiceImpl.class); @Autowired private JdbcDao jdbcDao; @Override public String getUserName(String name) { logger.info("==============demo test =========="+name); //jdbcDao.update("jwms.update.area.time", "jwms", new Date(),"app001301"); return "我的名字叫:" + name; } @Override public int getUserAge(int age) { return age; } @Override public int cudUser(Map<String, Object> map) { String sqlId = (String) map.get("sqlId"); String dbName = (String) map.get("dbName"); return jdbcDao.update(sqlId, map, dbName); } @Override public List<User> queryList(Map<String, Object> map) { String sqlId = (String) map.get("sqlId"); String dbName = (String) map.get("dbName"); return jdbcDao.queryForList(sqlId, dbName, map, User.class); } @Override public Page<User> queryListByPage(Map<String, Object> map) { String sqlId = (String) map.get("sqlId"); String dbName = (String) map.get("dbName"); int page = (int) map.get("page"); int size = (int) map.get("size"); return jdbcDao.queryForPage(sqlId, dbName, map, User.class, page, size); } }
9、 新建 DemoServiceImpl.java 实现BaseDataServices,最后osgi发布出的服务
/* * Project: OSMP * FileName: DemoServiceImpl.java * version: V1.0 */ package com.osmp.demo.service; import java.util.HashMap; import java.util.Map; import org.springframework.beans.factory.annotation.Autowired; import com.osmp.demo.service.user.UserService; import com.osmp.intf.define.model.Parameter; import com.osmp.intf.define.service.BaseDataService; /** * Description: * @author: wangkaiping * @date: 2016年11月9日 下午5:31:09上午10:51:30 */ public class DemoServiceImpl implements BaseDataService{ @Autowired private UserService service; @Override public Object execute(Parameter parameter) { Object result = null; String op = parameter.getQueryMap().get("op"); Map<String,Object> paramMap = new HashMap<String, Object>(); paramMap.putAll(parameter.getQueryMap()); switch (op) { case "cud": result = service.cudUser(paramMap); break; case "query": result = service.queryList(paramMap); break; case "queryPage": result = service.queryListByPage(paramMap); break; default: break; } return result; } }
- 实现BaseDataService接口,重写execute方法
- 从方法的Parameter获取入参 op 操作类型,并调用不同的方法完成crud
- 这里方法传递我们使用map作为参数传递
10、在src/main/resources/META-INF/spring 目录下新建spring配置文件 bundle-context.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:context="http://www.springframework.org/schema/context" xmlns:osgi="http://www.springframework.org/schema/osgi" 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-3.0.xsd http://www.springframework.org/schema/osgi http://www.springframework.org/schema/osgi/spring-osgi-1.2.xsd"> <context:component-scan base-package="com.osmp.demo.service"> </context:component-scan> <bean id="jdbcDao" class="com.osmp.jdbc.support.JdbcDao"></bean> <bean id="osmp.demo.service" class="com.osmp.demo.service.DemoServiceImpl" /> <osgi:service interface="com.osmp.intf.define.service.BaseDataService" ref="osmp.demo.service"> <osgi:service-properties> <entry key="name" value="osmp-demo" /> <entry key="mark" value="DEMO例子" /> </osgi:service-properties> </osgi:service> </beans>
- 这里我们的JdbcDao类是从依赖osmp-jdbc组件的。并在DemoServiceImpl里自动注入的。
- 与传统的spring相比,只是在spring命名空间里新增了一个spring-osgi的namespaces
- 通过osgi:service 将DemoServiceImpl 发布为一个osgi服务,服务名称为 osmp-demo
11、编写sql脚本。demo.xml
<?xml version="1.0" encoding="UTF-8" standalone="no" ?> <!DOCTYPE sqls SYSTEM "osmp_sql.dtd"> <sqls> <select id="demo.queryuser"> select * from demo_user <where> <if test="name not empty"> and name=:name </if> <if test="age not empty"> and age=:age </if> </where> </select> <insert id="demo.adduser"> insert into demo_user(id,name,age,remark) values(:id,:name,:age,:remark) </insert> <delete id="demo.deluser"> delete demo_user where id=:id </delete> <update id="demo.upuser"> update demo_user set <if test="name not empty"> name = :name </if> <if test="age not empty"> name = :age </if> <if test="remark not empty"> remark = :remark </if> <where> id = :id </where> </update> </sqls>
12、编写连接池配置文件 demo.osmp.jdbc.properties
osmp.jdbc.name=demo osmp.jdbc.driverClassName=com.mysql.jdbc.Driver osmp.jdbc.url=jdbc:mysql://10.2.1.9:3306/demo?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8 osmp.jdbc.username=xxx osmp.jdbc.password=xxx osmp.jdbc.initialSize=5 osmp.jdbc.maxActive=100 osmp.jdbc.minIdle=5 osmp.jdbc.maxWait=3000 osmp.jdbc.validationQuery=select 1 osmp.jdbc.timeBetweenEvictionRunsMillis=100000 osmp.jdbc.minEvictableIdleTimeMillis=30000 osmp.jdbc.removeAbandonedTimeout=30000
13、将sql脚本和 连接池配置文件分别上传到${servicemix_home}/etc/sqls ${servicemix_home}/etc/datasources 目录
14、osmp-demo mvn install 将osmp-demo.jar上传到${servicemix_home}/deploy 目录
到此我们的服务开发完毕。
新增一条数据
http://xxx.xxx.xxx.xxx:8181/cxf/service/osmp-demo?source={"from":"test"}¶meter={"dbName":"demo","op":"cud","sqlId":"demo.adduser","id":"100000","name":"zhangsang","age":"20","remark":'woshizhangsan"}
查询一条数据(根据名称查询)
http://xxx.xxx.xxx.xxx:8181/cxf/service/osmp-demo?source={"from":"test"}¶meter={"dbName":"demo","op":"query","sqlId":"demo.queryuser","name":"zhangsang"}
分页查询
http://xxx.xxx.xxx.xxx:8181/cxf/service/osmp-demo?source={"from":"test"}¶meter={"dbName":"demo","op":"queryPage","sqlId":"demo.queryuser","page":"1","size":"10"}
删除
http://xxx.xxx.xxx.xxx:8181/cxf/service/osmp-demo?source={"from":"test"}¶meter={"dbName":"demo","op":"cud","sqlId":"demo.deluser","id":"100000"}
- osmp-demo 服务名称。对应上面spring配置文件里发布的osgi:service里的 服务名称 name
- source={“from”:“test”} 这里是OSMP规定的。用来标识请求来源的,可以自己扩充 from 字段必须有。
- parameter json参数
- dbName:数据库名称 这里我们是demo
- op:我们在DemoServiceImpl里定义的操作符
- sqlId:对于我们操行这个操作时需要使用到的sql脚本里的哪个一个sql语句
- 其它的参数根据业务自己定义。
这里入参我是使用json的格式来定义的。可以无限扩充。
当你做完这一切的时候差不多三分钟的时候,你可以定义一个通用的增删改查服务。以后你只需要给一个sql的标识和一个数据库的名称。你就可以得到你想要的结果,根本只要会sql的就可以开发。是不是感觉有点儿意思了。。。。。
sql脚本基本上只要你能写出来的语句。都应该能被解析执行。下面的一些sql例子是真实线上跑起来的。大家可以看看。
我真心觉得,osmp 已经被业务线给玩坏了。。。。
感兴趣的同学可以把上面的demo部署后在osmp-web里进行实时管理。随时随地远程任意的替换和平滑升级。。。
感觉是不是开发一个osgi的服务是如此的简单了呢。。再也不用像eclipse那样新建plugin 工程。一个 一个的去选依赖的组件。。。。。。
今天就先到这儿吧,下一节我们会继续解讲osgi环境下集成cache组件。