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

  一个完整的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</includeBaseDirectory>
	<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目录下面有对应的可执行文件包。




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值