您的位置:首页 > 编程语言 > Java开发

dubbo 框架学习-将dubbo 服务做成可执行的java 应用

2017-08-01 08:57 351 查看
  一个完整的dubbo服务应该是由服务提供者、服务消费者、服务接口API三者构成的,我在做dubbo服务的demo 的时候把服务提供者和服务消费者作为两个web工程,而服务接口API作为一个普通的maven 工程,把它打成jar 包由另外两个工程引用,服务消费者web工程里面有处理http 请求的操作,是一个标准的spring mvc 工程,服务提供者web工程是一个spring mvc+mybatis 的工程,在服务提供者web 工程中并没有使用spring
mvc 的功能,web.xml 中配置了spring 上下文监听器用来读取对应的配置,这样的dubbo服务放在web 服务器(tomcat)下面运行是没有任何问题的。但是感觉把这样一个dubbo服务提供者作为一个web工程来运行有点鸡肋,因为web服务器只是作为dubbo服务启动的入口而已,那么为何不能把这样的dubbo服务做成一个普通的java 工程,然后提供启动的入口来运行呢?

  其实dubbo 源码中已经有对应的例子,例如dubbo-monitor-simple这个简单的监控器,他就是一个可执行的java应用,解压build后的

dubbo-monitor-simple-2.5.4-SNAPSHOT-assembly.tar.gz 文件,我们发现目录结构如下:



bin 目录下面存放的是这个dubbo服务启动的配置文件(windows/linux),conf目录下面只有一个dubbo.properties属性文件用来更改dubbo服务的配置,lib下面是包括这个project build后的jar和maven 所依赖的jar,bin 目录下面的文件见:



在windows 下面双击start.bat文件,这个服务就能启动起来,下面来构建自己的工程。

做这个之前我们需要了解另外一个dubbo源码的demo,它就是:dubbo-demo-provider 工程,这个工程也是一个可执行的java应用,而且我们可以通过eclipse来直接启动这个dubbo服务,见:



通过运行DemoProvider.java 这个文件,这个dubbo服务起来了,其中有这样一句demo:

com.alibaba.dubbo.container.Main.main(args);


额,这句话明显是调用dubbo自己写的类的一个方法,打开这个类看到:

public class Main {

public static final String CONTAINER_KEY = "dubbo.container";

public static final String SHUTDOWN_HOOK_KEY = "dubbo.shutdown.hook";

private static final Logger logger = LoggerFactory.getLogger(Main.class);

private static final ExtensionLoader<Container> loader = ExtensionLoader.getExtensionLoader(Container.class);

private static volatile boolean running = true;

public static void main(String[] args) {
try {
if (args == null || args.length == 0) {
String config = ConfigUtils.getProperty(CONTAINER_KEY, loader.getDefaultExtensionName());
args = Constants.COMMA_SPLIT_PATTERN.split(config);
}

final List<Container> containers = new ArrayList<Container>();
for (int i = 0; i < args.length; i ++) {
containers.add(loader.getExtension(args[i]));
}
.................................................................................................................................
这个里面加载dubbo一个容器,但是我们调用的时候并没有指定哪个容器,看过dubbo SPI机制就知道这个容器肯定是spring容器,而且dubbo-demo-provider 工程的src\main\resources\META-INF\spring存放了dubbo服务的配置文件,在看看dubbo spring容器的加载文件位置:

/*
* Copyright 1999-2011 Alibaba Group.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*      http://www.apache.org/licenses/LICENSE-2.0 *
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.alibaba.dubbo.container.spring;

import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.alibaba.dubbo.common.extension.ExtensionLoader;
import com.alibaba.dubbo.common.logger.Logger;
import com.alibaba.dubbo.common.logger.LoggerFactory;
import com.alibaba.dubbo.common.utils.ConfigUtils;
import com.alibaba.dubbo.container.Container;

/**
* SpringContainer. (SPI, Singleton, ThreadSafe)
*
* @author william.liangf
*/
public class SpringContainer implements Container {

private static final Logger logger = LoggerFactory.getLogger(SpringContainer.class);

public static final String SPRING_CONFIG = "dubbo.spring.config";

public static final String DEFAULT_SPRING_CONFIG = "classpath*:META-INF/spring/*.xml";

static ClassPathXmlApplicationContext context;

public static ClassPathXmlApplicationContext getContext() {
return context;
}

public void start() {
String configPath = ConfigUtils.getProperty(SPRING_CONFIG);
if (configPath == null || configPath.length() == 0) {
configPath = DEFAULT_SPRING_CONFIG;
}
context = new ClassPathXmlApplicationContext(configPath.split("[,\\s]+"));
context.start();
}

public void stop() {
try {
if (context != null) {
context.stop();
context.close();
context = null;
}
} catch (Throwable e) {
logger.error(e.getMessage(), e);
}
}

}


这个spring容器加载配置文件的默认位置就是src\main\resources\META-INF\spring目录下面的文件,当然也可以在dubbo.properties文件中修改加载文件的位置,通过添加:dubbo.spring.config=XXX 来指定。

明白以上原理后我们来建立一个基于spring的dubbo服务就简单了,下面是建立步骤:

1、创建一个普通的Maven java project。

2、添加maven 依赖,编写业务处理逻辑。

3、配置project 相关的配置文件,例如数据库连接、系统配置文件,dubbo服务配置文件,这些文件应该放在src\main\resources\META-INF\spring 目录下面。

这样就基本完成了,但是maven build后只是打成了jar 包,并没有dubbo 源代码例子中的XXXX-assembly.tar.gz文件,那怎样实现这个呢?这个需要maven-assembly-plugin 插件完成,pom.xml配置如下

<!-- build属性设置 -->
<build>
<finalName>yt-service-application-user</finalName>
<sourceDirectory>src/main/java</sourceDirectory>

<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<verbose />
<bootclasspath>${java.home}/lib/rt.jar;${java.home}/lib/jce.jar</bootclasspath>
</compilerArguments>
</configuration>
</plugin>

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack</id>
<phase>package</phase>
<goals>
<goal>unpack</goal>
</goals>
<configuration>
<artifactItems>
<artifactItem>
<groupId>com.hzlh</groupId>
<artifactId>yt-common-config</artifactId>
<version>0.0.1-SNAPSHOT</version>
<type>jar</type>
<overWrite>true</overWrite>
<outputDirectory>${basedir}/src/main/resources/META-INF</outputDirectory>
<includes>**/system/*.properties,**/spring/*.xml</includes>
</artifactItem>
<artifactItem>
<groupId>com.hzlh</groupId>
<artifactId>yt-service-application-user</artifactId>
<version>0.0.1-SNAPSHOT</version>
<outputDirectory>${project.build.directory}/dubbo</outputDirectory>
<includes>META-INF/assembly/**</includes>
</artifactItem>
</artifactItems>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<configuration>
<descriptor>src/main/assembly/assembly.xml</descriptor>
</configuration>
<executions>
<execution>
<id>make-assembly</id>
<phase>package</phase>
<goals>
<goal>single</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.tld</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>




其中红色部分配置就是插件配置,橙色部分配置是解压一个jar包中的配置文件到当前目录下面,应为我把配置文件单独作为一个工程抽出来,在这个工程里面引用了配置文件工程的jar包,所以需要解压。

来看看红色部分的配置:它需要 

<descriptor>src/main/assembly/assembly.xml</descriptor> 

这个目录下面的描述文件,我们可以把dubbo-monitor-simple这个工程下面这个文件copy 过来,打开assembly.xml
文件如下:

<!--
- Copyright 1999-2011 Alibaba Group.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
-      http://www.apache.org/licenses/LICENSE-2.0 -
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-->
<assembly>
<id>assembly</id>
<formats>
<format>tar.gz</format>
</formats>
<includeBaseDirectory>true</includ
b095
eBaseDirectory>
<fileSets>
<fileSet>
<directory>${basedir}/src/main/resources/assembly/bin</directory>
<outputDirectory>bin</outputDirectory>
<fileMode>0755</fileMode>
</fileSet>
<fileSet>
<directory>src/main/assembly/conf</directory>
<outputDirectory>conf</outputDirectory>
<fileMode>0644</fileMode>
</fileSet>
</fileSets>
<dependencySets>
<dependencySet>
<outputDirectory>lib</outputDirectory>
</dependencySet>
</dependencySets>
</assembly>

这里指定可执行文件的存放位置,配置文件的存放位置,以及依赖的jar存放的位置。${basedir}/src/main/resources/assembly/bin 这里指定了可执行文件读取的位置,我们的project中是没有这些文件的,可以直接从dubbo-monitor-simple目录下面copy过来,然后整个项目的结构如下:



在用maven install 后就会发现在target目录下面有对应的可执行文件包。




                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: