Spring Boot (a): Threshold

First, what is Spring Boot

Spring Boot is a new framework provided by Pivotal team, which is designed to simplify the development process as well as the initial build new Spring applications. The framework uses a particular manner be configured so that the developer is no longer necessary to define the configuration of the template. I will say to understand, is the Spring Boot fact, what the new framework is not, it is the default configuration use a lot of framework, like Maven incorporates all the Jar package, Spring Boot incorporates all of the framework.

1, a simplified spring application development framework;

2, spring a large integrated technology stack;

3, J2EE developers a one-stop solution;

Second, what are the benefits using Spring Boot

In fact, that is simple, fast and easy!

Usually if we need to build a Spring Web project when you need how to do it?

  • Configuring web.xml, spring loaded and springMVC
  • Configure a database connection configuration spring Affairs
  • Configuration read load profiles, open notes
  • Configuring Log Files
  • ...
  • After configuring Tomcat deployment debugging
  • ...

Now very popular micro-services, this project if I just need to send a message, if only my project is to produce an integrator; I need to toss it again!

But if you use Spring Boot it?
Very simple, I only need a very small number of configuration can be quickly and easily build up a Web project or build a micro-service!

Use Spring Boot how cool in the end, is expressed by the following piece of FIG.

Third, a simple example

1, IDEA building project

(1) Select File -> New -> Project ... New Project pop-up box

(2) Select Spring Initializr, Next will appear similar to the above configuration interface, Idea help us to do the integration

(3) Fill in the relevant content, click Next and then select the package and click Next depend, to finalize the information is correct click Finish.

2, project structure Introduction

As shown above, the Spring Boot infrastructure total of three documents:

  • src/main/java Program development and main entrance
  • src/main/resources Profiles
  • src/test/java test program

3, to achieve Spring Boot HelloWorld

(1) maven configuration

To the profiles of the label maven settings.xml configuration file to add

<profile>
  <id>jdk-1.8</id>
  <activation>
    <activeByDefault>true</activeByDefault>
    <jdk>1.8</jdk>
  </activation>
  <properties>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
    <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
  </properties>
</profile>

(2) introducing dependencies associated spring boot

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.9.RELEASE</version>
    </parent>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

(3) write a main program; launch applications Spring Boot

/**
 *  @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
 */
@SpringBootApplication
public class HelloWorldMainApplication {

    public static void main(String[] args) {

        // Spring应用启动起来
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}

(4) related to the preparation Controller, Service

@Controller
public class HelloController {

    @ResponseBody
    @RequestMapping("/hello")
    public String hello(){
        return "Hello World!";
    }
}

@RestController means that the inside of the Controller methods to json format output, do not write what jackjson the configuration.

(5) main test run

(6) How do unit testing

Test inlet opening src / test / under, http request to write simple test; mockmvc for use by MockMvcResultHandlers.print () to print out the result.

@RunWith(SpringRunner.class)
@SpringBootTest
public class HelloTests {
    private MockMvc mvc;

    @Before
    public void setUp() throws Exception {
        mvc = MockMvcBuilders.standaloneSetup(new HelloWorldController()).build();
    }

    @Test
    public void getHello() throws Exception {
        mvc.perform(MockMvcRequestBuilders.get("/hello").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk())
                .andExpect(content().string(equalTo("Hello World")));
    }
}

(7) to simplify deployment

·   <!-- 这个插件,可以将应用打包成一个可执行的jar包;-->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

This application will be labeled jar package, the direct use of java -jar command execution

4, Hello World exploration

(1) POM file

pom.xml file by default has two modules:

spring-boot-starter core module, including automatic configuration support, logging and YAML, if introduced into the spring-boot-starter-web web module may cancel the configuration, since the spring-boot-starter-web automatically dependent on the spring-boot-starter .

spring-boot-starter-test test modules, including JUnit, Hamcrest, Mockito.

Parent Project

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.9.RELEASE</version>
</parent>

他的父项目是
<parent>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-dependencies</artifactId>
  <version>1.5.9.RELEASE</version>
  <relativePath>../../spring-boot-dependencies</relativePath>
</parent>
他来真正管理Spring Boot应用里面的所有依赖版本;

Launcher

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

spring-boot-starter: spring-boot scene initiator; help us introducing the assembly modules running web depends;

Spring Boot all the scenes are extracted features, one made of Starters (initiator), are dependent only need to introduce all of these scenarios associated starter introduced in coming projects inside. What is the function to use it to import the starter what scene.

(2) of the main program, the main entrance class

/**
 *  @SpringBootApplication 来标注一个主程序类,说明这是一个Spring Boot应用
 */
@SpringBootApplication
public class HelloWorldMainApplication {

    public static void main(String[] args) {

        // Spring应用启动起来
        SpringApplication.run(HelloWorldMainApplication.class,args);
    }
}

@ ** SpringBootApplication **: Spring Boot label instructions on the application of this class is a class SpringBoot the main configuration, SpringBoot should run the main method of this class to start SpringBoot application;

@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 {
}

@ ** SpringBootConfiguration **: Spring Boot configuration class;

Marked on a class, he said it was a Spring Boot configuration class;

@ ** Configuration **: configuration class marked up this comment;

----- profile configuration class; configuration class is a container assembly; @Component

@ ** EnableAutoConfiguration **: turn on auto-configuration feature;

Things before we need to configure, Spring Boot to help us to automatically configure; @ ** EnableAutoConfiguration ** tell SpringBoot turn on auto-configuration; the automatic configuration to take effect;

@AutoConfigurationPackage
@Import(EnableAutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
}

@ ** AutoConfigurationPackage **: Automatic configuration package

​        @**Import**(AutoConfigurationPackages.Registrar.class):

Spring bottom notes @Import, the vessel is introduced into a component; component introduced by AutoConfigurationPackages.Registrar.class;

== Configuration The main classes (@SpringBootApplication labeled class) packets and where all of the following sub-packets to scan all the components inside the container Spring; ==

​    @**Import**(EnableAutoConfigurationImportSelector.class);

Import component to the container?

** EnableAutoConfigurationImportSelector **: the selector assembly which is introduced;

All of the components needed to return the introduced full class name manner; these components will be added to the container;

Importing a container will automatically configure a lot of class (xxxAutoConfiguration); this scenario is to import all the components required for container and configure these components;! [Automatic configuration class] (images / screenshots Sogou 20180129224104.png)

With automatic configuration class, eliminating the need to manually write the configuration we inject functional components such work;

​        SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class,classLoader);

== Spring Boot acquired at startup from the META-INF class path / spring.factories EnableAutoConfiguration specified value, these values ​​will be introduced into the container as an automatic configuration classes, class automatic configuration will take effect, help us automatically configured work; what we need before == own configuration, automatic configuration class to help us;

J2EE overall integration solutions and automatic configuration are spring-boot-autoconfigure-1.5.9.RELEASE.jar in;

Fourth, the configuration file

1, the configuration file Introduction

SpringBoot use a global configuration file, the configuration file name is fixed;

  • application.properties
  • application.yml

Profile role: Modify the default value SpringBoot auto-configuration; SpringBoot on the ground floor gave us automatically configured;

Yamla (Yamla Is not Markup Language)

YAML A Markup Language: is a markup language

YAML is not Markup Language: is not a markup language;

Markup Language:

Previous profile; most of them are using ** xxxx.xml ** file;

YAML: ** ** data-centric than JSON, XML and other more suitable profile;

YAML: Configuration example

server:
  port: 8081

2, YAML syntax:

(1) The basic syntax

k :( space) v: designates a pair of key-value pairs (there must be a space);

** ** indentation with spaces to control the hierarchy; as long as one is left-aligned data, are the same level

server:
    port: 8081
    path: /hello

And attribute values ​​are case sensitive;

(2) the value written

  • Literal: Common values ​​(numbers, strings, Boolean)

k: v: literally write directly;

No default string in single or double quotes;

"": Double quotes; there will not escape the string of special characters; special characters as themselves wish of intention

name: "zhangsan \ n lisi": Output; zhangsan wrap lisi

'': Single quote; will escape special characters, special characters finally just an ordinary string data

name: 'zhangsan \ n lisi': output; zhangsan \ n lisi

  • Object, Map (attributes and values) (key-value pairs):

k: v: the relationship between attributes and values ​​of an object to write the next line; note indentation

Object or k: v way

friends:
		lastName: zhangsan
		age: 20

 

  •  Array (List, Set):

Represents an element in the array values ​​- with

pets:
 - cat
 - dog
 - pig

3, the injection profile values

(1) yml profile

person:
    lastName: hello
    age: 18
    boss: false
    birth: 2017/12/12
    maps: {k1: v1,k2: 12}
    lists:
      - lisi
      - zhaoliu
    dog:
      name: 小狗
      age: 12

(2)javaBean:

/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中哪个下面的所有属性进行一一映射
 *
 * 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;
 *
 */
@Component
@ConfigurationProperties(prefix = "person")
public class Person {

    private String lastName;
    private Integer age;
    private Boolean boss;
    private Date birth;

    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;

We can import the configuration file processor, after writing configuration have prompted the

<!--导入配置文件处理器,配置文件进行绑定就会有提示-->
<dependency>
	groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-configuration-processor</artifactId>
	<optional>true</optional>
</dependency>

(3) @Value acquisition value and the comparison value acquired @ConfigurationProperties

Profile yml or properties they can get to value;

If you say that we just need to get some business logic at a particular value in the configuration file, use @Value;

If we say that we wrote a javaBean dedicated to mapping and configuration files, we just use @ConfigurationProperties;

(4) injection profile data check values

@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {

    /**
     * <bean class="Person">
     *      <property name="lastName" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}"></property>
     * <bean/>
     */

   //lastName必须是邮箱格式
    @Email
    //@Value("${person.last-name}")
    private String lastName;
    //@Value("#{11*2}")
    private Integer age;
    //@Value("true")
    private Boolean boss;

    private Date birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog;

(5)@PropertySource&@ImportResource&@Bean

@ ** PropertySource **: Loads the specified configuration file;

/**
 * 将配置文件中配置的每一个属性的值,映射到这个组件中
 * @ConfigurationProperties:告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定;
 *      prefix = "person":配置文件中哪个下面的所有属性进行一一映射
 *
 * 只有这个组件是容器中的组件,才能容器提供的@ConfigurationProperties功能;
 *  @ConfigurationProperties(prefix = "person")默认从全局配置文件中获取值;
 *
 */
@PropertySource(value = {"classpath:person.properties"})
@Component
@ConfigurationProperties(prefix = "person")
//@Validated
public class Person {

    /**
     * <bean class="Person">
     *      <property name="lastName" value="字面量/${key}从环境变量、配置文件中获取值/#{SpEL}"></property>
     * <bean/>
     */

   //lastName必须是邮箱格式
   // @Email
    //@Value("${person.last-name}")
    private String lastName;
    //@Value("#{11*2}")
    private Integer age;
    //@Value("true")
    private Boolean boss;

@ ** ImportResource **: Importing Spring configuration file, so that the contents of the configuration file which is to take effect;

Spring Boot there is no Spring configuration file, write our own configuration files, it can not automatically identify;

Would like Spring configuration file to take effect, came loaded; @ ** ImportResource ** marked on a configuration class

@ImportResource(locations = {"classpath:beans.xml"})
导入Spring的配置文件让其生效

Not to write the Spring configuration file

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <bean id="helloService" class="com.atguigu.springboot.service.HelloService"></bean>
</beans>

SpringBoot recommended way to add components to a container; recommended way to use the full annotated

  • Configuration class ** @ Configuration ** ------> Spring configuration file
  • Use ** @ Bean ** add components to the container
/**
 * @Configuration:指明当前类是一个配置类;就是来替代之前的Spring配置文件
 *
 * 在配置文件中用<bean><bean/>标签添加组件
 *
 */
@Configuration
public class MyAppConfig {

    //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
    @Bean
    public HelloService helloService02(){
        System.out.println("配置类@Bean给容器中添加组件了...");
        return new HelloService();
    }
}

4, the configuration file placeholder

(1) Random Number

${random.value}、${random.int}、${random.long}
${random.int(10)}、${random.int[1024,65536]}

(2) obtaining a placeholder value previously configured, may be used if no: to specify default values

person.last-name=张三${random.uuid}
person.age=${random.int}
person.birth=2017/12/15
person.boss=false
person.maps.k1=v1
person.maps.k2=14
person.lists=a,b,c
person.dog.name=${person.hello:hello}_dog
person.dog.age=15

5、Profile

(1) Multi-Profile file

We in the preparation of the master configuration file, the file name can be application- {profile} .properties / yml

Application.properties use the default configuration;

(2) yml support multiple block the way

server:
  port: 8081
spring:
  profiles:
    active: prod

---
server:
  port: 8083
spring:
  profiles: dev


---

server:
  port: 8084
spring:
  profiles: prod  #指定属于哪个环境

(3) activation profile is specified,

  • Spring.profiles.active = dev specified in the configuration file
  • Command line:

​        java -jar spring-boot-02-config-0.0.1-SNAPSHOT.jar --spring.profiles.active=dev;

Directly in the test, configure incoming command line parameters

  • Virtual machine parameters;

​        -Dspring.profiles.active=dev

6, the configuration file is loaded position

springboot started, it scans the following locations application.properties or application.yml Spring boot file as the default profile

–file:./config/

–file:./

–classpath:/config/

–classpath:/

In the end of a high priority, a high priority configuration overwrites the low priority configuration;

SpringBoot will be loaded from the four positions of all main configuration file; ** ** complementary configuration;

== We can also change the default configuration file location by spring.config.location ==

** items packed in the future, we can use the command-line parameters in the form of, when the project started to specify the new location of the configuration file; specified configuration file and the default load of these configuration files work together to form a complementary configuration; **

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --spring.config.location=G:/application.properties

7, arranged outside the loading sequence

** == SpringBoot may also be loaded from the arranged position; low priority level; high priority is configured to cover a low priority configuration, and any configuration may complement the configuration == **

** 1, the command line parameters **

All configurations can be specified on the command line

java -jar spring-boot-02-config-02-0.0.1-SNAPSHOT.jar --server.port=8087  --server.context-path=/abc

A plurality of configuration separated by spaces; - = CI value

2, from the java: JNDI properties comp / env of

3, Java system properties (System.getProperties ())

4, the operating system environment variables

5, RandomValuePropertySource configuration random. * Property Value

** == Looking for outgoing packets within a jar jar package; ** ==

== ** priority loaded with profile ** ==

** 6, jar external package or application- {profile} .properties application.yml (with spring.profile) Profile **

** 7, inside a jar or application- {profile} .properties application.yml (with spring.profile) Profile **

== ** come loaded with no profile ** ==

** 8, jar or outer package application.properties application.yml (without spring.profile) Profile **

** 9, inside a jar or application.properties application.yml (without spring.profile) Profile **

10, @PropertySource on the @ Configuration annotation class

 11, by default properties specified SpringApplication.setDefaultProperties

All supported configurations load source;

[Refer to the official documentation]

8, automatic configuration principle

Profiles in the end what to write? how to write? Automatic configuration principle;

[Profile attributes can be configured to reference]

(1) When SpringBoot initiated load master class configuration, turn on the auto-configuration feature == @ EnableAutoConfiguration ==

(2)@EnableAutoConfiguration 作用:

  • Use EnableAutoConfigurationImportSelector import some components to the container?
  • You can view selectImports (content method);
  • List <String> configurations = getCandidateConfigurations (annotationMetadata, attributes); obtaining candidates configuration
SpringFactoriesLoader.loadFactoryNames()
扫描所有jar包类路径下  META-INF/spring.factories
把扫描到的这些文件的内容包装成properties对象
从properties中获取到EnableAutoConfiguration.class类(类名)对应的值,然后把他们添加在容器中

The values ​​of all EnableAutoConfiguration the META-INF / spring.factories classpath arranged inside added to the vessel;

Each of these classes are xxxAutoConfiguration a container assembly, are added to the vessel; to do with their auto-configuration;

(3) Each class is automatically configure auto-configuration;

(4) ** HttpEncodingAutoConfiguration (Http coding autoconfiguration) ** Example explain the principle of auto-configuration:

@Configuration //表示这是一个配置类,以前编写的配置文件一样,也可以给容器中添加组件
@EnableConfigurationProperties(HttpEncodingProperties.class)//启动指定类的ConfigurationProperties功能;将配置文件中对应的值和HttpEncodingProperties绑定起来;并把HttpEncodingProperties加入到IOC容器中
@ConditionalOnWebApplication //spring底层@Conditional注解,根据不同的条件,如果满足指定的条件,整个配置类里面的配置就会失效;判断当前应用是否是web类,如果是,当前配置类生效
@ConditionalOnClass(CharacterEncodingFilter.class) //判断当前项目有没有这个类CharacterEncodingFilter;
SpringMVC中进行乱码解决的过滤器;
@ConditionalOnProperty(prefix = "spring.http.encoding", value = "enabled", matchIfMissing = true)  //判断配置文件中是否存在某个配置spring.http.encoding.enabled;如果不存在,判断也是成立的 
//即使我们配置文件中不配置pring.http.encoding.enabled=true,也是默认生效的;
public class HttpEncodingAutoConfiguration {
    //已经和springboot配置文件映射了
    private final HttpEncodingProperties properties;
    //只有一个有参构造器的情况下,参数的值就会从容器中拿
    public HttpEncodingAutoConfiguration(HttpEncodingProperties properties) {
		this.properties = properties;
	}
    @Bean //给容器中添加一个组件,这个组件的某些值需要从properties中回去
    @ConditionalOnEncodingFilter(CharacterEncodingFilter.class)//判断容器没有这个组件?
    public CharacterEncodingFilter characterEncodingFilter(){
        CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.properties.getCharset().name());
		filter.setForceRequestEncoding(this.properties.shouldForce(Type.REQUEST));
		filter.setForceResponseEncoding(this.properties.shouldForce(Type.RESPONSE));
		return filter;
    }
}

Depending on the conditions of the current judgment, decide whether the class configuration take effect?

Once this configuration classes take effect; this configuration class will be added to the various components of the container; the properties of these components are obtained from the corresponding properties of the class, each of these classes which is a property of binding and profile;

(5) all the attributes in the configuration file that can be configured are encapsulated in the class xxxxProperties; what configuration file can be configured to reference a function corresponding to the attribute class

@ConfigurationProperties(prefix = "spring.http.encoding")  //从配置文件中获取指定的值和bean的属性进行绑定
public class HttpEncodingProperties {

   public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");

** ** essence

  • springboot will start automatically configured to load a lot of class
  • We need to look at our functions there springboot default automatic configuration class written;
  • Let's look at this in the end configuration automatically configures the class which components (as long as we have to use component, we do not need to come equipped)
  • A container class is automatically configured when the added components, will automatically obtain certain properties from the properties of class, we can specify the values ​​of these attributes in the configuration file;

xxxxAutoConfigurartion: automatic configuration class;

Adding components to the container

xxxxProperties: encapsulation configuration file related attributes;

9, details

@Conditional derivative (@Conditional action version annotation Spring native) comment

Role: @Conditional must be specified condition is met only add components to the container, the configuration of all the contents inside to take effect;

@Conditional extended comment   Role (determining whether the current satisfies the specified conditions)  
@ConditionalOnJava java version of the system to meet the requirements
@ConditionalOnBean       Bean specify the presence of the container; 
@ConditionalOnMissingBean      Bean container specified does not exist; 
@ConditionalOnExpression   SpEL meet the specified expression    
@ConditionalOnClass  System has specified class              
@ConditionalOnMissingClass The system does not specify the class
@ConditionalOnSingleCandidate Only one container specified Bean, or this is the preferred Bean Bean
@ConditionalOnProperty     Whether the specified attribute value specified system
@ConditionalOnResource     The existence of the specified resource file in the classpath
@ConditionalOnWebApplication The current environment is the web   
@ConditionalOnNotWebApplication 当前不是web环境
@ConditionalOnJndi JNDI存在指定项

自动配置类必须在一定的条件下才能生效;

**我们可以通过启用  debug=true属性;来让控制台打印自动配置报告==**,这样我们就可以很方便的知道哪些自动配置类生效;

=========================
AUTO-CONFIGURATION REPORT
=========================


Positive matches:(自动配置类启用的)
-----------------

   DispatcherServletAutoConfiguration matched:
      - @ConditionalOnClass found required class 'org.springframework.web.servlet.DispatcherServlet'; @ConditionalOnMissingClass did not find unwanted class (OnClassCondition)
      - @ConditionalOnWebApplication (required) found StandardServletEnvironment (OnWebApplicationCondition)
        
    
Negative matches:(没有启动,没有匹配成功的自动配置类)
-----------------

   ActiveMQAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'javax.jms.ConnectionFactory', 'org.apache.activemq.ActiveMQConnectionFactory' (OnClassCondition)

   AopAutoConfiguration:
      Did not match:
         - @ConditionalOnClass did not find required classes 'org.aspectj.lang.annotation.Aspect', '三、快速入门

五、日志

1、SpringBoot选用 SLF4j和logback

以后开发的时候,日志记录方法的调用,不应该来直接调用日志的实现类,而是调用日志抽象层里面的方法;

给系统里面导入slf4j的jar和  logback的实现jar。

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class HelloWorld {
  public static void main(String[] args) {
    Logger logger = LoggerFactory.getLogger(HelloWorld.class);
    logger.info("Hello World");
  }
}

2、遗留问题

a(slf4j+logback): Spring(commons-logging)、Hibernate(jboss-logging)、MyBatis、xxxx

统一日志记录,即使是别的框架和我一起统一使用slf4j进行输出?

如何让系统中所有的日志都统一到slf4j?

(1)将系统中其它日志框架先排除出去

(2)用中间包来替换原有的日志框架

(3)导入slf4j其它的实现

3、SpringBoot日志关系

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter</artifactId>
</dependency>

SpringBoot使用它来做日志功能;

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-logging</artifactId>
</dependency>

4、底层依赖关系

(1)Spring Boot底层也是使用slf4j+logback的方式进行日志记录

(2)Spring Boot也把其他的日志都替换成了slf4j;

(3)中间替换包?

@SuppressWarnings("rawtypes")
public abstract class LogFactory {

    static String UNSUPPORTED_OPERATION_IN_JCL_OVER_SLF4J = "http://www.slf4j.org/codes.html#unsupported_operation_in_jcl_over_slf4j";

    static LogFactory logFactory = new SLF4JLogFactory();

(4)如果我们要引入其他框架?一定要把这个框架的默认日志依赖移除掉?

Spring框架用的commons-logging:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-core</artifactId>
	<exclusions>
		<exclusion>
			<groupId>commons-logging</groupId>
			<artifactId>commons-logging</artifactId>
		</exclusion>
	</exclusions>
</dependency>

**==SpringBoot能自动适配所有的日志,而且底层使用slf4j+logback的方式记录日志,引入其他框架的时候,只需要把这个框架依赖的日志框架排除掉即可;**

5、日志使用

(1)默认配置

Spring Boot默认帮我们配置好了日志

//记录器
Logger logger = LoggerFactory.getLogger(getClass());
@Test
public void contextLoads() {
	//System.out.println();
	//日志的级别;
	//由低到高   trace<debug<info<warn<error
	//可以调整输出的日志级别;日志就只会在这个级别以以后的高级别生效
	logger.trace("这是trace日志...");
	logger.debug("这是debug日志...");
	//SpringBoot默认给我们使用的是info级别的,没有指定级别的就用SpringBoot默认规定的级别;root级别
	logger.info("这是info日志...");
	logger.warn("这是warn日志...");
	logger.error("这是error日志...")
}
logging.level.com.atguigu=trace


#logging.path=
# 不指定路径在当前项目下生成springboot.log日志
# 可以指定完整的路径;
#logging.file=G:/springboot.log

# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹;使用 spring.log 作为默认文件
logging.path=/spring/log

# 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy-MM-dd} [%thread] %-5level %logger{50} - %msg%n
# 指定文件中日志输出的格式
logging.pattern.file=%d{yyyy-MM-dd} === [%thread] === %-5level === %logger{50} ==== %msg%n

 (2)指定配置

给类路径下放上每个日志框架自己的配置文件即可;SpringBoot就不使用他默认配置的了。

logback.xml:直接就被日志框架识别了;

logback-spring.xml:日志框架就不直接加载日志的配置项,由SpringBoot解析日志配置,可以使用SpringBoot的高级Profile功能;

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
  	可以指定某段配置只在某个环境下生效
</springProfile>
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
    <!--
        日志输出格式:
			%d表示日期时间,
			%thread表示线程名,
			%-5level:级别从左显示5个字符宽度
			%logger{50} 表示logger名字最长50个字符,否则按照句点分割。 
			%msg:日志消息,
			%n是换行符
        -->
    <layout class="ch.qos.logback.classic.PatternLayout">
        <springProfile name="dev">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ----> [%thread] ---> %-5level %logger{50} - %msg%n</pattern>
        </springProfile>
        <springProfile name="!dev">
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} ==== [%thread] ==== %-5level %logger{50} - %msg%n</pattern>
        </springProfile>
    </layout>
</appender>

如果使用logback.xml作为日志配置文件,还要使用profile功能,会有以下错误:

no applicable action for [springProfile]

6、切换日志框架

可以按照slf4j的日志适配图,进行相关的切换;

slf4j+log4j的方式:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
  <exclusions>
    <exclusion>
      <artifactId>logback-classic</artifactId>
      <groupId>ch.qos.logback</groupId>
    </exclusion>
    <exclusion>
      <artifactId>log4j-over-slf4j</artifactId>
      <groupId>org.slf4j</groupId>
    </exclusion>
  </exclusions>
</dependency>

<dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-log4j12</artifactId>
</dependency>

切换为log4j2:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
         <exclusion>
             <artifactId>spring-boot-starter-logging</artifactId>
             <groupId>org.springframework.boot</groupId>
         </exclusion>
    </exclusions>
</dependency>

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>

六、总结

使用 Spring Boot 可以非常方便、快速搭建项目,使我们不用关心框架之间的兼容性,适用版本等各种问题,我们想使用任何东西,仅仅添加一个配置就可以,所以使用 Spring Boot 非常适合构建微服务。

发布了110 篇原创文章 · 获赞 8 · 访问量 6921

Guess you like

Origin blog.csdn.net/guorui_java/article/details/104152433