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

02 SpringBoot核心

2018-12-24 13:17 41 查看

文章目录

  • SpringBoot基本配置
  • 外部文件配置
  • 日志配置
  • Profile配置
  • SpringBoot打包出一个可执行jar
  • Spring Boot运行原理
  • 原理简介

    随着JavaEE的不断壮大,Java的开发变得越来越复杂,这里的复杂,指的是写代码的方式。
    配置文件一大堆,各种xml,properties。与其他项目进行整合集成的时候,也越来越不方便。

    这个时候SpringBoot的出现,为解决上述问题提供了一个方案,可以说,是SpringBoot挽救了Java在服务端开发的陌路。

    但是SpringBoot本身,是没有引入新技术的,其主要是基于Spring4中的条件注解特性,将原先需要编程人员手动操作的代码,统一集成到了内部,并且提供外部配置,同时兼顾了灵活性与简单性。

    系统条件注解工具

    条件注解 说明
    @ConditionalOnBean 指定Bean是否存在
    @ConditionalOnClass 类路径下存在指定类
    @ConditionalOnCloudPlatform 是否是分布式平台
    @ConditionalOnExpression 由SpEL表达式决定
    @ConditionalOnJava JVM版本
    @ConditionalOnJndi 在JNDI存在的条件下查找指定的位置
    @ConditionalOnMissingBean 类路径缺失Bean的情况下
    @ConditionalOnMissingClass 类路径缺失Class的情况下
    @ConditionalOnNotWebApplication 非web环境
    @ConditionalOnProperty 指定属性是否有指定的值
    @ConditionalOnResource 类路径是否有指定的值
    @ConditionalOnSingleCandidate 指定Bean在容器中只有一个,
    或者指定首选Bean
    @ConditionalOnWebApplication 当前是web环境

    概述

    Spring Boot解决了什么问题

    Java开发越来越笨重

    • 配置多
    • 部署复杂
    • 第三方集成复杂

    Spring Boot 核心功能

    • Spring Boot可以以jar包的形式独立运行,运行一个Spring Boot项目只需要通过java -jar xx.jar 来运行
    • Spring Boot可以选择内嵌Tomcat、Jetty、Undertow,无需以war包形式部署
    • Spring Boot提供starter pom来简化Maven的依赖加载
    • Spring Boot提供基于http、ssh、telnet对运行时项目的监控
    • 无代码生成和xml配置

    优缺点

    优点

    • 快速构建项目
    • 对主流开发框架无缝集成
    • 可独立运行项目,无需外部依赖Servlet容器
    • 运行时应用监控
    • 极大提高开发、部署效率
    • 与云计算天然集成

    缺点

    • 学习资料少
    • 如果Spring,特别是Spring4基础不扎实,对Spring Boot原理会弄不清

    快速构建

    Spring Boot可以使用Maven和Gradle作为项目构建
    部署形式可以是jar或war
    JDK最低要求1.6
    支持以Groovy语言开发

    使用IDEA,可以很自动化的构建一个SpringBoot项目,但其本质上还是一个Maven项目

    如果网络有问题的话,可以手动构建

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.zln.learning.spboot</groupId>
    <artifactId>spboot-demo01</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>spboot-demo01</name>
    <description>Demo project for Spring Boot</description>
    <!--Spring Boot项目必须添加这个父级依赖-->
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
    </properties>
    <!--添加starter和其他需要的依赖-->
    <dependencies>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <scope>test</scope>
    </dependency>
    </dependencies>
    <build>
    <plugins>
    <!--添加Spring Boot的编译插件-->
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
    </plugins>
    </build>
    </project>

    上面的pom,添加的依赖并不多,但是实际上依赖很多

    • HelloWorld
    package org.zln.learning.spboot;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    @SpringBootApplication
    @RestController
    public class SpbootDemo01Application {
    @RequestMapping("/")
    String index() {
    return "Hello Spring Boot";
    }
    public static void main(String[] args) {
    SpringApplication.run(SpbootDemo01Application.class, args);
    }
    }

    代码说明

    • @SpringBootApplication
      ​ Spring Boot的核心注解,主要目的就是开启自动配置

    SpringBoot基本配置

    @SpringBootApplication

    Spring Boot 通常有一个名为 *Application 的入口类,

    入口类中的Main方法启动整个Spring Boot项目

    @SpringBootApplication是SpringBoot的核心注解,从他的源码中可以看到,

    它有一个@EnableAutoConfiguration注解;

    @EnableAutoConfiguration让SpringBoot根据类路径中的jar,

    为当前项目进行自动配置

    如:添加了spring-boot-starter-web依赖,则自动添加Tomcat和Spring MVC的依赖,

    然后Spring Boot会对Tomcat和SpringMVC进行自动配置

    Spring Boot自动扫描与@SpringBootApplication所在的同级包及其下级包的Bean

    建议入口类位置放在 groupId+arctifactId组合的包名下

    @Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration
    @EnableAutoConfiguration
    @ComponentScan(excludeFilters = {
    @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
    @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
    public @interface SpringBootApplication {
    
    /**
    * Exclude specific auto-configuration classes such that they will never be applied.
    * @return the classes to exclude
    */
    @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "exclude")
    Class<?>[] exclude() default {};
    
    /**
    * Exclude specific auto-configuration class names such that they will never be
    * applied.
    * @return the class names to exclude
    * @since 1.3.0
    */
    @AliasFor(annotation = EnableAutoConfiguration.class, attribute = "excludeName")
    String[] excludeName() default {};
    
    /**
    * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
    * for a type-safe alternative to String-based package names.
    * @return base packages to scan
    * @since 1.3.0
    */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};
    
    /**
    * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
    * scan for annotated components. The package of each class specified will be scanned.
    * <p>
    * Consider creating a special no-op marker class or interface in each package that
    * serves no purpose other than being referenced by this attribute.
    * @return base packages to scan
    * @since 1.3.0
    */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    Class<?>[] scanBasePackageClasses() default {};
    
    }

    关闭特定的自动注解

    @SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})

    定制Banner

    Banner指SpringBoot启动时候的默认图案

    我们在resources下新建一个
    banner.txt 文件
    打开网址 http://patorjk.com/software/taag
    输入我们需要的字符,将生成结果粘贴到 banner.txt 文件中即可

    关闭 Banner

    SpringApplication application = new SpringApplication(SpbootDemo01Application.class);
    application.setBannerMode(Banner.Mode.OFF);
    application.run(args);

    Spring Boot 配置文件

    Spring Boot
    使用一个全局的配置文件,放在 src/main/resources目录或类路径的config下
    名字叫做 application.properties或application.yml
    全局配置文件的作用是对一些默认配置进行修改

    基本的全局配置

    server.port=9090
    server.context-path=/helloworld

    如果使用的是yml,则可以

    server:
    port: 9090
    contextPath: /helloworld

    starter pom

    • 官方
    名称 描述
    spring-boot-starter 这是Spring Boot的核心启动器,包含了自动配置、日志和YAML
    spring-boot-starter-actuator 帮助监控和管理应用
    spring-boot-starter-amqp 通过spring-rabbit来支持AMQP协议(Advanced Message Queuing Protocol)
    spring-boot-starter-aop 支持面向方面的编程即AOP,包括spring-aop和AspectJ
    spring-boot-starter-artemis 通过Apache Artemis支持JMS的API(Java Message Service API)
    spring-boot-starter-batch 支持Spring Batch,包括HSQLDB数据库。
    spring-boot-starter-cache 支持Spring的Cache抽象。
    spring-boot-starter-cloud-connectors 支持Spring Cloud Connectors,简化了在像Cloud Foundry或Heroku这样的云平台上连接服务。
    spring-boot-starter-data-elasticsearch 支持ElasticSearch搜索和分析引擎,包括spring-data-elasticsearch。
    spring-boot-starter-data-gemfire 支持GemFire分布式数据存储,包括spring-data-gemfire。
    spring-boot-starter-data-jpa 支持JPA(Java Persistence API),包括spring-data-jpa、spring-orm、Hibernate。
    spring-boot-starter-data-mongodb 支持MongoDB数据,包括spring-data-mongodb。
    spring-boot-starter-data-rest 通过spring-data-rest-webmvc,支持通过REST暴露Spring Data数据仓库。
    spring-boot-starter-data-solr 支持Apache Solr搜索平台,包括spring-data-solr。
    spring-boot-starter-freemarker 支持FreeMarker模板引擎。
    spring-boot-starter-groovy-templates 支持Groovy模板引擎。
    spring-boot-starter-hateoas 通过spring-hateoas支持基于HATEOAS的RESTful Web服务。
    spring-boot-starter-hornetq 通过HornetQ支持JMS。
    spring-boot-starter-integration 支持通用的spring-integration模块。
    spring-boot-starter-jdbc 支持JDBC数据库。
    spring-boot-starter-jersey 支持Jersey RESTful Web服务框架。
    spring-boot-starter-jta-atomikos 通过Atomikos支持JTA分布式事务处理。
    spring-boot-starter-jta-bitronix 通过Bitronix支持JTA分布式事务处理。
    spring-boot-starter-mail 支持javax.mail模块。
    spring-boot-starter-mobile 支持spring-mobile。
    spring-boot-starter-mustache 支持Mustache模板引擎。
    spring-boot-starter-redis 支持Redis键值存储数据库,包括spring-redis。
    spring-boot-starter-security 支持spring-security。
    spring-boot-starter-social-facebook 支持spring-social-facebook
    spring-boot-starter-social-linkedin 支持pring-social-linkedin
    spring-boot-starter-social-twitter 支持pring-social-twitter
    spring-boot-starter-test 支持常规的测试依赖,包括JUnit、Hamcrest、Mockito以及spring-test模块。
    spring-boot-starter-thymeleaf 支持Thymeleaf模板引擎,包括与Spring的集成。
    spring-boot-starter-velocity 支持Velocity模板引擎。
    spring-boot-starter-web 支持全栈式Web开发,包括Tomcat和spring-webmvc。
    spring-boot-starter-websocket 支持WebSocket开发。
    spring-boot-starter-ws 支持Spring Web Services。
    spring-boot-starter-actuator 增加了面向产品上线相关的功能,比如测量和监控。
    spring-boot-starter-remote-shell 增加了远程ssh shell的支持。
    spring-boot-starter-jetty 引入了Jetty HTTP引擎(用于替换Tomcat)。
    spring-boot-starter-log4j 支持Log4J日志框架。
    spring-boot-starter-logging 引入了Spring Boot默认的日志框架Logback。
    spring-boot-starter-tomcat 引入了Spring Boot默认的HTTP引擎Tomcat。
    spring-boot-starter-undertow 引入了Undertow HTTP引擎(用于替换Tomcat)。
    • 第三方starter pom

    当我们需要某方面的技术的时候,先查查有没有对应的starter,如:MyBatis

    <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.3.0</version>
    </dependency>

    Spring Boot
    提倡无xml配置,但有时候必须用到xml配置,

    使用

    @ImportResource({"classpath:a.xml","classpath:b.xml"})
    导入即可

    外部文件配置

    SpringBoot允许使用

    properties
    yaml
    文件或者命令行参数作为外部配置

    命令行参数

    #!/bin/sh
    nohup java -Xms128m -Xmx256m -jar train-basic-0.0.1-SNAPSHOT.jar --spring.profiles.active=A-prod >/dev/null 2>&1 &

    --spring.profiles.active=A-prod
    就是指定了一个外部参数

    application.yml中的配置

    对于配置在

    application.yml
    主配置文件中的参数,可以直接使用
    @Value()
    注解进行获取

    当然,使用

    application.properties
    也是一样的

    package org.zln.spb.demo01.web;
    
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RestController;
    
    /**
    * @Author 张柳宁
    * @Description
    * @Date Create in 2018/1/31
    * @Modified By:
    */
    @RestController
    @Slf4j
    public class HelloController {
    
    @Value("${user.k1}")
    private String userK1;
    
    @RequestMapping("/hello")
    public String hello(){
    log.info(userK1);
    return "Hello ,世界";
    }
    
    }

    application.yml内容为

    user:
    k1: 张柳宁

    类型安全的配置

    如果不是

    application
    配置文件,而是其他配置文件,那么就需要先指定
    properties
    文件的位置

    package com.tdk.train.config;
    
    import lombok.Data;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    import org.springframework.context.annotation.PropertySource;
    import org.springframework.stereotype.Component;
    
    /**
    * Created by nbcoolkid on 2017-11-05.
    */
    @Component
    @PropertySource(value = "classpath:db.properties",encoding = "utf-8")
    @ConfigurationProperties(prefix = "mysql")
    @Data
    public class DbConfBean {
    private String url;
    private String url2;
    private String username;
    private String username2;
    private String password;
    private String password2;
    }

    将一个

    properties
    配置文件与
    JavaBean
    关联起来

    日志配置

    Spring Boot 支持Java UtilLogging、Log4J、Log4J2和LogBack作为日志框架

    默认使用LogBack作为日志框架

    # 配置日志文件路径
    logging.file=logs/spboot-demo01.log
    #配置日志级别,格式:logging.level.包名=级别
    logging.level.org.springframework.web=DEBUG

    如果需要对日志进行详细的配置,则

    logging:
    level: info
    config: classpath:logback.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration debug="false" scan="true" scanPeriod="1 seconds">
    
    <contextName>logback</contextName>
    <property name="log.path" value="./logs/train-basic.log"/>
    
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
    <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
    </appender>
    
    <appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${log.path}</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
    <fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zip</fileNamePattern>
    </rollingPolicy>
    <encoder>
    <pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
    </pattern>
    </encoder>
    </appender>
    
    <root level="info">
    <appender-ref ref="console"/>
    <appender-ref ref="file"/>
    </root>
    
    </configuration>

    Profile配置

    Profile是Spring用来针对不同的环境提供平不同的配置支持的
    全局Profile配置使用 application-{profile}.properties

    通过在application.properties中设置spring.profiles.active=dev 来设置活动的Profile

    SpringBoot打包出一个可执行jar

    <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
    <mainClass>org.zln.ehcache.Main</mainClass>
    </configuration>
    <executions>
    <execution>
    <goals>
    <goal>repackage</goal>
    </goals>
    </execution>
    </executions>
    </plugin>
    </plugins>
    </build>

    即是没有这段,默认打出来的jar也是可执行的

    Spring Boot运行原理

    Spring Boot的自动配置,其原理是Spring 4出现的条件化Bean

    三种方式查看当前项目已启用和未启用的自动配置

    • java -jar xx.jar --debug
    • 全局配置文件:debug=true
    • 运行的时候通过IDE为VM添加参数:-Ddebug

    SpringBootApplication–>EnableAutoConfiguration
    EnableAutoConfiguration–>Import
    Import–>EnableAutoConfigurationImportSelector
    EnableAutoConfigurationImportSelector–>AutoConfigurationImportSelector

    扫描 META-INF/spring.factories 文件

    spring-boot-autoconfigure-1.5.3.RELEASE.jar中就有

    其中配置的任何一个自动注解配置类,都有条件注解

    条件注解 说明
    @ConditionalOnBean 当容器中存在指定Bean的条件下
    @ConditionalOnClass 当类路径下有指定类的情况下
    @ConditionalOnExpression 基于SpEL表达式作为判断条件
    @ConditionalOnJava 基于JVM版本作为判断条件
    @ConditionalOnJndi 在JNDI存在的条件下查找指定位置
    @ConditionalOnMissingBean 当容器中不存在指定Bean的条件下
    @ConditionalOnMissingClass 当类路径没有指定类的条件下
    @ConditionalOnNotWebApplication 当前项目不是Web项目的条件下
    @ConditionalOnProperty 指定属性是否有指定的值
    @ConditionalOnResource 类路径是否有指定的值
    @ConditionalOnSingleCandidate 当指定Bean在容器中只有一个, 或者虽然有多个但是指定首选的Bean
    @ConditionalOnWebApplication 当前项目是Web项目的条件下

    自定义 starter pom

    当类存在的时候,自动配置这个Bean,并可将Bean的属性在application.properties文件中进行配置

    • pom
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.pzr</groupId>
    <artifactId>spring-boot-starter-pzrhello</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <!-- 引用依赖的父包 -->
    <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.1.RELEASE</version>
    </parent>
    <!-- 依赖包 -->
    <dependencies>
    <!-- spring boot 自动配置需要的包 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-autoconfigure</artifactId>
    </dependency>
    <!-- spring boot需要的包 -->
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    </dependencies>
    </project>
    • 添加属性配置类
    package com.pzr.spring_boot_stater_pzrhello;
    import org.springframework.boot.context.properties.ConfigurationProperties;
    /**
    * 属性配置类
    * @author pzr
    *
    */
    @ConfigurationProperties(prefix="hello")
    public class HelloServiceProperties {
    private static final String MSG = "world";
    private String msg = MSG;
    public String getMsg() {
    return msg;
    }
    public void setMsg(String msg) {
    this.msg = msg;
    }
    }

    代码说明:

    使用@ConfigurationProperties注解来设置前缀,

    在application.properties中通过hello.msg=来设置,若不设置,默认为hello.msg=world。

    • 添加判断依据类
    package com.pzr.spring_boot_stater_pzrhello;
    /**
    * 判断依据类
    * @author pzr
    *
    */
    public class HelloService {
    private String msg;
    public String sayHello(){
    return "Hello "+msg;
    }
    public String getMsg() {
    return msg;
    }
    public void setMsg(String msg) {
    this.msg = msg;
    };
    }
    • 添加自动配置类
    package com.pzr.spring_boot_stater_pzrhello;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
    import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
    import org.springframework.boot.context.properties.EnableConfigurationProperties;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    /**
    * 自动配置类
    * @author pzr
    *
    */
    @Configuration
    @EnableConfigurationProperties(HelloServiceProperties.class)
    @ConditionalOnClass(HelloService.class)
    @ConditionalOnProperty(prefix="hello",value="enabled",matchIfMissing=true)
    public class HelloServiceAutoConfiguration {
    @Autowired
    private HelloServiceProperties helloServiceProperties;
    @Bean
    public HelloService helloService(){
    HelloService helloService = new HelloService();
    helloService.setMsg(helloServiceProperties.getMsg());
    return helloService;
    }
    }

    将HelloServiceAutoConfiguration配置到 src/main/resources/META-INF/spring.properties

    org.springframework.boot.autoconfigure.EnableAutoConfiguration=
    com.pzr.spring_boot_stater_pzrhello.HelloServiceAutoConfiguration

    1. @Configuration:使用该注解来说明该类是配置类,等价于xml中的beans
    2. @EnableConfigurationProperties(HelloServiceProperties.class):开启属性注入,对注解配置Bean的支持
    3. @ConditionalOnClass(HelloService.class):条件注解,当类路径下有指定的类的条件下。
    4. @ConditionalOnProperty(prefix=”hello”,value=”enabled”,matchIfMissing=true):条件注解,指定的属性是否有指定的值。当设置hello=enabled,如果没有设置则默认为true,即为条件符合。假如我们将matchIfMissing设置为false,则当设置hello=enabled时,条件为false,则不会将该Bean加载进容器类,当使用@Autowired注入HelloService时会报错。
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: