Spring Boot 和 AdminLTE 的集成

Spring Boot 和 AdminLTE 的集成

AdminLTE 是个开源的管理模板,首页:http://adminlte.io/,GitHub地址:https://github.com/almasaeed2010/AdminLTE,目前有 2w+ star,100 多个 contributor,可以说是非常出名的开源管理模板了。

image

这篇描述将 AdminLTE 和 Spring Boot 整合起来进行后台开发并利用 AdminLTE 的前端组件、模板、布局。

  • 使用的 AdminLTE 版本 v2.4.3 (2018-02-22)
  • 项目地址:https://github.com/yingw/adminlte-boot-template

下面将介绍三种前后端集成的方式

  • static:所有 AdminLTE 的静态资源直接集成到项目
  • webjars:用 Webjars 将前端库集成到后端 maven 的依赖 jar 中
  • bower:用 Bower 将前端依赖定义,在项目编译过程中创建前端资源

1. 初步集成

1.1. 创建 Spring Boot 项目

从 http://start.spring.io/ 或者 IDE 中创建一个 Spring Boot 项目,依赖:Web、Thymeleaf、DevTools

1.2. 下载 AdminLTE

从 AdminLTE 的 GitHub release 页 下载项目(v2.4.3),解压

  • 拷贝 pages 目录、index.html、index2.html、start.html 到 templates 目录
  • 拷贝 dist 下 css、img、js 目录、bower_components、plugins 目录到 static 目录

    注意的是 bower_components 内有上千文件,拷贝、编译都很慢,虽然用后面的 webjars 依赖可以避免,目前还是需要的,在项目代码中没有放,请自行拷贝。

1.3. 修正路径

批量替换 pages 下面页面的一些相对路径,主要是 css、js、img 的引用

  • ../../dist/ 替换为 ../../
  • ../dist/ 替换为 ../
  • "dist/ 替换为 "./
  • 还有一些上级目录的如 index.html 替换

1.4. 动态跳转控制器

创建一个动态跳转控制器 AdminController

/**
 * @author yinguowei@gmail.com 2018/3/27.
 */
@Controller
class AdminController {
    private static Logger logger = LoggerFactory.getLogger(AdminController.class);

    @GetMapping("/")
    public String home() {
        return "redirect:index2.html";
    }

    @GetMapping(value = {"/**/*.html"})
    public String route(HttpServletRequest request) {
        logger.debug("AdminController.route: request.getRequestURI() = {}", request.getRequestURI());
        String path = request.getRequestURI();
        return path;
    }
}

设置些属性 application.properties

spring.thymeleaf.cache=false
spring.thymeleaf.suffix=

设置了这个控制器后所有的 .html 就可以跳转到对应的视图。如果将来不希望通过 .html 后缀访问 url,而是采用类似 restful 的地址,可以去掉 spring.thymeleaf.suffix 定义(默认是 .html),并在解析时候去掉 .html

    @RequestMapping(value = {"/**/*.html"})
    public String route(HttpServletRequest request) {
        logger.debug("DynamicController.route: request.getRequestURI() = {}", request.getRequestURI());
        String path = request.getRequestURI();
        return path.substring(1, path.length() - 5); // remove "/" and ".html"
    }

1.5. 字体和主题

临时去掉 Googleapi 字体

由于 googleapi 的字体可能被墙,建议全部注释

<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,600,700,300italic,400italic,600italic">

加上雅黑字体

并在主题内加上 AdminLTE.css 和 AdminLTE.min.css

font-family: 'Microsoft YaHei UI', 'Source Sans Pro', 'Helvetica Neue', Helvetica, Arial, sans-serif;

来使用客户端的微软雅黑字体

主题替换

如果需要主题,定制专门的 skin 和 skin.min.css

替换 <link rel="stylesheet" href="/css/skins/_all-skins.min.css"><link rel="stylesheet" href="dist/css/skins/skin-blue.min.css">

生成 min.css

TBD,有在线工具

1.6. 其他修正

部分页面由于 json/javascript 格式问题和 Thymeleaf 冲突,比如 charts/flot.html 改成:

<script th:inline="none">

1.7. 静态测试

Thymeleaf 的一大好处就是可以直接打开 html 进行页面测试而不需要启动服务器。编辑各 stylesheet 和 javascript 的应用地址,改为和当前页面相对,如:

<html xmlns:th="http://www.thymeleaf.org">

<link rel="stylesheet" href="../static/bower_components/bootstrap/dist/css/bootstrap.min.css" th:href="{/bower_components/bootstrap/dist/css/bootstrap.min.css}">
<script src="../static/bower_components/jquery/dist/jquery.min.js" th:src="@{/bower_components/jquery/dist/jquery.min.js}"></script>

但注意这一步也可以不用急着改太多页面,而是只改一两个测试下,因为后面要放到 Layout 公共页面统一改。

小结

经过这一系列集成,已经可以跑起来测试 http://localhost:8080,会自动跳转到 index2.html,可能有些路径的修正不完善或有问题,观察控制台 404 异常修正。

2. Thymeleaf Layout

Layout 是让多个页面共用一套页面模板,这样很多重复的代码就不用重复编码了。

引入 pom 依赖

<dependency>
  <groupId>nz.net.ultraq.thymeleaf</groupId>
  <artifactId>thymeleaf-layout-dialect</artifactId>
</dependency>

在 layout 目录创建 layout.html,可以用 index2.html 拷贝过去修改

2.1 layout/layout.html

标题

  <title layout:title-pattern="$LAYOUT_TITLE | $CONTENT_TITLE">AdminLTE 2</title>

修改原来的相对地址,去掉 static,只保留大部分页面都要用的如 bootstrap, jquery, datatable

  <!-- Bootstrap 3.3.7 -->
  <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
  <!-- Font Awesome -->
  <link rel="stylesheet" href="/bower_components/font-awesome/css/font-awesome.min.css">
  <!-- Ionicons -->
  <link rel="stylesheet" href="/bower_components/Ionicons/css/ionicons.min.css">
  <!-- jvectormap -->
  <link rel="stylesheet" href="/bower_components/jvectormap/jquery-jvectormap.css">
  <!-- Theme style -->
  <link rel="stylesheet" href="/css/AdminLTE.min.css">
  <!-- AdminLTE Skins. Choose a skin from the css/skins
       folder instead of downloading all of them to reduce the load. -->
  <link rel="stylesheet" href="/css/skins/_all-skins.min.css">

修改菜单可以动态根据传入变量选中

<li class="treeview" th:classappend="${menu=='index' || menu=='index2' ? 'active menu-open' : ''}">
  <ul class="treeview-menu">
    <li th:classappend="${menu=='index' ? 'active' : ''}"><a href="/index.html"><i class="fa fa-circle-o"></i> Dashboard v1</a></li>

修改 img 的相对地址,如

<img class="direct-chat-img" src="../static/img/user1-128x128.jpg" th:src="@{/img/user1-128x128.jpg}" alt="message user image">

js

<!-- jQuery 3 -->
<script src="/bower_components/jquery/dist/jquery.min.js"></script>
<!-- Bootstrap 3.3.7 -->
<script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<!-- AdminLTE App -->
<script src="/js/adminlte.min.js"></script>

<!-- Optionally -->
<!-- Slimscroll -->
<script src="/bower_components/jquery-slimscroll/jquery.slimscroll.min.js"></script>
<!-- FastClick -->
<script src="/bower_components/fastclick/lib/fastclick.js"></script>
<!-- AdminLTE for demo purposes -->
<script src="/js/demo.js"></script>

<div layout:fragment="customScript" th:remove="tag">

</div>

如果想单独测试 layout.html,跟下面 index2 一样修改加上静态和动态的地址

声明插入点

<div class="content-wrapper" layout:fragment="content">
...
<div layout:fragment="customScript" th:remove="tag">
</tag>

2.2 index2.html

修改 index2.html、start.html、blank.html 来使用 layout


<html xmlns:th="http://www.thymeleaf.org"
      xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
      layout:decorate="~{layout/layout.html}"
      th:with="menu='index2'">

stylesheet 和 javascript

为了本地测试,保留 stylesheet 和 javascript,但是加上 th:remove="all" 在解析时自己删掉

  <!-- Bootstrap 3.3.7 -->
  <link rel="stylesheet" href="../static/bower_components/bootstrap/dist/css/bootstrap.min.css" th:remove="all">
  <!-- Font Awesome -->
  <link rel="stylesheet" href="../static/bower_components/font-awesome/css/font-awesome.min.css" th:remove="all">
  <!-- Ionicons -->
  <link rel="stylesheet" href="../static/bower_components/Ionicons/css/ionicons.min.css" th:remove="all">
  <!-- Theme style -->
  <link rel="stylesheet" href="../static/css/AdminLTE.min.css" th:remove="all">
  <!-- AdminLTE Skins. -->
  <link rel="stylesheet" href="../static/css/skins/_all-skins.min.css" th:remove="all">
  <!-- jvectormap -->
  <link rel="stylesheet" href="../static/bower_components/jvectormap/jquery-jvectormap.css" th:remove="all">
  <!-- 表格 -->
  <link rel="stylesheet" href="../static/bower_components/datatables.net-bs/css/dataTables.bootstrap.min.css" th:remove="all">
  <!-- PACE -->
  <link rel="stylesheet" href="../static/bower_components/PACE/themes/blue/pace-theme-minimal.css" th:remove="all">

js,页面自定义的 js 可以放到 customScript fragment 里面去

<!-- jQuery 3 -->
<script src="../static/bower_components/jquery/dist/jquery.min.js" th:remove="all"></script>
<!-- Bootstrap 3.3.7 -->
<script src="../static/bower_components/bootstrap/dist/js/bootstrap.min.js" th:remove="all"></script>
<!-- FastClick -->
<script src="../static/bower_components/fastclick/lib/fastclick.js" th:remove="all"></script>
<!-- AdminLTE App -->
<script src="../static/js/adminlte.min.js" th:remove="all"></script>

<div layout:fragment="customScript">

  <!-- Sparkline -->
  <script src="../static/bower_components/jquery-sparkline/dist/jquery.sparkline.min.js" th:src="@{/bower_components/jquery-sparkline/dist/jquery.sparkline.min.js}"></script>
  <!-- jvectormap  -->
  <script src="../static/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js" th:src="@{/plugins/jvectormap/jquery-jvectormap-1.2.2.min.js}"></script>
  <script src="../static/plugins/jvectormap/jquery-jvectormap-world-mill-en.js" th:src="@{/plugins/jvectormap/jquery-jvectormap-world-mill-en.js}"></script>
  <!-- SlimScroll -->
  <script src="../static/bower_components/jquery-slimscroll/jquery.slimscroll.min.js" th:src="@{/bower_components/jquery-slimscroll/jquery.slimscroll.min.js}"></script>
  <!-- ChartJS -->
  <script src="../static/bower_components/chart.js/Chart.js" th:src="@{/bower_components/chart.js/Chart.js}"></script>
  <!-- AdminLTE dashboard demo (This is only for demo purposes) -->
  <script src="../static/js/pages/dashboard2.js" th:src="@{/js/pages/dashboard2.js}"></script>
  <!-- AdminLTE for demo purposes -->
  <script src="../static/js/demo.js" th:src="@{/js/demo.js}"></script>

</div>

删掉不用的节点

删掉:navbar-custom-menumain-sidebar(也可以保留菜单测试)、main-footercontrol-sidebarcontrol-sidebar-bg

内容声明

在 content-wrapper 上声明

<div class="content-wrapper" layout:fragment="content">

2.3 login layout

还有些 404、500 页面使用的是和 layout 完全不同的布局,也可以提炼一个 layout-login,然后 login.html、logout.html、404、500 等都使用这个布局,这里就不重复了。

总结

通过使用 layout,可以将大部分页面共用代码提取出来,通过 fragment 插入页面的定制内容。但是这里大部分页面将来都不会是项目内必须使用的,就不全部改了。

