文档章节

JFinal 中使用 Dubbo —— 1 改造JFinal Demo

 糊搞
发布于 2015/04/20 23:58
字数 3462
阅读 7461
收藏 87
点赞 24
评论 16

1. Dubbo Demo概述

此Demo实际在2014年上半年就已经完成了,只是到最近才有时间和心情写完此文。同时,将JFinal升级到了1.9,并采用Maven构建项目。

另外,仔细想了想,Provider其实可以不依托Tomcat之类的Web容器启动,并验证成功。

 

1.1. JFinal Spring插件

有很多人认为,既然有了JFinal,为什么还要Spring。殊不知一些基于Spring的很牛X的东东集成到JFinal中能够事半功倍。比如Dubbo这个高性能优秀的服务框架,它基于Spring,于是JFinal提供的Spring插件就能更方便地将Dubbo集成进咱们的程序中,成为高大上的程序。

 

1.2. 基于jfinal_demo_for_maven

构建本Demo的目的只为了向读者演示如何将咱们的程序改造成基于Dubbo的应用,选择JFinal的Demo,使得JFinal读者可以快速进入状况,而且笔者也能省下开发Demo功能的时间。

 

1.3. 项目依赖及感谢

公司 / 组织

产品

说明

JFinal

JFinal 1.9

http://www.jfinal.com/

    JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。 在拥有Java语言所有优势的同时再拥有ruby、python、php等动态语言的开发效率!为您节约更多时间,去陪恋人、家人和朋友 :)

 

JFinal 1.9 Demo for Maven

JFinal的Demo

阿里巴巴

Dubbo

http://www.oschina.net/p/dubbo

Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,使得应用可通过高性能的 RPC 实现服务的输出和输入功能,可以和 Spring框架无缝集成。

感谢Dubbo,使咱们不需要太多专业知识和能力就能够很轻易地将程序转变成分布式这种高大上的概念型产品。


Druid

http://www.oschina.net/p/druid

Druid是Java语言中最好的数据库连接池。Druid能够提供强大的监控和扩展功能。


 Spring

http://www.oschina.net/p/spring

    Spring Framework 是一个开源的Java/Java EE全功能栈(full-stack)的应用程序框架,以Apache许可证形式发布,也有.NET平台上的移植版本。该框架基于 Expert One-on-One Java EE Design and Development(ISBN 0-7645-4385-7)一书中的代码,最初由 Rod Johnson 和 Juergen Hoeller等开发。Spring Framework 提供了一个简易的开发方式,这种开发方式,将避免那些可能致使底层代码变得繁杂混乱的大量的属性文件和帮助类。

其它

slf4j

log4j

mysql-connector-java

感谢以上项目及环境,使我们能简便快速地构建分布式应用。希望它们能越做越强,也希望更多人从中受益。

Dubbo相关文档已经存放在JFinalDubboDemoApi项目下,请读者仔细阅读。

 

2. Demo结构

2.1. 三体结构

用过Spring的读者都清楚MVC中,C中的业务被分了层,Controller中只看见Service接口即可,实现是可以随配置更换的。

典型的就是下面的接口服务结构:

 

在分布式应用中,你的应用部署在客户端,而业务实现被部署在服务端,如下图:

 

 

而使用Dubbo后,这一切就能轻易实现。本Demo中,按Dubbo的Consumer --> Api --> Provider概念,原JFinal Demo被切割成三部分:

  • JFinalDubboDemoConsumer.war

此war包部署在Consumer客户端,只包含与Web交互有关内容,并调用接口Api来完成相关数据操作(不限于数据操作,只是JFinal Demo中只有数据操作适合提取成api,可不能误导读者)。

  • JFinalDubboDemoApi.jar

将所有业务服务(数据操作)的接口提取出来,集中到一个jar包中,便于Consumer端和Provider端引用(根据实际应用中的业务的要求,不同业务的服务接口应该打包成多个jar包,本Demo只需要一个jar包即可)。

要注意的是,Consumer端和Provider端要引用相同的Api,不然就会出乱子。

  • JFinalDubboDemoProvider

此war包部署在Provider服务端,提供JFinal Demo中Blog的数据服务,它实现数据服务接口Api(提取出的接口在JFinalDubboDemoApi.jar中),并连接数据库完成数据操作。

 

三部分相互独立,千万不要将Api归入Consumer或者Provider包。不然,依赖关系不明确,Api也不方便为其它程序引用。

 

2.2. 部署结构

Api项目分别被Consumer项目端和Provider项目引用,因此,被同时打包进两个war包当中。具体部署结构请看下图:

 

 

既然是分布式服务,那么Consumer端和Provider端都可实现集群,从而真正体现分布式的优势。如何实现集群请参看后面的教程。

 

3. Demo实现

此章节只说明改造中必要说明的部分,其它内容请参见源码。

 

3.1. JFinalDubboDemoApi

新建一个java项目(注意,非Dynamic Web Project),项目命名为“JFinalDubboDemoApi”。

项目中只有两个类,Blog和BlogService:

  • Blog.java

public class Blog extends Model<Blog> {
	private static final long serialVersionUID = -6749384460553909926L;
}

不声明dao字段是因为原来Demo中Blog的dao字段用于数据库操作,而Consumer端不与数据库打交道,所以不需要提供dao。但是,Consumer端得到Blog实例时,还可通过实例看到Model的各种接口。细心的读者可能发现了,Blog还是继承自Model,而且少了dao字段的声明。这是因为,此Demo中将Model做为通信用的Dto,即Data Transfer Object。

编码时要注意了,概念要转换,Model接口在客户端已经不能使用了,不然会出错。后面的章节会讲到并非只有Model做dto,可以有其它选择。

 

  •  BlogService

public interface BlogService {
	Page<Blog> paginate(int pageNumber, int pageSize);

	void update(Blog blog);

	Blog save(Blog blog);

	Blog findById(String id);

	void deleteById(String id);
}

 将JFinal原Demo中所有的数据操作集成到了BlogService接口中,例如:原Controller中的getModel(Blog.class).save()这类代码就提取接口成为了save(Blog)。


3.2. JFinalDubboDemoConsumer

原JFinal Demo项目被改名成“JFinalDubboDemoConsumer”。

3.2.1. Dubbo Consumer配置

3.2.1.1. consumer.xml

标准的Dubbo服务消费方配置文件,改自Dubbo官方Demo:

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
		http://code.alibabatech.com/schema/dubbo
		http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
	<dubbo:application name="jfinal-duboo-demo-consumer" />
	
	<!-- 设置本机IP,一定要正确 -->
	<dubbo:protocol host="192.168.1.100" />

	<!-- 使用multicast广播注册中心暴露发现服务地址 -->
	<dubbo:registry protocol="multicast" address="multicast://224.5.6.7:2181" />

	<!-- 声明BlogService服务代理 -->
	<dubbo:reference id="blogService"
		interface="cn.gh.duboo.demo.service.BlogService" />
</beans>

 里面的参数都在Dubbo开发者指南中有说明,需要提到的是,最下面的配置注册了blogService接口。注意:标签是“dubbo:reference”。


3.2.1.2. applicationContext.xml

SpringPlugin无构造参数启动时会到“webapp\WEB-INF”下读取“applicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

	<import resource="consumer.xml" />
</beans>

 载入此文件即启动Spring,按配置中的“import”标签将加载Dubbo的配置文件“consumer.xml”。


3.2.2. 改造Config

原Demo的“DemoConfig.java”类名被改成“DemoConsumerConfig.java”,相应地,“web.xml”中也得相应改动。

由于Consumer端不需要数据库操作,因此,“a_little_config.txt”被移动到JFinalDubboDemoProvider工程中,改名为“duboo_demo_provider_config.txt”。

只有两个方法需要做出修改:

@Override
	public void configConstant(Constants me) {
		me.setDevMode(true);
	}

	@Override
	public void configPlugin(Plugins me) {
		me.add(new SpringPlugin());
	}


3.2.3. 改造BlogController.java

由于用到了SpringPlugin插件,因此,“BlogController.java”中就用到与之配套的“Ioc”注解。

@Before({ BlogInterceptor.class, IocInterceptor.class })
public class BlogController extends Controller {

	@Inject.BY_NAME
	private BlogService blogService;

在类定义上使用@Before(IocInterceptor.class)是为了告诉SpringPlugin插件,此类需要用到Spring的Bean注入。而@Inject.BY_NAME是告诉SpringPlugin插件,blogService字段需要注入,注入的实例是consumer.xml中声明的同名Bean。这样,类中的各方法就可以使用blogService实例了。

注意:是注入,而不是初始化,并且注入的是一个代理(参见Dubbo文档)。BlogService只是个接口,它的实现部署在Provider端。

请看类中各方法的变化:

    public void index() {
		setAttr("blogPage", blogService.paginate(getParaToInt(0, 1), 10));
		render("blog.html");
	}

	public void add() {
		render("add.html");
	}

	@Before(BlogValidator.class)
	public void save() {
		Blog blog = getModel(Blog.class, "blog");
		blogService.save(blog);
		redirect("/blog");
	}

	public void edit() {
		setAttr("blog", blogService.findById(getPara()));
	}

	@Before(BlogValidator.class)
	public void update() {
		Blog blog = getModel(Blog.class, "blog");
		blogService.update(blog);
		redirect("/blog");
	}

	public void delete() {
		blogService.deleteById(getPara());
		redirect("/blog");
	}

可以看到,所有的数据操作都是通过blogService接口进行操作。 


3.3. JFinalDubboDemoProvider

新建一个Dynamic Web项目,命名为“JFinalDubboDemoProvider”。其实只创建成普通Java项目也可以,原因后面解释。

 

3.3.1. Dubbo Provider配置

3.3.1.1. provider.xml

标准的Dubbo服务提供方配置文件,改自Dubbo官方Demo:

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://code.alibabatech.com/schema/dubbo
        http://code.alibabatech.com/schema/dubbo/dubbo.xsd
        ">

	<!-- 提供方应用信息,用于计算依赖关系 -->
	<dubbo:application name="jfinal-duboo-demo-provider" />

	<!-- 使用multicast广播注册中心暴露服务地址 -->
	<dubbo:registry protocol="multicast" address="multicast://224.5.6.7:2181" />

	<!-- 用dubbo协议在20880端口暴露服务,注意本机IP要设置正确 -->
	<dubbo:protocol name="dubbo" host="192.168.1.100" port="20880" />

	<!-- 声明Blog的Dao实例 -->
	<bean id="blogDao" class="cn.gh.duboo.demo.model.Blog" />

	<!-- 声明BlogService服务实例 -->
	<bean id="blogService" class="cn.gh.duboo.demo.service.impl.BlogServiceImpl">
		<!-- 将Blog的Dao实例注入 -->
		<property name="blogDao" ref="blogDao" />
	</bean>

	<!-- 声明需要暴露的服务接口 -->
	<dubbo:service interface="cn.gh.duboo.demo.service.BlogService"
		ref="blogService" />

</beans>

前几个参数都在Dubbo开发者指南中有说明。

配置中声明了“blogService”这个Bean实例,它是BlogService的一个实现。并通过配置将Blog的Dao注入到这个Bean中,“BlogServiceImpl”中不用初始化blogDao就可以使用了。如果有看不懂的读者请恶补Spring配置。

最后,通过“dubbo:service”标签暴露“BlogService”服务给Consumer端。“cn.gh.duboo.demo.service.BlogService”就是暴露出来的服务名,具体内容参见Dubbo文档。

 

3.3.1.2. applicationContext.xml

SpringPlugin无构造参数启动时会到“webapp\WEB-INF”下读取“applicationContext.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"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd">

	<import resource="provider.xml" />
</beans>

 载入此文件即启动Spring,按配置中的“import”标签将加载Dubbo的配置文件“provider.xml”。


3.3.2. duboo_demo_provider_config.txt

原JFinal Demo中的“a_little_config.txt”被移动到JFinalDubboDemoProvider工程中,改名为“duboo_demo_provider_config.txt”。

内容不变,参数值请根据自己数据库情况自行修改。

 

3.3.3. 改造Config

将原JFinal Demo中的“DemoConfig.java”移动到项目中,并改名成“DemoProviderConfig.java”。同样地,“web.xml”中也得相应改动。

这里抛弃了C3P0数据源插件,改用Druid,因为它可以监控Sql运行情况。Druid的其它优点请自行百度。

改动的地方如下:

@Override
	public void configConstant(Constants me) {
		loadPropertyFile("duboo_demo_provider_config.txt");
		me.setDevMode(getPropertyToBoolean("devMode", false));
		me.setViewType(ViewType.JSP);
	}

	@Override
	public void configHandler(Handlers me) {
		// 声明Druid监控页面URL
		me.add(new DruidStatViewHandler("/druid"));
	}

	@Override
	public void configPlugin(Plugins me) {
		// 配置Druid数据库连接池插件
		DruidPlugin dp = new DruidPlugin(getProperty("jdbcUrl"),
				getProperty("user"), getProperty("password").trim());

		StatFilter stat = new StatFilter();
		stat.setMergeSql(true);
		dp.addFilter(stat);

		WallFilter wall = new WallFilter();
		wall.setDbType(JdbcConstants.MYSQL);

		dp.addFilter(wall);

		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);

		arp.setShowSql(getPropertyToBoolean("devMode", false));
		arp.setDevMode(getPropertyToBoolean("devMode", false));
		arp.addMapping("blog", Blog.class); // 映射blog 表到 Blog模型
		arp.setDialect(new MysqlDialect());

		// 配置Spring插件
		SpringPlugin sp = new SpringPlugin();

		// 加入各插件到Config
		me.add(dp);
		me.add(arp);
		me.add(sp);
	}

 配置中没有什么特别的,只是启动了Druid监控。部署到Tomcat后,通过http://www.id:port/druid即可监控Sql的执行情况。


3.3.4. BlogServiceImpl.java

实现BlogService接口,整个Demo的数据操作代码都存在此类中。

public class BlogServiceImpl implements BlogService {

	private Blog blogDao;
	
	public Page<Blog> paginate(int pageNumber, int pageSize) {
		return blogDao.paginate(pageNumber, pageSize, "select *", "from blog order by id asc");
	}

	public void update(Blog blog) {
		if (blog == null) {
			return;
		}
		blog.update();
	}

	public Blog save(Blog blog) {
		if (blog == null) {
			return null;
		}
		blog.save();
		return blog;
	}

	public Blog findById(String id) {
		Blog blog = blogDao.findById(id);
		return blog;
	}

	public void deleteById(String id) {
		blogDao.deleteById(id);
	}
	
	/**
	 * 通过Spring配置文件注入Blog的dao
	 * @param blogDao
	 */
	public void setBlogDao(Blog blogDao) {
		this.blogDao = blogDao;
	}
}

 没有什么好介绍的,大家要注意的地方就是Blog的dao是通过Spring配置注入的。


3.3.5. 启动类

由于Provider只是个服务,那么它就能够脱离Tomcat之类的Web容器独立运行,所以咱们就大胆的试试:

创建一个专门用于独立启动的类命名为“DemoProviderApp.java”,在它的main()方法中加入如下代码:

public class DemoProviderApp {

	public static void main(String[] args) throws InterruptedException {
		// 读取配置文件
		Prop p = PropKit.use("duboo_demo_provider_config.txt", "utf-8");

		// 配置Druid数据库连接池插件
		DruidPlugin dp = new DruidPlugin(p.get("jdbcUrl"), p.get("user"), p
				.get("password").trim());

		WallFilter wall = new WallFilter();
		wall.setDbType(JdbcConstants.MYSQL);
		dp.addFilter(wall);

		// 配置ActiveRecord插件
		ActiveRecordPlugin arp = new ActiveRecordPlugin(dp);

		arp.addMapping("blog", Blog.class); // 映射blog 表到 Blog模型
		arp.setDialect(new MysqlDialect());
		arp.setShowSql(p.getBoolean("devMode", false));
		arp.setDevMode(p.getBoolean("devMode", false));

		// 配置Spring插件
		SpringPlugin sp = new SpringPlugin(
				"src/main/webapp/WEB-INF/applicationContext.xml");

		// 手动启动各插件
		dp.start();
		arp.start();
		sp.start();

		System.out.println("Demo provider for Dubbo启动完成。");
		
		// 没有这一句,启动到这服务就退出了
		Thread.currentThread().join();
	}
}

