? 今天云南11选五5玩法:真正决定人生高度的,是你做事的速度 - ◆昨天云南十一选五开奖◆
  • 2017年度一级建造师考试成绩已发布 2019-03-19
  • 淮南选出54名代表出席省工会十四大 2019-03-19
  • 特朗普让俄重返G7遭5国反对 唯独安倍表态我理解 2019-03-14
  • 2018年军队院校报考指南 军校在山西省计划招生396人 2019-03-14
  • 你知道端午节的来历吗? 2019-03-13
  • 中外藏学专家齐聚西藏畅谈古象雄文化 2019-03-13
  • 自治区明确新生儿疾病筛查两项目价格 2019-03-07
  • 中美科学家在三峡地区发现世界最早动物足迹化石 2019-01-27
  • 百公里加速仅3.4s!宝马全新M5于3月22日上市 2018-12-12
  • 今天云南11选五5玩法:真正决定人生高度的,是你做事的速度

    昨天云南十一选五开奖 www.wahbn.com 小说:真正决定人生高度的,是你做事的速度作者:扁开更新时间:2019-03-25字数:16852

    Spring的简史

    第一阶段:XML配置,在Spring1.x时代,使用Spring开发满眼都是xml配置的Bean,随着项目的扩大,我们需要把xml配置文件分放到不同的配置文件里,那时候需要频繁的在开发的类和配置文件之间切换。

    第二阶段:注解配置,在Spring2.x时代,Spring提供声明Bean的注解,大大减少了配置量。应用的基本配置用xml,业务配置用注解。

    第三阶段:Java配置,从Spring3.x到现在,Spring提供了Java配置,使用Java配置可以让你更理解你所配置的Bean。

    Spring Boot:使用“习惯优于配置”的理念让你的项目快速运行起来。使用Spring Boot很容易创建一个独立运行、准生产级别的基于Spring框架的项目,使用Spring Boot你可以不用或者只需要很少的Spring配置。

    下面就来使用Spring Boot一步步搭建一个前后端分离的应用开发框架,并且以后不断的去完善这个框架,往里面添加功能。后面以实战为主,不会介绍太多概念,取而代之的是详细的操作。

    ?

    零、开发技术简介

    开发平台:windows

    开发工具:Intellij IDEA 2017.1

    JDK:Java 8

    Maven:maven-3.3.9

    服务器:tomcat 8.0

    数据库:MySQL 5.7

    数据源:Druid1.1.6

    缓存:Redis 3.2

    日志框架:SLF4J+Logback

    Spring Boot:1.5.7.RELEASE

    ORM框架:MyBatis+通用Mapper

    Spring Boot官方文档:Spring Boot Reference Guide

    ?

    一、创建项目

    这一节创建项目的基础结构,按照spring boot的思想,将各个不同的功能按照starter的形式拆分开来,做到灵活组合,并简单介绍下Spring Boot相关的东西。

    1、创建工程

    ① 通过File > New > Project,新建工程,选择Spring Initializr,然后Next。

    ② 尽量为自己的框架想个好点的名字,可以去申请个自己的域名。我这里项目名称为Sunny,项目路径为com.lyyzoo.sunny。

    ③ 这里先什么都不选,后面再去集成。注意我的Spring Boot版本为1.5.9。Next

    ④ 定义好工程的目录,用一个专用目录吧,不要在一个目录下和其它东西杂在一起。之后点击Finish。

    上面说的这么详细,只有一个目的,从一个开始就做好规范。

    ⑤ 生成的项目结构如下,可以自己去看下pom.xml里的内容。

    2、创建Starter

    先创建一个core核心、cache缓存、security授权认证,其它的后面再集成进去。

    跟上面一样的方式,在Sunny下创建sunny-starter-core、sunny-starter-cache、sunny-starter-security子???。

    这样分??楹?,我们以后需要哪个??榫鸵肽母瞿?榧纯?,如果哪个??椴宦阈枨?,还可以重写该???。

    最终的项目结构如下:

    3、启动项目

    首先在core??橄吕雌舳⒘私釹pringBoot项目。

    ① 在com.lyyzoo.core根目录下,有一个SunnyStarterCoreApplication,这是SpringBoot的入口类,通常是*Application的命名。

    入口类里有一个main方法,其实就是一个标准的Java应用的入口方法。在main方法中使用SpringApplication.run启动Spring Boot项目。

    然后看看@SpringBootApplication注解,@SpringBootApplication是Spring Boot的核心注解,是一个组合注解。

    @EnableAutoConfiguration让Spring Boot根据类路径中的jar包依赖为当前项目进行自动配置。

    Spring Boot会自动扫描@SpringBootApplication所在类的同级包以及下级包里的Bean。

    ② 先启动项目,这里可以看到有一个Spring Boot的启动程序,点击右边的按钮启动项目??吹娇刂铺⊿pring的标志,就算是启动成功了。

    ③ 替换默认的banner

    可以到//patorjk.com/software/taag/这个网站生成一个自己项目的banner。创建banner.txt并放到resources根目录下。

    4、Spring Boot 配置

    ① 配置文件

    Spring Boot使用一个全局的配置文件application.properties或application.yaml,放置在src/main/resources目录下。我们可以在这个全局配置文件中对一些默认的配置值进行修改。

    具体有哪些配置可到官网查找,有非常多的配置,不过大部分使用默认即可。Common application properties

    然后,需要为不同的环境配置不同的配置文件,全局使用application-{profile}.properties指定不同环境配置文件。

    我这里增加了开发环境(dev)和生产环境(prod)的配置文件,并通过在application.properties中设置spring.profiles.active=dev来指定当前环境。

    ② starter pom

    Spring Boot为我们提供了简化开发绝大多数场景的starter pom,只要使用了应用场景所需的starter pom,无需繁杂的配置,就可以得到Spring Boot为我们提供的自动配置的Bean。

    后面我们将会通过加入这些starter来一步步集成我们想要的功能。具体有哪些starter,可以到官网查看:Starters

    ③ 自动配置

    Spring Boot关于自动配置的源码在spring-boot-autoconfigure中如下:

    我们可以在application.properties中加入debug=true,查看当前项目中已启用和未启用的自动配置。

    我们在application.properties中的配置其实就是覆盖spring-boot-autoconfigure里的默认配置,比如web相关配置在web包下。

    常见的如HttpEncodingProperties配置http编码,里面自动配置的编码为UTF-8。

    MultipartProperties,上传文件的属性,设置了上传最大文件1M。

    ServerProperties,配置内嵌Servlet容器,配置端口、contextPath等等。

    之前说@SpringBootApplication是Spring Boot的核心注解,但他的核心功能是由@EnableAutoConfiguration注解提供的。

    @EnableAutoConfiguration注解通过@Import导入配置功能,在AutoConfigurationImportSelector中,通过SpringFactoriesLoader.loadFactoryNames扫描META-INF/spring.factories文件。

    在spring.factories中,配置了需要自动配置的类,我们也可以通过这种方式添加自己的自动配置。

    在spring-boot-autoconfigure下就有一个spring.factories,如下:

    说了这么多,只为说明一点,Spring Boot为我们做了很多自动化的配置,搭建快速方便。

    但是,正因为它为我们做了很多事情,就有很多坑,有时候,出了问题,我们可能很难找出问题所在,这时候,我们可能就要考虑下是否是自动配置导致的,有可能配置冲突了,或者没有使用上自定义的配置等等。

    5、项目结构划分

    core是项目的核心???,结构初步规划如下:

     base是项目的基础核心,定义一些基础类,如BaseController、BaseService等;

    ??? cache是缓存相关;

    ??? config是配置中心,??樗械呐渲梅诺絚onfig里统一管理;

    ??? constants里定义系统的常量。

    ??? exception里封装一些基础的异常类;

     system是系统???;

    ??? util里则是一些通用工具类;

    ?

    二、基础结构功能

    1、web支持

    只需在pom.xml中加入spring-boot-starter-web的依赖即可。

    之后,查看POM的依赖树(插件:Maven Helper),可以看到引入了starter、tomcat、web支持等??梢钥闯?,Sping Boot内嵌了servlet容器,默认tomcat。

    自动配置在WebMvcAutoConfiguration和WebMvcProperties里,可自行查看源码,一般我们不需添加其他配置就可以启动这个web项目了。

    2、基础功能

    在core中添加一些基础的功能支持。

    ① 首先引入一些常用的依赖库,主要是一些常用工具类,方便以后的开发。

     1 <!-- ******************************* 常用依赖库 ********************************** -->
     2 <!-- 针对开发IO流功能的工具类库 -->
     3 <dependency>
     4     <groupId>commons-io</groupId>
     5     <artifactId>commons-io</artifactId>
     6     <version>${commons.io.version}</version>
     7 </dependency>
     8 <!-- 文件上传 -->
     9 <dependency>
    10     <groupId>commons-fileupload</groupId>
    11     <artifactId>commons-fileupload</artifactId>
    12     <version>${commons.fileupload.version}</version>
    13     <exclusions>
    14         <exclusion>
    15             <groupId>commons-io</groupId>
    16             <artifactId>commons-io</artifactId>
    17         </exclusion>
    18     </exclusions>
    19 </dependency>
    20 <!-- 常用的集合操作,丰富的工具类 -->
    21 <dependency>
    22     <groupId>commons-collections</groupId>
    23     <artifactId>commons-collections</artifactId>
    24     <version>${commons.collections.version}</version>
    25 </dependency>
    26 <!-- 操作javabean的工具包 -->
    27 <dependency>
    28     <groupId>commons-beanutils</groupId>
    29     <artifactId>commons-beanutils</artifactId>
    30     <version>${commons.beanutils.version}</version>
    31     <exclusions>
    32         <exclusion>
    33             <groupId>commons-collections</groupId>
    34             <artifactId>commons-collections</artifactId>
    35         </exclusion>
    36     </exclusions>
    37 </dependency>
    38 <!-- 包含一些通用的编码解码算法. 如:MD5、SHA1、Base64等 -->
    39 <dependency>
    40     <groupId>commons-codec</groupId>
    41     <artifactId>commons-codec</artifactId>
    42     <version>${commons.codec.version}</version>
    43 </dependency>
    44 <!-- 包含丰富的工具类如 StringUtils -->
    45 <dependency>
    46     <groupId>org.apache.commons</groupId>
    47     <artifactId>commons-lang3</artifactId>
    48     <version>${commons.lang3.version}</version>
    49 </dependency>
    50 <!--
    51     Guava工程包含了若干被Google的Java项目广泛依赖的核心库. 集合[collections] 、缓存[caching] 、原生类型支持[primitives support] 、
    52     并发库[concurrency libraries] 、通用注解[common annotations] 、字符串处理[string processing] 、I/O 等等。
    53 -->
    54 <dependency>
    55     <groupId>com.google.guava</groupId>
    56     <artifactId>guava</artifactId>
    57     <version>${guava.version}</version>
    58 </dependency>
    View Code

    版本号如下:

    ② 在base添加一个Result类,作为前端的返回对象,Controller的直接返回对象都是Result。

    package com.lyyzoo.core.base;
    
    import com.fasterxml.jackson.annotation.JsonInclude;
    
    import java.io.Serializable;
    
    /**
     * 前端返回对象
     *
     * @version 1.0
     * @author bojiangzhou 2017-12-28
     */
    public class Result implements Serializable {
        private static final long serialVersionUID = 1430633339880116031L;
    
        /**
         * 成功与否标志
         */
        private boolean success = true;
        /**
         * 返回状态码,为空则默认200.前端需要拦截一些常见的状态码如403、404、500等
         */
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private Integer status;
        /**
         * 编码,可用于前端处理多语言,不需要则不用返回编码
         */
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private String code;
        /**
         * 相关消息
         */
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private String msg;
        /**
         * 相关数据
         */
        @JsonInclude(JsonInclude.Include.NON_NULL)
        private Object data;
    
    
        public Result() {}
    
        public Result(boolean success) {
            this.success = success;
        }
    
        public Result(boolean success, Integer status) {
            this.success = success;
            this.status = status;
        }
    
        public Result(boolean success, String code, String msg){
            this(success);
            this.code = code;
            this.msg = msg;
        }
    
        public Result(boolean success, Integer status, String code, String msg) {
            this.success = success;
            this.status = status;
            this.code = code;
            this.msg = msg;
        }
    
        public Result(boolean success, String code, String msg, Object data){
            this(success);
            this.code = code;
            this.msg = msg;
            this.data = data;
        }
    
        public boolean isSuccess() {
            return success;
        }
    
        public void setSuccess(boolean success) {
            this.success = success;
        }
    
        public Integer getStatus() {
            return status;
        }
    
        public void setStatus(Integer status) {
            this.status = status;
        }
    
        public String getCode() {
            return code;
        }
    
        public void setCode(String code) {
            this.code = code;
        }
    
        public String getMsg() {
            return msg;
        }
    
        public void setMsg(String msg) {
            this.msg = msg;
        }
    
        public Object getData() {
            return data;
        }
    
        public void setData(Object data) {
            this.data = data;
        }
    }
    View Code

    之后在util添加生成Result的工具类Results,用于快速方便的创建Result对象。

    package com.lyyzoo.core.util;
    
    import com.lyyzoo.core.base.Result;
    
    /**
     * Result生成工具类
     *
     * @version 1.0
     * @author bojiangzhou 2017-12-28
     */
    public class Results {
    
        protected Results() {}
    
        public static Result newResult() {
            return new Result();
    
        }
    
        public static Result newResult(boolean success) {
            return new Result(success);
        }
    
        //
        // 业务调用成功
        // ----------------------------------------------------------------------------------------------------
        public static Result success() {
            return new Result();
        }
    
        public static Result success(String msg) {
            return new Result(true, null, msg);
        }
    
        public static Result success(String code, String msg) {
            return new Result(true, code, msg);
        }
    
        public static Result successWithStatus(Integer status) {
            return new Result(true, status);
        }
    
        public static Result successWithStatus(Integer status, String msg) {
            return new Result(true, status, null, msg);
        }
    
        public static Result successWithData(Object data) {
            return new Result(true, null, null, data);
        }
    
        public static Result successWithData(Object data, String msg) {
            return new Result(true, null, msg, data);
        }
    
        public static Result successWithData(Object data, String code, String msg) {
            return new Result(true, code, msg, data);
        }
    
        //
        // 业务调用失败
        // ----------------------------------------------------------------------------------------------------
        public static Result failure() {
            return new Result(false);
        }
    
        public static Result failure(String msg) {
            return new Result(false, null, msg);
        }
    
        public static Result failure(String code, String msg) {
            return new Result(false, code, msg);
        }
    
        public static Result failureWithStatus(Integer status) {
            return new Result(false, status);
        }
    
        public static Result failureWithStatus(Integer status, String msg) {
            return new Result(false, status, null, msg);
        }
    
        public static Result failureWithData(Object data) {
            return new Result(false, null, null, data);
        }
    
        public static Result failureWithData(Object data, String msg) {
            return new Result(false, null, msg, data);
        }
    
        public static Result failureWithData(Object data, String code, String msg) {
            return new Result(false, code, msg, data);
        }
    
    }
    View Code

    ③ 在base添加BaseEnum<K, V>枚举接口,定义了获取值和描述的接口。

     1 package com.lyyzoo.core.base;
     2 
     3 /**
     4  * 基础枚举接口
     5  *
     6  * @version 1.0
     7  * @author bojiangzhou 2017-12-31
     8  */
     9 public interface BaseEnum<K, V> {
    10 
    11     /**
    12      * 获取编码
    13      *
    14      * @return 编码
    15      */
    16     K code();
    17 
    18     /**
    19      * 获取描述
    20      * 
    21      * @return 描述
    22      */
    23     V desc();
    24 
    25 }
    View Code

    然后在constants下定义一个基础枚举常量类,我们把一些描述信息维护到枚举里面,尽量不要在代码中直接出现魔法值(如一些编码、中文等),以后的枚举常量类也可以按照这种模式来写。

     1 package com.lyyzoo.core.constants;
     2 
     3 import com.lyyzoo.core.base.BaseEnum;
     4 
     5 import java.util.HashMap;
     6 import java.util.Map;
     7 
     8 /**
     9  * 基础枚举值
    10  *
    11  * @version 1.0
    12  * @author bojiangzhou 2018-01-01
    13  */
    14 public enum BaseEnums implements BaseEnum<String, String> {
    15 
    16     SUCCESS("request.success", "请求成功"),
    17 
    18     FAILURE("request.failure", "请求失败"),
    19 
    20     OPERATION_SUCCESS("operation.success", "操作成功"),
    21 
    22     OPERATION_FAILURE("operation.failure", "操作失败"),
    23 
    24     ERROR("system.error", "系统异常"),
    25 
    26     NOT_FOUND("not_found", "请求资源不存在"),
    27 
    28     FORBIDDEN("forbidden", "无权限访问"),
    29 
    30     VERSION_NOT_MATCH("record_not_exists_or_version_not_match", "记录版本不存在或不匹配"),
    31 
    32     PARAMETER_NOT_NULL("parameter_not_be_null", "参数不能为空");
    33 
    34     private String code;
    35 
    36     private String desc;
    37 
    38     private static Map<String, String> allMap = new HashMap<>();
    39 
    40     BaseEnums(String code, String desc) {
    41         this.code = code;
    42         this.desc = desc;
    43     }
    44 
    45     static {
    46         for(BaseEnums enums : BaseEnums.values()){
    47             allMap.put(enums.code, enums.desc);
    48         }
    49     }
    50 
    51     @Override
    52     public String code() {
    53         return code;
    54     }
    55 
    56     @Override
    57     public String desc() {
    58         return desc;
    59     }
    60 
    61     public String desc(String code) {
    62         return allMap.get(code);
    63     }
    64 
    65 }
    View Code

    ④ 再添加一个常用的日期工具类对象,主要包含一些常用的日期时间格式化,后续可再继续往里面添加一些公共方法。

      1 package com.lyyzoo.core.util;
      2 
      3 
      4 import org.apache.commons.lang3.StringUtils;
      5 import org.apache.commons.lang3.time.DateUtils;
      6 
      7 import java.text.ParseException;
      8 import java.text.SimpleDateFormat;
      9 import java.util.Date;
     10 
     11 /**
     12  * 日期时间工具类
     13  *
     14  * @version 1.0
     15  * @author bojiangzhou 2017-12-28
     16  */
     17 public class Dates {
     18 
     19     /**
     20      * 日期时间匹配格式
     21      */
     22     public interface Pattern {
     23         //
     24         // 常规模式
     25         // ----------------------------------------------------------------------------------------------------
     26         /**
     27          * yyyy-MM-dd
     28          */
     29         String DATE = "yyyy-MM-dd";
     30         /**
     31          * yyyy-MM-dd HH:mm:ss
     32          */
     33         String DATETIME = "yyyy-MM-dd HH:mm:ss";
     34         /**
     35          * yyyy-MM-dd HH:mm
     36          */
     37         String DATETIME_MM = "yyyy-MM-dd HH:mm";
     38         /**
     39          * yyyy-MM-dd HH:mm:ss.SSS
     40          */
     41         String DATETIME_SSS = "yyyy-MM-dd HH:mm:ss.SSS";
     42         /**
     43          * HH:mm
     44          */
     45         String TIME = "HH:mm";
     46         /**
     47          * HH:mm:ss
     48          */
     49         String TIME_SS = "HH:mm:ss";
     50 
     51         //
     52         // 系统时间格式
     53         // ----------------------------------------------------------------------------------------------------
     54         /**
     55          * yyyy/MM/dd
     56          */
     57         String SYS_DATE = "yyyy/MM/dd";
     58         /**
     59          * yyyy/MM/dd HH:mm:ss
     60          */
    漫谈儿童的不适应行为及治疗 我看目前很火的IT小说。。。 “头上长草”是个什么梗? 佛家经典禅语 【现代诗歌】趁 灰姑娘是如何教我们不劳而获的 你相信这超凡脱俗的爱情吗? 38D、梦姑、倒追女与万能USB 罗李华:双鱼座2016年运势 传奇影星夏梦:一生光影梦,绝代有佳人

    86698 91454 44658 71701 42670 18600 79745 36800 30025 86494 66109 78672 32986 99640 36877 15830 29190 80656 46867 93797 92529 10672 88936

    我要说两句: (0人参与)

    发布
  • 2017年度一级建造师考试成绩已发布 2019-03-19
  • 淮南选出54名代表出席省工会十四大 2019-03-19
  • 特朗普让俄重返G7遭5国反对 唯独安倍表态我理解 2019-03-14
  • 2018年军队院校报考指南 军校在山西省计划招生396人 2019-03-14
  • 你知道端午节的来历吗? 2019-03-13
  • 中外藏学专家齐聚西藏畅谈古象雄文化 2019-03-13
  • 自治区明确新生儿疾病筛查两项目价格 2019-03-07
  • 中美科学家在三峡地区发现世界最早动物足迹化石 2019-01-27
  • 百公里加速仅3.4s!宝马全新M5于3月22日上市 2018-12-12