3. Webjars

上面介绍的基本就是静态集成的全部内容,不过前面提到,要把 bower_componenets 这个几千个文件夹的第三方 js、css 依赖库放到项目管理中,总是不太方便的,对于后端开发来说,最好前端的组件也是几个依赖来管理就最简单了,webjars 就是以这个目标设计的工具。

3.1 Webjars 依赖

根据项目使用的库的版本,到 webjars 官网去搜索对应的定义即可,再把 maven 定义拷进来。

例如:

<!--bootstrap-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>bootstrap</artifactId>
	<version>3.3.7</version>
</dependency>

所有的声明

<!-- Webjars begin -->
<!--bootstrap-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>bootstrap</artifactId>
	<version>3.3.7</version>
</dependency>
<!--font-awesome-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>font-awesome</artifactId>
	<version>4.7.0</version>
</dependency>
<!--ionicons-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>ionicons</artifactId>
	<version>2.0.1</version>
</dependency>
<!--morrisjs-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>morrisjs</artifactId>
	<version>0.5.1</version>
</dependency>
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>raphael</artifactId>
	<version>2.2.7</version>
</dependency>
<!--sparkline-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>jquery-sparkline</artifactId>
	<version>2.1.3</version>
</dependency>
<!--jvectormap-->
<dependency>
	<groupId>org.webjars</groupId>
	<artifactId>jvectormap</artifactId>
	<version>2.0.4</version>
</dependency>
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>bower-jvectormap</artifactId>
	<version>1.2.2</version>
</dependency>
<!--datepicker-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>bootstrap-datepicker</artifactId>
	<version>1.7.1</version>
</dependency>
<!--daterangepicker-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>bootstrap-daterangepicker</artifactId>
	<version>2.1.27</version>
</dependency>
<!--moment-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>moment</artifactId>
	<version>2.20.1</version>
</dependency>
<!--knob-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>jquery-knob</artifactId>
	<version>1.2.13</version>
</dependency>
<!--chartjs-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>chartjs</artifactId>
	<version>1.0.2</version>
</dependency>
<!--icheck-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>iCheck</artifactId>
	<version>1.0.2</version>
</dependency>
<!--Flot.js-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>flot</artifactId>
	<version>0.8.3</version>
</dependency>
<!--color picker-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>bootstrap-colorpicker</artifactId>
	<version>2.5.1</version>
</dependency>
<!--select2-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>select2</artifactId>
	<version>4.0.5</version>
</dependency>
<!--ckeditor-->
<dependency>
	<groupId>org.webjars.npm</groupId>
	<artifactId>ckeditor</artifactId>
	<version>4.8.0</version>
</dependency>
<!--PACE (update from original plugins-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>pace</artifactId>
	<version>1.0.2</version>
</dependency>

<!--datatables-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>datatables.net</artifactId>
	<version>1.10.16</version>
</dependency>
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>datatables.net-bs</artifactId>
	<version>2.1.1</version>
</dependency>
<!--fastclick-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>fastclick</artifactId>
	<version>1.0.6</version>
</dependency>
<!--jquery-->
<dependency>
	<groupId>org.webjars.bower</groupId>
	<artifactId>jquery</artifactId>
	<version>3.3.1</version>
</dependency>
<!--jquery-ui-->
<dependency>
	<groupId>org.webjars</groupId>
	<artifactId>jquery-ui</artifactId>
	<version>1.11.4</version>
</dependency>
<!--metisMenu-->
<dependency>
	<groupId>org.webjars</groupId>
	<artifactId>metisMenu</artifactId>
	<version>2.7.0</version>
</dependency>
<!--slimScroll-->
<dependency>
	<groupId>org.webjars</groupId>
	<artifactId>jQuery-slimScroll</artifactId>
	<version>1.3.8</version>
</dependency>
<!--pace (updated from Plugins)-->
<dependency>
	<groupId>org.webjars</groupId>
	<artifactId>pace</artifactId>
	<version>1.0.2</version>
</dependency>
<!-- sweetalert -->
<dependency>
	<groupId>org.webjars.npm</groupId>
	<artifactId>sweetalert</artifactId>
	<version>2.1.0</version>
</dependency>

<!-- Webjars end -->

3.2 修正路径

替换 bower_components 为 /webjars,可以直接从 /webjars 开始应用这些依赖,如:

<link rel="stylesheet" href="/webjars/bootstrap/3.3.7/dist/css/bootstrap.min.css">

注意个别有大小写问题:Ionicons,等等

有些 plugins 目录的依赖也可以通过 webjars 改掉,可能是作者稍微做了修改,如 pace

注意将来要是用上 Spring Security,记得把 webjars 上下文的资源设置为可以访问

..., "/webjars/**").permitAll();

3.3 Webjars Locator

还有个 Webjars 的 Locator 可以用来自动检索版本,写引用 url 的时候就可以连版本号也省略了。

但是会没有代码提示功能,而且只在版本需要经常升级不想动代码的时候才有用,意义不大。

<!--webjars-locator-->
<dependency>
	<groupId>org.webjars</groupId>
	<artifactId>webjars-locator</artifactId>
	<version>0.30</version>
</dependency>

3.4 使用 webjars 的限制

使用 webjars,也有缺点,就是在静态测试的时候,没法直接引用 jar 内的样式和脚本,所以用 webjars 的时候就不能做静态测试了;好处是不用在代码库中存着那上千个依赖。各有取舍吧。

4. Bower

最后一种方式,还可以使用 Bower 来在编译时生成依赖文件。需要用到 frontend-maven-plugin,安装 node 和 bower

4.1 node 配置

package.json

{
  "name": "BootifulAdminLTE",
  "version": "1.0.0",
  "description": "Bootiful-AdminLTE application",
  "dependencies": {
    "bower": "~1.8.4"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/yingw/bootiful-adminlte.git"
  },
  "author": "yinguowei",
  "license": "MIT"
}
  • 也可以根目录执行 npm init,创建 package.json,加上 bower:npm install bower --save
  • 建议加上 description、repository,否则会有一些告警