怎么样,几行代码就可以将Provider服务作为一般Java应用启动。

由于使用了JFinal的插件,只用少量代码就达到目的,否则还要写一大套代码。前人种树,后人乘凉,所以再次感谢 @JFinal 大大,并大喊:“JFinal威武”。


源码地址:

JFinalDubboDemoApi.zip

JFinalDubboDemoConsumer.zip

JFinalDubboDemoProvider.zip


Dubbo文档:

Dubbo 的文档镜像


系列文章:

JFinal 中使用 Dubbo —— 2 部署及运行

JFinal 中使用 Dubbo —— 3 集群

© 著作权归作者所有

共有 人打赏支持
粉丝 80
博文 5
码字总数 10741
作品 0
深圳
程序员
加载中

评论(16)

罗斌杰是也
大赞~!
糊搞

引用来自“jiannan”的评论

可以参考0,只是你这名字取的,让我觉得你写的有点不放心0
哈哈,,,自己看着办就行了~~~
jiannan
jiannan
可以参考0,只是你这名字取的,让我觉得你写的有点不放心0
糊搞

引用来自“蓝薯”的评论

写的不错 支持
谢谢~~~
蓝薯
蓝薯
写的不错 支持
糊搞

引用来自“空大”的评论

感谢作者文章
不客气,希望大家一起提高啊~~~
尾生
尾生
感谢作者文章
s
shufangxieyang
非常好,后续好好学习
糊搞
推荐后者,因为jar包可重复使用在多个项目中
糊搞

引用来自“江南红衣”的评论

JFinal 2.0 没有了Sping插件了,还能用Dubbo吗
你可以将JFinal 1.9中SpringPlugin的3个Java文件复制到你的项目中,或者将这3个文件单独打包成JFinal-Sring.jar
JFinal 3.4 发布,将极速贯彻到 UI 层

jfinal 的终极目标是全面实现软件开发整个过程的极速开发,极大提升开发效率,极大降低学习成本,极大提升开发体验 jfinal 诞生头五年,已实现 WEB + ORM + AOP 层面的极速开发,赢得了大量开...

JFinal ⋅ 04/28 ⋅ 129

JAVA 极速WEB+ORM框架 - JFinal

JFinal 是基于 Java 语言的极速 WEB + ORM 框架,其核心设计目标是开发迅速、代码量少、学习简单、功能强大、轻量级、易扩展、Restful。在拥有Java语言所有优势的同时再拥有ruby、python、p...

JFinal ⋅ 2012/03/18 ⋅ 496

Jboot v1.4.9 发布,核心 JFinal 升级到 3.4 最新版本

Jboot 是一个基于 JFinal 和 Undertow 开发的微服务框架。提供了 AOP、RPC、分布式缓存、限流、降级、熔断、统一配置中心、Opentracing 数据追踪、metrics 数据监控、分布式 session、代码生...

理工男海哥 ⋅ 05/03 ⋅ 0

基于注释自动生成 API 文档 - Regan API

Regan API 前言 Regan API 项目是基于注释自动生成api文档,很大缩短了开始与后期维护API接口文档的时间。 Regan API 利用jdk提供的Doclet 类读取文档注释,可手动配置需要读取的文件,同时增...

Jeff_Regan ⋅ 06/15 ⋅ 0

jfinal-admin 3.2 发布,beetl 模板升级到 2.7.14

jfinal-admin 3.2 版本正式发布啦。 基于JFinal的后台管理系统,采用了简洁强大的JFinal作为web框架,模板引擎用的是beetl,数据库用mysql,前端bootstrap框架。 演示地址 http://jad.yxyun...

IT小香猪 ⋅ 04/19 ⋅ 0

kiplinglee/jfinal-ioc-plugin

jfinal-ioc-plugin JFinal 依赖注入插件 1.在JFinalConfig文件中配置IOC插件 @Overridepublic void configConstant(Constants me) { // 创建controller实现依赖注入me.setControllerFactory......

kiplinglee ⋅ 04/13 ⋅ 0

JFinal 1.6可以无缝升级到最高哪个版本?

大约在JFinal 1.6的时候做了一个项目,一直运行至今。中途没升级也没做功能扩展,时至今日,需要做功能升级了,但是时隔太久远,基本不记得JFinal这个框架一路过来的升级过程了。所以想请求帮...

车开源 ⋅ 05/11 ⋅ 0

JFinal如何使用JNDI连接数据库

想用JNDI的方式连接数据库,但是JFinal中用的是DruidPlugin和ActiveRecordPlugin,没有看到用DataSource的地方?请问JFinal支持JNDI连接方式吗?怎么具体实现?...

zqq3436 ⋅ 06/11 ⋅ 0

jfinal兼容oracle integer字段

为什么oracle integer字段用了number(3,0),jfinal生成的字段还是BigDecimal @jfinal

tianxia007 ⋅ 05/02 ⋅ 0

JFinal(1.6)在Validator里执行过getFile,在Controller里取不到文件

JFinal在Validator里执行过getFile之后Validator中是可以取到文件及有关信息,但是在Controller里取不到文件,是不是我的姿势不正确?@JFinal

车开源 ⋅ 05/15 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

Mahout推荐算法API详解

前言 用Mahout来构建推荐系统,是一件既简单又困难的事情。简单是因为Mahout完整地封装了“协同过滤”算法,并实现了并行化,提供非常简单的API接口;困难是因为我们不了解算法细节,很难去根...

xiaomin0322 ⋅ 11分钟前 ⋅ 0

WampServer默认web服务器根目录位置

安装WampServer之后的web服务器根目录默认位置在WampServer安装目录下的www:

临江仙卜算子 ⋅ 13分钟前 ⋅ 0

Redux的一些手法记录

Redux Redux的基本概念见另一篇文。 这里记录一下Redux在项目中的实际操作的手法。 actions 首先定义action.js,actions的type,可以另起一个action-type.js文件。 action-type.js用来存...

LinearLaw ⋅ 14分钟前 ⋅ 0

android 手势检测(左右滑动、上下滑动)

GestureDetector类可以让我们快速的处理手势事件,如点击,滑动等。 使用GestureDetector分三步: 1. 定义GestureDetector类 2. 初始化手势类,同时设置手势监听 3. 将touch事件交给gesture...

王先森oO ⋅ 28分钟前 ⋅ 0

java 方法的执行时间监控 设置超时(Future 接口)

java 方法的执行时间监控 设置超时(Future 接口) import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executor......

青峰Jun19er ⋅ 32分钟前 ⋅ 0

一名开源小白的Apache成长自述

今天收到了来自Apache Vote我成为Serviceomb项目Committer的邮件,代表自己的贡献得到了充分的肯定;除了感谢团队的给力支持,我更希望将自己的成长经历——如何践行Apache Way的心得介绍给大...

微服务框架 ⋅ 35分钟前 ⋅ 0

vim介绍、颜色显示和移动光标、一般模式下复制、剪切和粘贴

1.vim 是 vi 的升级版 vim 是带有颜色显示的 mini安装的系统,一般都不带有vim [root@aminglinux-128 ~]# yum install -y vim-enhanced已加载插件:fastestmirror, langpacksLoading mir...

oschina130111 ⋅ 35分钟前 ⋅ 0

Deepin 操作系统四面楚歌

作为国内做的最好的 Linux 发行版,源自 Debian sid 的 Deepin 目前正面临重重困境,新版本不断延期,开发人员离职,bug 长期得不到修复,和 Debian/Ubuntu 的兼容性问题也面临越来越严重的挑...

六库科技 ⋅ 35分钟前 ⋅ 0

MyBatis之动态sql

我们需要知道的是,使用mybatis重点是对sql的灵活解析和处理。在原先的UserMappser.xml中,我们这样查询表中满足条件的记录 : 123 <select id="findUserList" parameterType="userQuery...

瑟青豆 ⋅ 36分钟前 ⋅ 0

这届俄罗斯世界杯的冷门那么多怎么办?

最纯粹的世界杯,最神奇的大冷门。 德国0比1被墨西哥摩擦了。 日本历史性的赢了哥伦比亚。 C罗也挑平了西班牙。 梅西被冰岛狮吼吼愣神了。 就连11次进世界杯4强的巴西也被瑞士逼平了。 天台已...

开源中国众包平台 ⋅ 36分钟前 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部