4.2 Bower 配置

AdminLTE 本身就用了 bower 来管理依赖,拷贝项目中的 bower.json 到根目录,创建 .bowerrc

bower.json

{
  "name": "admin-lte",
  "homepage": "https://adminlte.io",
  "authors": [
    "Abdullah Almsaeed <abdullah@almsaeedstudio.com>"
  ],
  "description": "Admin dashboard and control panel template",
  "main": [
    "index2.html",
    "dist/css/AdminLTE.css",
    "dist/js/adminlte.js",
    "build/less/AdminLTE.less"
  ],
  "keywords": [
    "css",
    "js",
    "html",
    "template",
    "admin",
    "bootstrap",
    "theme",
    "backend",
    "responsive"
  ],
  "license": "MIT",
  "ignore": [
    "/.*",
    "node_modules",
    "bower_components",
    "composer.json",
    "documentation"
  ],
  "dependencies": {
    "bootstrap-slider": "*",
    "chart.js": "1.0.*",
    "ckeditor": "^4.7.0",
    "bootstrap-colorpicker": "^2.5.1",
    "bootstrap": "^3.3.7",
    "jquery": "^3.2.1",
    "datatables.net": "^1.10.15",
    "datatables.net-bs": "^2.1.1",
    "bootstrap-datepicker": "^1.7.0",
    "bootstrap-daterangepicker": "^2.1.25",
    "moment": "^2.18.1",
    "fastclick": "^1.0.6",
    "Flot": "flot#^0.8.3",
    "fullcalendar": "^3.4.0",
    "inputmask": "jquery.inputmask#^3.3.7",
    "ion.rangeSlider": "ionrangeslider#^2.2.0",
    "jvectormap": "^2.0.4",
    "jquery-knob": "^1.2.13",
    "morris.js": "^0.5.1",
    "PACE": "pace#^1.0.2",
    "select2": "^4.0.3",
    "jquery-slimscroll": "slimscroll#^1.3.8",
    "bootstrap-timepicker": "^0.5.2",
    "jquery-sparkline": "^2.1.3",
    "font-awesome": "^4.7.0",
    "Ionicons": "ionicons#^2.0.1",
    "jquery-ui": "1.11.4"
  },
  "resolutions": {
    "jquery": "^3.2.1"
  }
}

可以在最后再加入些从 plugins 切换来的依赖

    "jquery-validation": "^1.17.0",
    "datatables-plugins": "^1.10.15",
    "iCheck": "^1.0.2",
    "html5shiv": "^3.7.3",
    "respond": "Respond#^1.4.2",
    "datatables-i18n": "^1.0.4",
    "zTree": "^3.5.33",
    "switchery": "^0.8.2"

有版本冲突的话可以在最后的 resolutions 里面添加定义

  "resolutions": {
    "fastclick": "^1.0.6",
    "jquery": "^3.2.1"
  }

.bowerrc

{
  "directory" : "src/main/resources/static/bower_components",
  "allow_root": true
}

指定输出目录(默认根目录),并允许 root 执行(在 Linux 下打包用)

4.3 frontend-maven-plugin

使用 frontend-maven-plugin 来安装 Node 和 Bower。

在 pom 里面定义

    <properties>
        <frontend-maven-plugin.version>1.6</frontend-maven-plugin.version>
        <node.version>v8.10.0</node.version>
        <npm.version>5.6.0</npm.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>com.github.eirslett</groupId>
                <artifactId>frontend-maven-plugin</artifactId>
                <version>${frontend-maven-plugin.version}</version>
                <executions>
                    <execution>
                        <id>install node and npm</id>
                        <goals>
                            <goal>install-node-and-npm</goal>
                        </goals>
                        <configuration>
                            <nodeVersion>${node.version}</nodeVersion>
                            <npmVersion>${npm.version}</npmVersion>
                            <!-- if you don't need to download from these 3rd party registry, comments these -->
                            <nodeDownloadRoot>https://npm.taobao.org/mirrors/node/</nodeDownloadRoot>
                            <npmDownloadRoot>https://registry.npm.taobao.org/npm/-/</npmDownloadRoot>
                        </configuration>
                    </execution>
                    <execution>
                        <id>npm install</id>
                        <goals>
                            <goal>npm</goal>
                        </goals>
                        <configuration>
                            <npmInheritsProxyConfigFromMaven>false</npmInheritsProxyConfigFromMaven>
                        </configuration>
                    </execution>
                    <execution>
                        <id>bower install</id>
                        <goals>
                            <goal>bower</goal>
                        </goals>
                        <configuration>
                            <bowerInheritsProxyConfigFromMaven>false</bowerInheritsProxyConfigFromMaven>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>
  • install-node-and-npm: 安装 node 和 npm,并使用的淘宝镜像
  • npm: 执行 npm install,禁用 maven 的代理
  • bower: 执行 bower install,禁用 maven 的代理

这样就会在 static 目录创建出 bower_components 并下载好所有依赖,第一次比较慢,之后就快了。

运行 mvn spring-boot:run 就可以编译执行

使用本项目

clone 后,由于 master 分支是基于静态依赖,但是没有提交 bower_components 目录。可以:

  1. 第一种方式自己下载 AdminLTE 后解压该目录到 static 目录
  2. 第二种方式直接用 webjars 分支
  3. 第三种方式先切换到 bower 分支,编译完成就自动下载在 static 目录了,再切换回 static 目录或者直接使用 bower 分支

个人建议用 webjars 分支,如果对 node、bower 很熟悉也不在乎超多文件打包就使用 bower 分支。

详细的命令查看项目首页 README:https://github.com/yingw/bootiful-adminlte.git

点我阅读更多...

构建喊图片的“ASCII牛(COWSAY)”docker 镜像

构建喊图片的“ASCII牛(COWSAY)”docker 镜像

[toc]

COWSAY

cowsay 是一个生成ASCII图片的程序,显示一头牛的消息。它也可以使用预先制作的图像,以生成其他动物的图片,如Linux的吉祥物企鹅。由于它是用Perl编写的,它也适用于其他系统,如微软的Windows。有时,IRC、桌面截图和软件文档中会使用它。它更像黑客文化中的玩笑,但一段时间后,它也较常被一般人使用。在2007年,它被选为Debian的今日软件包。

简单的例子

$ cowsay "Hello, Yinguowei\!"
 ___________________
< Hello, Yinguowei! >
 -------------------
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

可能需要先安装:sudo apt-get install cowsay

fortune 命令

fortuen 是用来显示随机格言的一个 Linux 程序,用管道符把它和 cowsay 连起来: ```sh $ fortune | cowsay __________________________ /
| 现在,有右的东西影响我们,也有“左”的东西影响我们,但根深蒂固的还是“左”的东 | | 西 | | | \ - 邓小平 / —————————————————————————- \ ^
^ \ (oo)___ (__)\ )\/
||—-w | || ||


如果提示没有这个命令,可以先安装下:`sudo apt-get install fortune`

### 中文 fortune
默认显示的格言是英文的,如果对上图中文的感兴趣,可以参考阮一峰的[博客](http://www.ruanyifeng.com/blog/2015/04/fortune.html)

### 换个动物
我们还可以换好多可爱的小动物来喊麦

$ cowsay -f sheep “Im Shaun…” _____ < Im Shaun… > ————-

__
UooU.’@@@@@@. \__/(@@@@@@@@@@) (@@@@@@@@) YY~~~~YY’ || ||


支持的动物列表可以通过 `cowsay -l` 查看,其就是在 `/usr/share/cowsay/cows` 目录下的 `*.cow` 文件。

### 从源码编译 cowsay

GitHub 上 cowsay 的仓库有许多个,但是最老作为 Debian 发行的那个原版应该是[这个](https://github.com/tnalpgge/rank-amateur-cowsay) (看提交历史是从作者最早的 CVS 迁移来的,最早是 19 年前的代码!)

```sh
git clone https://github.com/tnalpgge/rank-amateur-cowsay.git

创建自定义的 cow

接下来开始做自己相关标识、商标的 ascii 图形

  • 当然可以自己画,也可以从图片转(后面会讲到),也可以从一些 ascii 图库的网站找一个,比如: ascii-code.comASCII Art Archive,再做一些修改:
  • 图形里的斜杠要替换为两个斜杠 ‘\\’
  • $thoughts 表示语言框的指引箭头 ‘\‘。其他还有些:$eyes 是眼睛,’oo’,$tongue 是舌头 ‘U’。
  • 有个小 bug:每一行不能以 ‘\’ 或空格结尾,否则这行当中的所有空格都会被删掉,简单处理只要在每行最后加点东西就行了。

我做的金龙鱼:

               \ |
                \|
     |\\\\_________
 /=_/            o \ <_
 |=_           (   v/
 |/ \__________+___/   (R)
     |///    |/|/

转成 cow 格式并放到 rank-amateur-cowsay/cows/arawana.cow

##
## A cow with an arawana, by yinguowei@gmail.com
##
$the_cow = <<EOC;
               $thoughts |
                $thoughts|
     |\\\\\\\\_________
 /=_/            o \\ <_
 |=_           (   v/
 |/ \\__________+___/   (R)
     |///    |/|/
EOC

打包为 docker 镜像或者 Linux 命令

重新打包 cowsay

mv rank-amateur-cowsay cowsay
tar -czvf ascii-cow/cowsay.tar.gz cowsay

编写 Dockerfile

FROM alpine
# install cowsay
ADD cowsay.tar.gz /tmp
RUN apk-install perl &&\
  cd /tmp/cowsay/ &&\
  echo | ./install.sh &&\
  rm -rf /tmp/cowsay
  • 注意 apk-installalpine Linux 的包管理工具,也可以转换成其他 Linux Docker 基础镜像的包管理工具。

我们也可以安装了 perl 来编译

yum install -y perl
./install.sh

编译完成后,就可以测试了:

$ cowsay -f arawana "Hello, Wilmar."

成功输出新的小龙鱼:

 ________________ 
< Hello, Wilmar. >
 ---------------- 
               \ | 
                \|
     |\\\\_________
 /=_/            o \ <_
 |=_           (   v/
 |/ \__________+___/   (R)
     |///    |/|/
     

接下来,我们开始创建彩色的 ascii 内容,并把图片直接转成 ascii。

im2a

im2a 是一个开源的图像转 ASCII 工具,支持256色终端。

安装 im2a

git clone https://github.com/tzvetkoff/im2a.git

源码编译安装

./bootstrap
./configure
make install

打包

tar -czvf ascii-cow/im2a.tar.gz im2a

或者可以:

在 docker 中编译安装

FROM alpine
# install im2a
ADD im2a.tar.gz /tmp
RUN apk-install imagemagick-dev &&\
  apk-install --virtual build-dependencies make autoconf automake libtool gawk gcc g++ ncurses-dev &&\
  cd /tmp/im2a/ &&\
  ./bootstrap &&\
  ./configure &&\
  ln -s /usr/lib/liblcms2.so.2 /usr/lib/liblcms2.so &&\
  ln -s /usr/lib/libfontconfig.so.1 /usr/lib/libfontconfig.so &&\
  ln -s /usr/lib/libfreetype.so.6 /usr/lib/libfreetype.so &&\
  ln -s /lib/libz.so.1 /lib/libz.so &&\
  touch Makefile.am &&\
  find . -exec touch {} \; &&\
  make clean &&\
  make install &&\
  rm -rf /tmp/im2a &&\
  apk del build-dependencies

测试一下

echo ${im2a $IM2A_ARGS -W "${WIDTH}" -H "${HEIGHT}" "${FILE}"}

最后,把喊话内容变成彩色的:

ascii-cow

ascii-cow Dockerfile 模板

基于 andrewmacheret 制作的基础镜像

git clone https://github.com/andrewmacheret/ascii-cow.git

和 cowsay 整合,用管道符连接

convert_image() {
  im2a $IM2A_ARGS -W "${WIDTH}" -H "${HEIGHT}" "${FILE}" |
    cowsay $COW_ARGS -n |
    perl -p -e 's/(([-_]){'"${WIDTH}"'})[-_]+/\1\2\2/' |
    perl -p -e 's/ +([|\/\\]) *$/ \1/'
}

定制 cows

重新编译 Dockerfile

mkdir node_modules
docker build -t yinguowei/ascii-cow .

如果不想重新编译进去新的小动物,也可以直接把 cow 文件拷贝到容器里的 cows 目录;甚至直接替换 default.cow 文件来让命令直接输出你想要的小动物:

npm install -g express
docker run -d yinguowei/ascii-cow
docker cp arawana.cow <CONTAINER_NAME|CONTAINER_ID>/usr/local/share/cows/

测试

docker run --rm -it yinguowei/ascii-cow ./ascii-cow.sh -u "https://avatars3.githubusercontent.com/u/1177503?v=3&s=230" -w 60

输入的原图是: image

转换输出的 ascii 图: image

设置终端使用白色字体的话: image

文本内容是这样的:

 ______________________________________________________________ 
/ KKKKKKKKKKd..;;;;;;;;;;;;;;;;;;;;;;;;;;,,...';..dKKKKKKKKKKK \
| KKKKKKKKO;..;;;,,;.'.',. .,;;'...'.     .',;;;,..oKKKKKXNXKK |
| KKKKKKKK0:.;,...                           ';;,. cMMMNMMMMMM |
| KKKKKKKKd; ,'    .c'.               ..;dl    .,,.oMMMMMMMMMM |
| KKKKKKKKO.,'.  .KMMWWWNX0Okl':kkOKXNWWWMMMl   .;;.NMMMMMMMMM |
| KKKKKKK0..,   lMMMMWWWWWWWWWWWWWWWWWWWWWMMMO   .;.OXWMMMMMMM |
| WWNNNXX0d.'  cMMMMWWWWWWWWWWWWWWWWWWWWWWWMMMx  .;.cKKXMMMMNK |
| WWMMMMMMo.'  NMMMWWWWWWWWWWWWWWWWWWWWWWWWWMMM. .,.KKKKKKKKKK |
| 00XMNXNNN.'  d0koclkXWWWWWWWWWWWWWWWWWWXXXWMN   ,.KKKKKKKKKK |
| 00NMK000Wl  'NOo;:;'..,oONWWWWWNkxo:,... ..l0O   :KKKKKK0OOO |
| 00MMK0O:ox   NMMXxooolclc:OWWWWk:loccloodO0WMW.   ::0KKKOkkk |
| WWMMXKc;dl. 'MMMxlNo',Odx0NWWWWWKOlXx''xk,0MMM. .:d;cKKKOkkk |
| XNMMWMl,xl;'WMMMMMMWXNWNKNWWWWWWWNXWNXNWNWMMMMk.;lx,:KKKOkkk |
| 0XMX00clXd,.XMMMMMWWWWWWWWXlNWWWWWWWWWWWWWMMMMX.,dXlcKKKkkkk |
| 0NMK00x.0ckdlMMMWWWWWWWWW0O:XWWWWWWWWWWWWWWMMMcdkc0.dOkkkkkk |
| NWMK00XccolN.MMMWWWWWWWWNklkOkKWWWWWWWWWWWWMMN.Ncoc,kkkkkkkk |
| WMMMMMMMo;k0.KMMWWWWWWWWWXXKKXXWWWWWWWWWWWMMMl:0O,:kkkkkkkkk |
| 0MWKXXMMMO'l'cMMMWWWWWOkldolkKddodkkNWWWWMMMk.co.'okkkkkkkkk |
| KMN000MMMKkxd.OMMMWWWNXKkO0KKKKK0Ok0XWWWMMMK,XXNMX.kkkkkkkkk |
| NMX00KMMM0kkkx;:KMMMWWWWWNXKKKKXNWWWWWWMMMk.0NNNWW.xkkkkkkkk |
| MMWNNWMMWkkkkkkx:;dNMMWWWWXdodxNWWWWWMM0c,c.OWNWWM.okkkkkkkk |
| XMWWWMMMWkkkkkkkkkd'.cxXWWWWWWWWWWWXx: ;xkkx,ckxdd:.lxkkkkkk |
| XMX00KMMNkkxo:;;;;; ,' '::coxkkdl:;. ,. ,,,,loxOKXXX0dc:xkkk |
| NMK00XMMXx,..'''''. ',,..;lxxxdc;'.',, .', oWWWWWWWWWWWK'okk |
| MMXKKNMMO .,'....'.. ,,,,. .0N' .,,,,. ..'.'XWWWWWWXxOXMN.xk |
| MMMMMMMM;.,,........ .,'  ..  ... .,, ..... ,llloooodXWMM'0N |
| MMMMMMMM..,'.........   ....  .....  ........ONNNNNNWWWWM.XM |
| MMMMMMMM..,'................  ...............ONWWWWWWNXNM,KM |
| MMMMMMMM..,'..............'.. .,,,,'..........:lllclokWWM.WM |
\ MMMMMMMM..,,.............''. ................ lO0NNNNNWWk:MM /
 -------------------------------------------------------------- 
        \   ^__^
         \  (oo)\_______
            (__)\       )\/\
                ||----w |
                ||     ||

看上去就是: image

开始试一下新的小动物:

$ url='http://www.wilmar-international.com/wp-content/themes/wilmar/assets/images/wilmar_logo.jpg'
$ docker run --rm -it yinguowei/ascii-cow ./ascii-cow.sh -u "$url" -w 80 -c "-f arawana"

原图: image

输出:

 __________________________________________________________________________________ 
/ MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM \
| MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM |
| MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMWKOkkk0NMMMWk:''',o0MN0kkkk0WMMMNx;''',dXMM |
| MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMKOkkkOXMMMMOc'...,cd0WMMM0o,...;xNMMMMM |
| MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMXOkkkkKNKOxl;'...,dkc'...:kWMMMMMMMM |
| MMMMMMMMMMMMMMMMMMMMMMMKKNMMNXXWMMMMMMMMMMMMMMMN0kkkkkOXMMXd;....'cOMMMMMMMMMMMM |
| MMMMMMMMMMMMMMMMMMMMMMNxx0MMOxx0MMMMMMMMMMMMMMMMMMWKNMMMMMMMMWkoKMMMMMMMMMMMMMMM |
| MMMMMMMMMMMMMMMMMMMMMMMWWMMM0ddKMMMMMMMWNWMMMWNNWMMMMMMWNNNWMMMMMMMMMMNMMMMMMMMM |
| MMMM0ddOMMkdddkMM0dxWMNdxkMM0dxXMMddxOKKxdx00K0xdxMMMkxkOOxdxNMM0ddKkxxMMMMMMMMM |
| MMMMMkddNKdxkddKWdxXMMNdxkMM0ddXMMxddMMMNddOMMM0ddKMMNMMMWOddOMMKddkMMMMMMMMMMMM |
| MMMMMWxdxxxXMkdxkd0MMMNdxkMM0dd0MMxddMMMWddOMMM0ddKMMKkxXWKddOMMXdd0MMMMMMMMMMMM |
| MMMMMMKxddOMMNxddkMMMMNdxkMM0dd0MMxddMMMWddkMMM0ddKM0dd0MM0ddOMMXddOMMMMMMMMMMMM |
| MMMMMMM000MMMMX00WMMMMW000MMX00KMM000MMMW000MMMK00XMMKOkOKW0kOXMN00KMMMMMMMMMMMM |
| MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM |
\ MMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMM /
 ---------------------------------------------------------------------------------- 
               \ |
                \|
     |\\\\_________
 /=_/            o \ <_
 |=_           (   v/
 |/ \__________+___/   (R)
     |///    |/|/

下载 PDF, 截图1, 截图2, 文本.

截图: image image image

最后,如果对你的镜像满意的话,提交到 Docker Hub 共享给你的团队吧!

链接

点我阅读更多...

Dubbo 2.5.3 学习笔记

Dubbo 2.5.3 学习笔记

Dubbo 介绍

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

本文写于 17 年初,当时的 Dubbo 基本已经不再更新一段时间,版本是 2.5.3,17 年底的时候捐献给了 Apache 孵化项目,又开始更新。新的官网 (http://dubbo.apache.org/)

架构图:

节点角色说明:

  • Provider: 暴露服务的服务提供方。
  • Consumer: 调用远程服务的服务消费方。
  • Registry: 服务注册与发现的注册中心。
  • Monitor: 统计服务的调用次调和调用时间的监控中心。
  • Container: 服务运行容器。

项目 URL:

  • 源码:https://github.com/alibaba/dubbo 新地址:https://github.com/apache/incubator-dubbo
  • 下载:http://repo1.maven.org/maven2/com/alibaba/dubbo
  • http://repo1.maven.org/maven2/com/alibaba/dubbo/2.5.3/
  • 微博:http://weibo.com/dubbo

当前版本 2.5.3, 23 Oct 2012

Zookeeper

Zookeeper 的介绍

Zookeeper (http://zookeeper.apache.org/) 一般作为 Dubbo 的注册中心,当前版本 3.4.9

文档:https://zookeeper.apache.org/doc/current/zookeeperStarted.html

运行 Zookeeper

下载 (3.4.9 老地址已失效,最新地址:https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.12/zookeeper-3.4.12.tar.gz)

$ wget https://mirrors.tuna.tsinghua.edu.cn/apache/zookeeper/zookeeper-3.4.9/zookeeper-3.4.9.tar.gz
$ tar -zxvf zookeeper-3.4.9.tar.gz

创建配置文件 zoo.cfg

$ cp conf/zoo_sample.cfg conf/zoo.cfg

设置 dataDir 和 dataLogDir :

dataDir=/home/yin/Dubbo/zookeeper-3.4.9/data
dataLogDir=/home/yin/Dubbo/zookeeper-3.4.9/logs

其他参数如:

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181

启动:

$ cd ~/Dubbo/zookeeper-3.4.9/bin/
$ ./zkServer.sh start

检查状态:

$ ./zkServer.sh status

停止服务

$ ./zkServer.sh stop

查看进程

$ jps

有个进程:QuorumPeerMain

zkCli 连接到 ZooKeeper 服务

$ bin/zkCli.sh -server 127.0.0.1:2181

运行复制的 ZooKeeper

Zoo.cfg

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

在文件 data/myid 里设置 id,文件内容就一个 id:

1

Zkclient

有多种 Zookeeper 的客户端程序

com.github.adyliu zkclient 2.1.1

支持 zk 3.4.5, 最后更新日期 2013 年 https://github.com/adyliu/zkclient

<dependency>
    <groupId>com.github.adyliu</groupId>
    <artifactId>zkclient</artifactId>
    <version>2.1.1</version>
</dependency>

com.101tec zkclient 0.10

https://github.com/sgroschupf/zkclient 支持 zookeeper 3.4.8, Dubbo 官方推荐的 最后更新: 2016

<dependency>
    <groupId>com.101tec</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.10</version>
</dependency>

com.github.sgroschupf zkclient 0.1

(last update: 2011, same author as 101tec, subbort zk 3.3.3) https://github.com/sgroschupf/zkclient

<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>

Apache Curator

https://github.com/Netflix/curator http://curator.apache.org/ http://blog.csdn.net/lzy_lizhiyang/article/details/48518731

Dubbo Admin

老版本下载:dubbo-admin-2.5.3.war,新版本在这里:https://github.com/apache/incubator-dubbo-ops

Using Tomcat: $ unzip dubbo-admin-2.5.3.war -d ROOT

Edit WEB-INF/dubbo.properties

dubbo.registry.address=zookeeper://10.229.15.96:2181
dubbo.admin.root.password=root
dubbo.admin.guest.password=guest

注意当前版本的 Dubbo Admin 只能使用 jdk1.7 (不能使用 1.8). See: http://www.cnblogs.com/digdeep/p/5205537.html

在 Tomcat 的 catalina.bat and setclasspath.bat 里设置:

set JAVA_HOME=D:\Tools\jdk1.7.0_80
set JRE_HOME=D:\Tools\jdk1.7.0_80\jre

设置 host,启动

$ cd ~/Dubbo/dubbo-admin/bin
$ ./startup.sh

访问 http://devops.wilmar.cn:8787 用账号 root/root 登入

(小 Bug:如果发布到非 ROOT 上下文,比如: http://localhost:8787/dubbo-admin-2.5.3 ,有些连接会失效,建议发布到 ROOT,或者修复连接:WEB-INF\templates\sysinfo\layout\default.vm 文件里,修改 onclick="window.location.href='/sysinfo/$tab';"onclick="window.location.href='$rootContextPath.getURI("/sysinfo/$tab")';" )

Dubbo Monitor

Dubbo 的监控程序,当前版本 2.5.3

$ tar -zxvf dubbo-monitor-simple-2.5.3-assembly.tar.gz

编辑 /home/yin/Dubbo/dubbo-monitor-simple-2.5.3/conf/dubbo.properties

dubbo.container=log4j,spring,registry,jetty
dubbo.application.name=simple-monitor
dubbo.application.owner=
#dubbo.registry.address=multicast://224.5.6.7:1234
dubbo.registry.address=zookeeper://127.0.0.1:2181
#dubbo.registry.address=redis://127.0.0.1:6379
#dubbo.registry.address=dubbo://127.0.0.1:9090
dubbo.protocol.port=7070
dubbo.jetty.port=8686
dubbo.jetty.directory=${user.home}/Dubbo/dubbo-monitor-simple-2.5.3
dubbo.charts.directory=${dubbo.jetty.directory}/charts
dubbo.statistics.directory=${user.home}/monitor/statistics
dubbo.log4j.file=logs/dubbo-monitor-simple.log
dubbo.log4j.level=WARN

Eg: dubbo.registry.address=zookeeper://10.135.108.152:2181?backup=10.135.108.153:2181,10.135.108.154:2181

$ cd ~/Dubbo/dubbo-monitor-simple-2.5.3/bin/
$ ./start.sh

http://devops.wilmar.cn:8686/

Set in app:

<!-- monitor -->
<dubbo:monitor protocol="registry" />

Provider App

Maven 依赖

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>dubbo</artifactId>
    <version>2.5.3</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
        </exclusion>
    </exclusions>
</dependency>

zookeeper:

<dependency>
    <groupId>org.apache.zookeeper</groupId>
    <artifactId>zookeeper</artifactId>
    <version>3.4.9</version>
    <exclusions>
        <exclusion>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
        </exclusion>
        <exclusion>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
        </exclusion>
    </exclusions>
</dependency>

<dependency>
    <groupId>com.github.sgroschupf</groupId>
    <artifactId>zkclient</artifactId>
    <version>0.1</version>
</dependency>

spring-dubbo.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: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="dubbo-provider"/>

    <!-- 使用multicast广播注册中心暴露服务地址 -->
<!--    <dubbo:registry address="multicast://224.5.6.7:1234"/>-->
    <dubbo:registry address="zookeeper://10.229.15.96:2181" check="false" subscribe="false" register=""/>
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880"/>

    <!-- 声明需要暴露的服务接口 -->
    <dubbo:service interface="cn.wilmar.api.HelloService" ref="helloService"/>

</beans>

App

@SpringBootApplication
@ImportResource({"classpath:spring-dubbo.xml"})
public class HelloProviderApplication {

Some service:

@Service("helloService")
public class HelloServiceImpl implements HelloService {

Consumer App

<?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="dubbo-consumer"  />

    <!-- 使用multicast广播注册中心暴露发现服务地址 -->
<!--
    <dubbo:registry address="multicast://224.5.6.7:1234" />
-->
    <dubbo:registry address="zookeeper://10.229.15.96:2181"/>
    <!--can't add:  check="false" subscribe="false"
    register=""-->
    <!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
    <dubbo:reference id="helloService" interface="cn.wilmar.api.HelloService" />

</beans>

Close check at startup:

<!-- 生成远程服务代理,可以和本地bean一样使用demoService -->
<dubbo:reference id="helloService" interface="cn.wilmar.api.HelloService" check="false" />

注入 Service:

@Autowired
HelloService helloService;

Cache

<dubbo:reference id="helloService" interface="cn.wilmar.api.HelloService" check="false" cache="true" />

Cluster: http://blog.csdn.net/zuoanyinxiang/article/details/50977072

<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="cn.wilmar.api.HelloService" ref="helloService" cluster="failover"/>

Loadbalance

<!-- 声明需要暴露的服务接口 -->
<dubbo:service interface="cn.wilmar.api.HelloService" ref="helloService" cluster="failover" loadbalance="random"/>

Multicast Register http://blog.csdn.net/zuoanyinxiang/article/details/50980106

<dubbo:registry address="multicast://224.5.6.7:1234"/>
<dubbo:registry address="zookeeper://10.229.15.96:2181" check="false" subscribe="false"
                register="" default="false"/>

只订阅(不注册) 适用开发环境开发 <dubbo:registry server=”” register=”false”

在reference里面(订阅)加上url指定dubbo服务 (但是不适合代码提交,可以用jvm参数)

只注册(不订阅) Subscribe=”false”

其他关于Dubbo的学习,必看的资料:

  • 用户指南
  • 开发指南
  • 管理指南
  • 常见问题 其实就是首页http://dubbo.io/ 下面的四个链接,里面内容编排比较乱,都看就是了 在下载栏目里的大部分下载地址都失效了,我东拼西凑找了差不多,放在: http://pan.baidu.com/s/1kVfTj2f

国内还吴水成架构师做的培训视频:http://pan.baidu.com/s/1i5DhkmL

点我阅读更多...