原文:Mkyong
Spring Boot——Jetty 作为嵌入式服务器
默认情况下,Spring Boot 使用 Tomcat 作为默认的嵌入式服务器,要将其更改为 Jetty,只需排除 Tomcat 并包含 Jetty,如下所示:
1.弹簧靴起动器网
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
2.百里香叶
pom.xml
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
</dependency>
查看依赖关系
$ mvn dependency:tree
[INFO] org.springframework.boot:spring-boot-web-thymeleaf:jar:1.0
[INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:1.4.2.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:1.4.2.RELEASE:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:1.4.2.RELEASE:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.1.7:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.1.7:compile
[INFO] | | | +- org.slf4j:jcl-over-slf4j:jar:1.7.21:compile
[INFO] | | | +- org.slf4j:jul-to-slf4j:jar:1.7.21:compile
[INFO] | | | \- org.slf4j:log4j-over-slf4j:jar:1.7.21:compile
[INFO] | | +- org.springframework:spring-core:jar:4.3.4.RELEASE:compile
[INFO] | | \- org.yaml:snakeyaml:jar:1.17:runtime
[INFO] | +- org.springframework.boot:spring-boot-starter-web:jar:1.4.2.RELEASE:compile
[INFO] | | +- org.hibernate:hibernate-validator:jar:5.2.4.Final:compile
[INFO] | | | +- javax.validation:validation-api:jar:1.1.0.Final:compile
[INFO] | | | +- org.jboss.logging:jboss-logging:jar:3.3.0.Final:compile
[INFO] | | | \- com.fasterxml:classmate:jar:1.3.3:compile
[INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.8.4:compile
[INFO] | | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.8.4:compile
[INFO] | | | \- com.fasterxml.jackson.core:jackson-core:jar:2.8.4:compile
[INFO] | | +- org.springframework:spring-web:jar:4.3.4.RELEASE:compile
[INFO] | | | +- org.springframework:spring-aop:jar:4.3.4.RELEASE:compile
[INFO] | | | \- org.springframework:spring-beans:jar:4.3.4.RELEASE:compile
[INFO] | | \- org.springframework:spring-webmvc:jar:4.3.4.RELEASE:compile
[INFO] | | \- org.springframework:spring-expression:jar:4.3.4.RELEASE:compile
[INFO] | +- org.thymeleaf:thymeleaf-spring4:jar:2.1.5.RELEASE:compile
[INFO] | | +- org.thymeleaf:thymeleaf:jar:2.1.5.RELEASE:compile
[INFO] | | | +- ognl:ognl:jar:3.0.8:compile
[INFO] | | | +- org.javassist:javassist:jar:3.20.0-GA:compile
[INFO] | | | \- org.unbescape:unbescape:jar:1.1.0.RELEASE:compile
[INFO] | | \- org.slf4j:slf4j-api:jar:1.7.21:compile
[INFO] | \- nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect:jar:1.4.0:compile
[INFO] | \- org.codehaus.groovy:groovy:jar:2.4.7:compile
[INFO] +- org.springframework.boot:spring-boot-starter-jetty:jar:1.4.2.RELEASE:compile
[INFO] | +- org.eclipse.jetty:jetty-servlets:jar:9.3.14.v20161028:compile
[INFO] | | +- org.eclipse.jetty:jetty-continuation:jar:9.3.14.v20161028:compile
[INFO] | | +- org.eclipse.jetty:jetty-http:jar:9.3.14.v20161028:compile
[INFO] | | +- org.eclipse.jetty:jetty-util:jar:9.3.14.v20161028:compile
[INFO] | | \- org.eclipse.jetty:jetty-io:jar:9.3.14.v20161028:compile
[INFO] | +- org.eclipse.jetty:jetty-webapp:jar:9.3.14.v20161028:compile
[INFO] | | +- org.eclipse.jetty:jetty-xml:jar:9.3.14.v20161028:compile
[INFO] | | \- org.eclipse.jetty:jetty-servlet:jar:9.3.14.v20161028:compile
[INFO] | | \- org.eclipse.jetty:jetty-security:jar:9.3.14.v20161028:compile
[INFO] | | \- org.eclipse.jetty:jetty-server:jar:9.3.14.v20161028:compile
[INFO] | +- org.eclipse.jetty.websocket:websocket-server:jar:9.3.14.v20161028:compile
[INFO] | | +- org.eclipse.jetty.websocket:websocket-common:jar:9.3.14.v20161028:compile
[INFO] | | | \- org.eclipse.jetty.websocket:websocket-api:jar:9.3.14.v20161028:compile
[INFO] | | +- org.eclipse.jetty.websocket:websocket-client:jar:9.3.14.v20161028:compile
[INFO] | | \- org.eclipse.jetty.websocket:websocket-servlet:jar:9.3.14.v20161028:compile
[INFO] | | \- javax.servlet:javax.servlet-api:jar:3.1.0:compile
[INFO] | +- org.eclipse.jetty.websocket:javax-websocket-server-impl:jar:9.3.14.v20161028:compile
[INFO] | | +- org.eclipse.jetty:jetty-annotations:jar:9.3.14.v20161028:compile
[INFO] | | | +- org.eclipse.jetty:jetty-plus:jar:9.3.14.v20161028:compile
[INFO] | | | +- javax.annotation:javax.annotation-api:jar:1.2:compile
[INFO] | | | +- org.ow2.asm:asm:jar:5.0.1:compile
[INFO] | | | \- org.ow2.asm:asm-commons:jar:5.0.1:compile
[INFO] | | | \- org.ow2.asm:asm-tree:jar:5.0.1:compile
[INFO] | | +- org.eclipse.jetty.websocket:javax-websocket-client-impl:jar:9.3.14.v20161028:compile
[INFO] | | \- javax.websocket:javax.websocket-api:jar:1.0:compile
[INFO] | \- org.mortbay.jasper:apache-el:jar:8.0.33:compile
[INFO] +- org.springframework.boot:spring-boot-devtools:jar:1.4.2.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot:jar:1.4.2.RELEASE:compile
[INFO] | | \- org.springframework:spring-context:jar:4.3.4.RELEASE:compile
[INFO] | \- org.springframework.boot:spring-boot-autoconfigure:jar:1.4.2.RELEASE:compile
PS 用 Spring Boot 1.4.2.RELEASE 测试
Note
Spring Boot 1.4.2.RELEASE use Jetty 9.3.14.v20161028
参考
Spring Boot + JUnit 5 + Mockito
在本文中,我们将向您展示如何用 JUnit 5 和 Mockito 进行 Spring Boot 2 集成测试。
- Spring Boot 2.1.2 .版本
- JUnit 5
- Mockito 2
- maven3
简而言之,从spring-boot-starter-test
中排除 junit4,手动包含 JUnit 5 jupiter 引擎,完成。
让我们看看下面的 Spring boot MVC web 应用,以及如何用 JUnit 5 进行单元测试,用 Mockito 框架进行 MVC。
1.专家
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project
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.mkyong.spring</groupId>
<artifactId>testing-junit5-mockito</artifactId>
<version>1.0</version>
<properties>
<java.version>1.8</java.version>
<junit-jupiter.version>5.3.2</junit-jupiter.version>
<mockito.version>2.24.0</mockito.version>
</properties>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<dependencies>
<!-- mvc -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- exclude junit 4 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- junit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${
junit-jupiter.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</build>
</project>
显示项目依赖关系。
$ mvn dependency:tree
[INFO] com.mkyong.spring:testing-junit5-mockito:jar:1.0
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.1.2.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.1.2.RELEASE:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.1.2.RELEASE:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.11.1:compile
[INFO] | | | | \- org.apache.logging.log4j:log4j-api:jar:2.11.1:compile
[INFO] | | | \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
[INFO] | | +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO] | | \- org.yaml:snakeyaml:jar:1.23:runtime
[INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.1.2.RELEASE:compile
[INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.8:compile
[INFO] | | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO] | | | \- com.fasterxml.jackson.core:jackson-core:jar:2.9.8:compile
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.8:compile
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.8:compile
[INFO] | | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.8:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.2.RELEASE:compile
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.14:compile
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.14:compile
[INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.14:compile
[INFO] | +- org.hibernate.validator:hibernate-validator:jar:6.0.14.Final:compile
[INFO] | | +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
[INFO] | | \- com.fasterxml:classmate:jar:1.4.0:compile
[INFO] | +- org.springframework:spring-web:jar:5.1.4.RELEASE:compile
[INFO] | | \- org.springframework:spring-beans:jar:5.1.4.RELEASE:compile
[INFO] | \- org.springframework:spring-webmvc:jar:5.1.4.RELEASE:compile
[INFO] | +- org.springframework:spring-aop:jar:5.1.4.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:5.1.4.RELEASE:compile
[INFO] | \- org.springframework:spring-expression:jar:5.1.4.RELEASE:compile
[INFO] +- org.springframework.boot:spring-boot-starter-test:jar:2.1.2.RELEASE:test
[INFO] | +- org.springframework.boot:spring-boot-test:jar:2.1.2.RELEASE:test
[INFO] | +- org.springframework.boot:spring-boot-test-autoconfigure:jar:2.1.2.RELEASE:test
[INFO] | +- com.jayway.jsonpath:json-path:jar:2.4.0:test
[INFO] | | +- net.minidev:json-smart:jar:2.3:test
[INFO] | | | \- net.minidev:accessors-smart:jar:1.2:test
[INFO] | | | \- org.ow2.asm:asm:jar:5.0.4:test
[INFO] | | \- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] | +- org.assertj:assertj-core:jar:3.11.1:test
[INFO] | +- org.mockito:mockito-core:jar:2.24.0:test
[INFO] | | +- net.bytebuddy:byte-buddy:jar:1.9.7:test
[INFO] | | +- net.bytebuddy:byte-buddy-agent:jar:1.9.7:test
[INFO] | | \- org.objenesis:objenesis:jar:2.6:test
[INFO] | +- org.hamcrest:hamcrest-core:jar:1.3:test
[INFO] | +- org.hamcrest:hamcrest-library:jar:1.3:test
[INFO] | +- org.skyscreamer:jsonassert:jar:1.5.0:test
[INFO] | | \- com.vaadin.external.google:android-json:jar:0.0.20131108.vaadin1:test
[INFO] | +- org.springframework:spring-core:jar:5.1.4.RELEASE:compile
[INFO] | | \- org.springframework:spring-jcl:jar:5.1.4.RELEASE:compile
[INFO] | +- org.springframework:spring-test:jar:5.1.4.RELEASE:test
[INFO] | \- org.xmlunit:xmlunit-core:jar:2.6.2:test
[INFO] | \- javax.xml.bind:jaxb-api:jar:2.3.1:test
[INFO] | \- javax.activation:javax.activation-api:jar:1.2.0:test
[INFO] +- org.junit.jupiter:junit-jupiter-engine:jar:5.3.2:test
[INFO] | +- org.apiguardian:apiguardian-api:jar:1.0.0:test
[INFO] | +- org.junit.platform:junit-platform-engine:jar:1.3.2:test
[INFO] | | +- org.junit.platform:junit-platform-commons:jar:1.3.2:test
[INFO] | | \- org.opentest4j:opentest4j:jar:1.1.1:test
[INFO] | \- org.junit.jupiter:junit-jupiter-api:jar:5.3.2:test
[INFO] \- org.springframework.boot:spring-boot-devtools:jar:2.1.2.RELEASE:compile (optional)
[INFO] +- org.springframework.boot:spring-boot:jar:2.1.2.RELEASE:compile
[INFO] \- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.2.RELEASE:compile
2.测试 Spring Boot + JUnit 5 + Mockito。
2.1 测试下列弹簧部件。
HelloServiceImpl.java
package com.mkyong.core.services;
import com.mkyong.core.repository.HelloRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class HelloServiceImpl implements HelloService {
@Autowired
HelloRepository helloRepository;
@Override
public String get() {
return helloRepository.get();
}
}
HelloRepositoryImpl.java
package com.mkyong.core.repository;
import org.springframework.stereotype.Repository;
@Repository
public class HelloRepositoryImpl implements HelloRepository {
@Override
public String get() {
return "Hello JUnit 5";
}
}
2.2 JUnit 5
HelloServiceTest.java
package com.mkyong.core.services;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest
public class HelloServiceTest {
@Autowired
HelloService helloService;
@DisplayName("Test Spring @Autowired Integration")
@Test
void testGet() {
assertEquals("Hello JUnit 5", helloService.get());
}
}
2.3 Mockito.
HelloServiceMockTest.java
package com.mkyong.core.services;
import com.mkyong.core.repository.HelloRepository;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.mockito.Mockito.when;
@SpringBootTest
public class HelloServiceMockTest {
@Mock
private HelloRepository helloRepository;
@InjectMocks // auto inject helloRepository
private HelloService helloService = new HelloServiceImpl();
@BeforeEach
void setMockOutput() {
when(helloRepository.get()).thenReturn("Hello Mockito From Repository");
}
@DisplayName("Test Mock helloService + helloRepository")
@Test
void testGet() {
assertEquals("Hello Mockito From Repository", helloService.get());
}
}
3.测试 Spring MVC 控制器。
3.1 MVC 控制器。
MainController.java
package com.mkyong.core.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MainController {
@ResponseBody
@GetMapping("/")
public String hello() {
return "Hello Controller";
}
}
3.2 JUnit 5 和 MVC 测试。
MainControllerTest.java
package com.mkyong.core.controller;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.boot.test.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;
import java.net.URL;
import static org.junit.jupiter.api.Assertions.assertEquals;
@SpringBootTest(webEnvironment = WebEnvironment.RANDOM_PORT)
public class MainControllerTest {
// bind the above RANDOM_PORT
@LocalServerPort
private int port;
@Autowired
private TestRestTemplate restTemplate;
@Test
public void getHello() throws Exception {
ResponseEntity<String> response = restTemplate.getForEntity(
new URL("http://localhost:" + port + "/").toString(), String.class);
assertEquals("Hello Controller", response.getBody());
}
}
完成了。
下载源代码
$ git clone https://github.com/mkyong/spring-boot.git
$ cd testing-junit5-mockito
$ mvn test
参考
Spring Boot Log4j 2 示例
在本教程中,我们将向您展示如何在 Spring Boot 框架中使用 Apache Log4j 2 。
使用的技术:
- Spring Boot 2.1.2 .版本
- 弹簧 5.1.4 释放
- Log4j 2.11.1
- maven3
- Java 8
1.项目目录
2.专家
关键是排除默认logback
,用spring-boot-starter-log4j2
包含log4j
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project
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>
<artifactId>logging-log4j2</artifactId>
<packaging>jar</packaging>
<name>Spring Boot log4j2 Example</name>
<url>https://www.mkyong.com</url>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<!-- exclude logback , add log4j2 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
</dependency>
<!-- asynchronous loggers -->
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
<!-- for log4j2.yml, need jackson-databind and jackson-dataformat-yaml -->
<!-- spring-boot-starter-web -> spring-boot-starter-json -> jackson-databind-->
<!-- included by spring boot
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Package as an executable jar/war -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</build>
</project>
显示项目依赖关系。
$ mvn dependency:tree
[INFO] \- org.springframework.boot:spring-boot-starter-log4j2:jar:2.1.2.RELEASE:compile
[INFO] +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.11.1:compile <--- slf4j to log4j bridge
[INFO] | \- org.apache.logging.log4j:log4j-api:jar:2.11.1:compile
[INFO] +- org.apache.logging.log4j:log4j-core:jar:2.11.1:compile
[INFO] +- org.apache.logging.log4j:log4j-jul:jar:2.11.1:compile
[INFO] \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
$ mvn dependency:tree
[INFO] org.springframework.boot:logging-log4j2:jar:1.0
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.1.2.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.1.2.RELEASE:compile
[INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.8:compile
[INFO] | | | \- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.8:compile
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.8:compile
[INFO] | | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.8:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.2.RELEASE:compile
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.14:compile
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.14:compile
[INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.14:compile
[INFO] | +- org.hibernate.validator:hibernate-validator:jar:6.0.14.Final:compile
[INFO] | | +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
[INFO] | | \- com.fasterxml:classmate:jar:1.4.0:compile
[INFO] | +- org.springframework:spring-web:jar:5.1.4.RELEASE:compile
[INFO] | | \- org.springframework:spring-beans:jar:5.1.4.RELEASE:compile
[INFO] | \- org.springframework:spring-webmvc:jar:5.1.4.RELEASE:compile
[INFO] | +- org.springframework:spring-aop:jar:5.1.4.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:5.1.4.RELEASE:compile
[INFO] | \- org.springframework:spring-expression:jar:5.1.4.RELEASE:compile
[INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:2.1.2.RELEASE:compile
[INFO] | +- org.thymeleaf:thymeleaf-spring5:jar:3.0.11.RELEASE:compile
[INFO] | | +- org.thymeleaf:thymeleaf:jar:3.0.11.RELEASE:compile
[INFO] | | | +- org.attoparser:attoparser:jar:2.0.5.RELEASE:compile
[INFO] | | | \- org.unbescape:unbescape:jar:1.1.6.RELEASE:compile
[INFO] | | \- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] | \- org.thymeleaf.extras:thymeleaf-extras-java8time:jar:3.0.2.RELEASE:compile
[INFO] +- org.springframework.boot:spring-boot-starter:jar:2.1.2.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot:jar:2.1.2.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.2.RELEASE:compile
[INFO] | +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO] | +- org.springframework:spring-core:jar:5.1.4.RELEASE:compile
[INFO] | | \- org.springframework:spring-jcl:jar:5.1.4.RELEASE:compile
[INFO] | \- org.yaml:snakeyaml:jar:1.23:compile
[INFO] +- org.springframework.boot:spring-boot-starter-log4j2:jar:2.1.2.RELEASE:compile
[INFO] | +- org.apache.logging.log4j:log4j-slf4j-impl:jar:2.11.1:compile
[INFO] | | \- org.apache.logging.log4j:log4j-api:jar:2.11.1:compile
[INFO] | +- org.apache.logging.log4j:log4j-core:jar:2.11.1:compile
[INFO] | +- org.apache.logging.log4j:log4j-jul:jar:2.11.1:compile
[INFO] | \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
[INFO] +- com.lmax:disruptor:jar:3.4.2:compile
[INFO] \- com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:jar:2.9.8:compile
[INFO] \- com.fasterxml.jackson.core:jackson-core:jar:2.9.8:compile
3.log4j2.xml
3.1 在项目类路径中创建一个log4j2.xml
,src/resources/
src/resources/log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
<Appenders>
<Console name="LogToConsole" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
<File name="LogToFile" fileName="logs/app.log">
<PatternLayout>
<Pattern>%d %p %c{
1.} [%t] %m%n</Pattern>
</PatternLayout>
</File>
</Appenders>
<Loggers>
<Logger name="com.mkyong" level="debug" additivity="false">
<AppenderRef ref="LogToFile"/>
<AppenderRef ref="LogToConsole"/>
</Logger>
<Logger name="org.springframework.boot" level="error" additivity="false">
<AppenderRef ref="LogToConsole"/>
</Logger>
<Root level="error">
<AppenderRef ref="LogToFile"/>
<AppenderRef ref="LogToConsole"/>
</Root>
</Loggers>
</Configuration>
3.2 对于log4j2.yml
,我们需要包含jackson-databind
和jackson-dataformat-yaml
,因为jackson-databind
已经包含在 Spring Boot 启动器中,所以我们只需要包含jackson-dataformat-yaml
pom.xml
<!-- spring-boot-starter-web -> spring-boot-starter-json -> jackson-databind-->
<!-- included by spring boot
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
-->
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-yaml</artifactId>
</dependency>
log4j2.yml
Configuration:
status: debug
appenders:
Console:
name: LogToConsole
PatternLayout:
Pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
RollingFile:
- name: LogToRollingFile
fileName: logs/app.log
filePattern: "logs/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"
PatternLayout:
pattern: "[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n"
Policies:
SizeBasedTriggeringPolicy:
size: 10MB
DefaultRollOverStrategy:
max: 10
Loggers:
logger:
- name: com.mkyong
level: debug
additivity: false
AppenderRef:
- ref: LogToConsole
- ref: LogToRollingFile
Root:
level: error
AppenderRef:
ref: LogToConsole
4.你好 log4j2
4.1 一个简单的 Spring MVC web 应用,用 log4j2 登录。
HelloController.java
package com.mkyong;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Arrays;
import java.util.List;
@Controller
public class HelloController {
private static final Logger logger = LogManager.getLogger(HelloController.class);
private List<Integer> num = Arrays.asList(1, 2, 3, 4, 5);
@GetMapping("/")
public String main(Model model) {
// pre-java 8
if (logger.isDebugEnabled()) {
logger.debug("Hello from Log4j 2 - num : {}", num);
}
// java 8 lambda, no need to check log level
logger.debug("Hello from Log4j 2 - num : {}", () -> num);
model.addAttribute("tasks", num);
return "welcome"; //view
}
private int getNum() {
return 100;
}
}
4.2 模板
src/resources/templates/welcome.html
<!DOCTYPE HTML>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head></head>
<body>
<h1>Spring Boot + log4j2 example</h1>
<ul>
<li th:each="task : ${tasks}" th:text="${task}"></li>
</ul>
</body>
</html>
5.演示
5.1 启动 Spring Boot
StartApplication.java
package com.mkyong;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class StartApplication {
public static void main(String[] args) {
SpringApplication.run(StartApplication.class, args);
}
}
http://localhost:8080
查看日志记录:
Terminal
19:10:08.723 [http-nio-8080-exec-1] DEBUG com.mkyong.HelloController - Hello from Log4j 2 - num : [1, 2, 3, 4, 5]
19:10:08.724 [http-nio-8080-exec-1] DEBUG com.mkyong.HelloController - Hello from Log4j 2 - num : [1, 2, 3, 4, 5]
6.log4j 2–异步记录器
6.1 要启用异步日志,我们需要包含disruptor
pom.xml
<dependency>
<groupId>com.lmax</groupId>
<artifactId>disruptor</artifactId>
<version>3.4.2</version>
</dependency>
6.2 设置系统属性log4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector
Terminal
$ mvn package
$ java -Dlog4j2.contextSelector=org.apache.logging.log4j.core.async.AsyncLoggerContextSelector -jar target/logging-log4j2-1.0.jar
019-03-27 19:28:57,185 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3
2019-03-27 19:28:57,189 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=AsyncLoggerRingBuffer
2019-03-27 19:28:57,194 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=StatusLogger
2019-03-27 19:28:57,195 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=ContextSelector
2019-03-27 19:28:57,195 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Loggers,name=org.springframework.boot
2019-03-27 19:28:57,196 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Loggers,name=
2019-03-27 19:28:57,196 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Loggers,name=com.mkyong
2019-03-27 19:28:57,197 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Appenders,name=LogToConsole
2019-03-27 19:28:57,200 main DEBUG Registering MBean org.apache.logging.log4j2:type=AsyncContext@578486a3,component=Appenders,name=LogToFile
下载源代码
$ git clone https://github.com/mkyong/spring-boot.git
$ cd logging-log4j2
$ mvn spring-boot:run
Access localhost:8080
$ mvn 包
$ Java-dlog 4j 2 . context selector = org . Apache . logging . log4j . core . async . asyncloggercontextselector-jar target/logging-log4j 2-1.0 . jar
Accesslocalhost:8080
参考
Spring Boot 非 web 应用示例
在 Spring Boot,要创建一个非 web 应用程序,实现CommandLineRunner
并覆盖run
方法,例如:
import org.springframework.boot.CommandLineRunner;
@SpringBootApplication
public class SpringBootConsoleApplication implements CommandLineRunner {
public static void main(String[] args) throws Exception {
SpringApplication.run(SpringBootConsoleApplication.class, args);
}
//access command line arguments
@Override
public void run(String... args) throws Exception {
//do something
}
}
1.项目结构
一个标准的 Maven 项目结构。
2.项目依赖性
仅spring-boot-starter
pom.xml
<project
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.mkyong</groupId>
<artifactId>spring-boot-simple</artifactId>
<packaging>jar</packaging>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.1.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Package as an executable jar/war -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.春天
3.1 返回消息的服务。
HelloMessageService.java
package com.mkyong.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class HelloMessageService {
@Value("${name:unknown}")
private String name;
public String getMessage() {
return getMessage(name);
}
public String getMessage(String name) {
return "Hello " + name;
}
}
application.properties
name=mkyong
3.2 CommandLineRunner
示例。如果您运行这个 Spring Boot,那么run
方法将是入口点。
SpringBootConsoleApplication.java
package com.mkyong;
import com.mkyong.service.HelloMessageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.Banner;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import static java.lang.System.exit;
@SpringBootApplication
public class SpringBootConsoleApplication implements CommandLineRunner {
@Autowired
private HelloMessageService helloService;
public static void main(String[] args) throws Exception {
//disabled banner, don't want to see the spring logo
SpringApplication app = new SpringApplication(SpringBootConsoleApplication.class);
app.setBannerMode(Banner.Mode.OFF);
app.run(args);
}
// Put your logic here.
@Override
public void run(String... args) throws Exception {
if (args.length > 0) {
System.out.println(helloService.getMessage(args[0].toString()));
} else {
System.out.println(helloService.getMessage());
}
exit(0);
}
}
4.演示
打包并运行它。
## Go to project directory
## package it
$ mvn package
$ java -jar target/spring-boot-simple-1.0.jar
Hello mkyong
$ java -jar target/spring-boot-simple-1.0.jar "donald trump"
Hello donald trump
下载源代码
Download – spring-boot-non-web-example.zip (5 KB)
参考
Tags : CommandLineRunner executable jar jar spring boot
相关文章
Spring Boot-基于配置文件的属性和 yaml 示例
在 Spring Boot,它按以下顺序挑选.properties
或.yaml
文件:
application-{profile}.properties
和 YAML 的变种application.properties
和 YAML 的变种
Note
For detail, sequence and order, please refer to this official Externalized Configuration documentation.
测试:
- Spring Boot 2.1.2 .版本
- maven3
1.项目结构
一个标准的 Maven 项目结构。
2.@配置属性
稍后读取属性或 yaml 文件。
ServerProperties.java
package com.mkyong.config;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
@Component
@ConfigurationProperties("server")
public class ServerProperties {
private String email;
private List<Cluster> cluster = new ArrayList<>();
public static class Cluster {
private String ip;
private String path;
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
@Override
public String toString() {
return "Cluster{" +
"ip='" + ip + '\'' +
", path='" + path + '\'' +
'}';
}
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Cluster> getCluster() {
return cluster;
}
public void setCluster(List<Cluster> cluster) {
this.cluster = cluster;
}
@Override
public String toString() {
return "ServerProperties{" +
"email='" + email + '\'' +
", cluster=" + cluster +
'}';
}
}
3.基于配置文件的属性
多个配置文件.properties
示例。
application.properties
#Logging
logging.level.org.springframework.web=ERROR
logging.level.com.mkyong=ERROR
logging.level.=error
#spring
spring.main.banner-mode=off
spring.profiles.active=dev
application-dev.properties
#dev environment
server.email: dev@mkyong.com
server.cluster[0].ip=127.0.0.1
server.cluster[0].path=/dev1
server.cluster[1].ip=127.0.0.2
server.cluster[1].path=/dev2
server.cluster[2].ip=127.0.0.3
server.cluster[2].path=/dev3
application-prod.properties
#production environment
server.email: prod@mkyong.com
server.cluster[0].ip=192.168.0.1
server.cluster[0].path=/app1
server.cluster[1].ip=192.168.0.2
server.cluster[1].path=/app2
server.cluster[2].ip=192.168.0.3
server.cluster[2].path=/app3
4.基于配置文件的 YAML
多个配置文件.yml
示例。在 YAML,我们可以通过使用“—”分隔符来创建多个概要文件。
application.yml
logging:
level:
.: error
org.springframework: ERROR
com.mkyong: ERROR
spring:
profiles:
active: "dev"
main:
banner-mode: "off"
server:
email: default@mkyong.com
---
spring:
profiles: dev
server:
email: dev@mkyong.com
cluster:
- ip: 127.0.0.1
path: /dev1
- ip: 127.0.0.2
path: /dev2
- ip: 127.0.0.3
path: /dev3
---
spring:
profiles: prod
server:
email: prod@mkyong.com
cluster:
- ip: 192.168.0.1
path: /app1
- ip: 192.168.0.2
path: /app2
- ip: 192.168.0.3
path: /app3
5.演示
5.1 Spring Boot 应用程序。
Application.java
package com.mkyong;
import com.mkyong.config.ServerProperties;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private ServerProperties serverProperties;
@Override
public void run(String... args) {
System.out.println(serverProperties);
}
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
5.2 打包并运行它。
$ mvn package
# The 'dev' profile is configured in application.properties
# Profile : dev , picks application-dev.properties or YAML
$ java -jar target/spring-boot-profile-1.0.jar
ServerProperties{
email='[email protected]', cluster=[
Cluster{
ip='127.0.0.1', path='/dev1'},
Cluster{
ip='127.0.0.2', path='/dev2'},
Cluster{
ip='127.0.0.3', path='/dev3'}
]}
# Profile : prod, picks application-prod.properties or YAML
$ java -jar -Dspring.profiles.active=prod target/spring-boot-profile-1.0.jar
ServerProperties{
email='[email protected]', cluster=[
Cluster{
ip='192.168.0.1', path='/app1'},
Cluster{
ip='192.168.0.2', path='/app2'},
Cluster{
ip='192.168.0.3', path='/app3'}
]}
# Profile : abc, a non-exists profile
$ java -jar -Dspring.profiles.active=abc target/spring-boot-profile-1.0.jar
ServerProperties{
email='null', cluster=[]}
Note
Spring Boot, the default profile is default
, we can set the profile via spring.profiles.active
property.
下载源代码
$ git clone https://github.com/mkyong/spring-boot.git
属性示例
$ cd 配置文件-属性
$ mvn 包
YAML 示例
$ cd 简介-yaml
$mvn 包
参考
Spring Boot 配置文件示例
在本文中,我们将向您展示如何在 Spring Boot 使用@Profile
以及如何测试它。
使用的工具:
- Spring Boot 1.5.1 .版本
- 专家
1.项目结构
一个标准的 Maven 项目结构。
## 2.项目依赖性
标准spring-boot-starter
和spring-boot-starter-test
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project
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>
<artifactId>spring-boot-profile</artifactId>
<packaging>jar</packaging>
<name>Spring Boot Profiles Example</name>
<description>Spring Boot Profiles Example</description>
<url>https://www.mkyong.com</url>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.4.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Package as an executable jar/war -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
3.Spring Boot
在 Spring Boot,默认配置文件是“default
”。查看以下天气服务。
3.1 一个接口。
WeatherService.java
package com.mkyong.service;
public interface WeatherService {
String forecast();
}
3.2 简介:阳光默认。
SunnyDayService.java
package com.mkyong.service;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
@Service
@Profile({
"sunny", "default"})
public class SunnyDayService implements WeatherService {
@Override
public String forecast() {
return "Today is sunny day!";
}
}
3.3 简介:下雨。
RainingDayService.java
package com.mkyong.service;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;
@Service
@Profile("raining")
public class RainingDayService implements WeatherService {
@Override
public String forecast() {
return "Today is raining day!";
}
}
3.4 启动 Spring Boot 应用程序。
Application.java
package com.mkyong;
import com.mkyong.service.WeatherService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private WeatherService weatherService;
@Override
public void run(String... args) throws Exception {
//weather forecast, default is sunny day!
System.out.println(weatherService.forecast());
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
3.5 属性文件。
application.properties
# default profile is 'defau;t'
#spring.profiles.active=sunny
logging.level.=error
spring.main.banner-mode=off
4.单元测试
一些单元测试的例子。
4.1 服务类的单元测试。通过@ActiveProfiles
设置激活的个人信息
TestWeatherService.java
package com.mkyong;
import com.mkyong.service.WeatherService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import static org.assertj.core.api.Assertions.assertThat;
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("raining")
public class TestWeatherService {
@Autowired
WeatherService weatherService;
@Test
public void testRainingProfile() throws Exception {
String output = weatherService.forecast();
assertThat(output).contains("Today is raining day!");
}
}
4.2 对 Spring Boot 应用程序进行单元测试。您可以通过属性spring.profiles.active
设置活动配置文件
TestApplication.java
package com.mkyong;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.springframework.boot.test.rule.OutputCapture;
import static org.assertj.core.api.Assertions.assertThat;
public class TestApplication {
@Rule
public OutputCapture outputCapture = new OutputCapture();
@Test
public void testDefaultProfile() throws Exception {
Application.main(new String[0]);
String output = this.outputCapture.toString();
assertThat(output).contains("Today is sunny day!");
}
@Test
public void testRainingProfile() throws Exception {
System.setProperty("spring.profiles.active", "raining");
Application.main(new String[0]);
String output = this.outputCapture.toString();
assertThat(output).contains("Today is raining day!");
}
@Test
public void testRainingProfile_withDoption() throws Exception {
Application.main(new String[]{
"--spring.profiles.active=raining"});
String output = this.outputCapture.toString();
assertThat(output).contains("Today is raining day!");
}
@After
public void after() {
System.clearProperty("spring.profiles.active");
}
}
这个 Spring Boot 的例子值得称赞。
5.演示
打包并运行它。
$ mvn package
#default profile, sunny day!
$ java -jar target/spring-boot-profile-1.0.jar
Today is sunny day!
# set a profile
$ java -jar -Dspring.profiles.active=raining target/spring-boot-profile-1.0.jar
Today is raining day!
下载源代码
Download – spring-boot-profile-example.zip (5 KB)
参考
profiles spring boot spring profile
Spring Boot-应用程序启动时运行代码
在 Spring Boot,当应用程序完全启动时,我们可以创建一个CommandLineRunner
bean 来运行代码。
StartBookApplication.java
package com.mkyong;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
@SpringBootApplication
public class StartBookApplication {
public static void main(String[] args) {
SpringApplication.run(StartBookApplication.class, args);
}
// Injects a repository bean
@Bean
CommandLineRunner initDatabase(BookRepository repository) {
return args -> {
repository.save(
new Book("A Guide to the Bodhisattva Way of Life")
);
};
}
// Injects a ApplicationContext
@Bean
CommandLineRunner initPrint(ApplicationContext ctx) {
return args -> {
System.out.println("All beans loaded by Spring Boot:\n");
List<String> beans = Arrays.stream(ctx.getBeanDefinitionNames())
.sorted(Comparator.naturalOrder())
.collect(Collectors.toList());
beans.forEach(x -> System.out.println(x));
};
}
// Injects nothing
@Bean
CommandLineRunner initPrintOneLine() {
return args -> {
System.out.println("Hello World Spring Boot!");
};
}
}
用 Spring Boot 2 号进行了测试
参考
Spring Boot–显示 Hibernate SQL 查询
在application.properties
中添加以下行来记录 Hibernate SQL 查询。
application.properties
#show sql statement
logging.level.org.hibernate.SQL=debug
#show sql values
logging.level.org.hibernate.type.descriptor.sql=trace
1.org.hibernate.SQL=debug
application.properties
logging.level.org.hibernate.SQL=debug
1.1 选择查询。
Console
2017-02-23 21:36:42 DEBUG org.hibernate.SQL - select customer0_.id as id1_0_,
customer0_.created_date as created_date2_0_, customer0_.email as email3_0_,
customer0_.name as name4_0_ from customer customer0_
2.org . hibernate . type . descriptor . SQL = trace
application.properties
logging.level.org.hibernate.SQL=debug
logging.level.org.hibernate.type.descriptor.sql=trace
2.1 选择查询及其值。
Console
2017-02-23 21:39:23 DEBUG org.hibernate.SQL - select customer0_.id as id1_0_,
customer0_.created_date as created_date2_0_, customer0_.email as email3_0_,
customer0_.name as name4_0_ from customer customer0_
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([id1_0_] : [BIGINT]) - [1]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([created_date2_0_] : [TIMESTAMP]) - [2017-02-11 00:00:00.0]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([email3_0_] : [VARCHAR]) - [111@yahoo.com]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([name4_0_] : [VARCHAR]) - [mkyong]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([id1_0_] : [BIGINT]) - [2]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([created_date2_0_] : [TIMESTAMP]) - [2017-02-12 00:00:00.0]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([email3_0_] : [VARCHAR]) - [222@yahoo.com]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([name4_0_] : [VARCHAR]) - [yflow]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([id1_0_] : [BIGINT]) - [3]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([created_date2_0_] : [TIMESTAMP]) - [2017-02-13 00:00:00.0]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([email3_0_] : [VARCHAR]) - [333@yahoo.com]
2017-02-23 21:39:23 TRACE o.h.t.descriptor.sql.BasicExtractor - extracted value ([name4_0_] : [VARCHAR]) - [zilap]
2.2 插入查询及其值。
Console
2017-02-23 21:44:15 DEBUG org.hibernate.SQL - select customer_seq.nextval from dual
2017-02-23 21:44:15 DEBUG org.hibernate.SQL - insert into customer (created_date, email, name, id) values (?, ?, ?, ?)
2017-02-23 21:44:15 TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [1] as [TIMESTAMP] - [Thu Feb 23 21:44:15 SGT 2017]
2017-02-23 21:44:15 TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [aa]
2017-02-23 21:44:15 TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [3] as [VARCHAR] - [a]
2017-02-23 21:44:15 TRACE o.h.type.descriptor.sql.BasicBinder - binding parameter [4] as [BIGINT] - [1]
Note
You might be interested in this article – Hibernate Logging Guide
参考
Spring Boot SLF4j 回溯示例
在本教程中,我们将向您展示如何在 Spring Boot 框架中使用 Logback 。
使用的技术:
- Spring Boot 2.1.2 .版本
- 弹簧 5.1.4 释放
- 回溯 1.2.3
- maven3
- Java 8
1.项目目录
2.专家
在 Spring Boot,Logback 是默认的日志框架,只需添加spring-boot-starter-web
,它将引入logback
依赖项。
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project
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>
<artifactId>spring-boot-slf4j</artifactId>
<packaging>jar</packaging>
<name>Spring Boot SLF4j</name>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<!-- Package as an executable jar/war -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</build>
</project>
显示项目依赖关系。
$ mvn dependency:tree
+- org.springframework.boot:spring-boot-starter-web:jar:2.1.2.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.1.2.RELEASE:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.1.2.RELEASE:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.3:compile
$ mvn dependency:tree
org.springframework.boot:spring-boot-slf4j:jar:1.0
[INFO] +- org.springframework.boot:spring-boot-starter-web:jar:2.1.2.RELEASE:compile
[INFO] | +- org.springframework.boot:spring-boot-starter:jar:2.1.2.RELEASE:compile
[INFO] | | +- org.springframework.boot:spring-boot-starter-logging:jar:2.1.2.RELEASE:compile
[INFO] | | | +- ch.qos.logback:logback-classic:jar:1.2.3:compile
[INFO] | | | | \- ch.qos.logback:logback-core:jar:1.2.3:compile
[INFO] | | | +- org.apache.logging.log4j:log4j-to-slf4j:jar:2.11.1:compile
[INFO] | | | | \- org.apache.logging.log4j:log4j-api:jar:2.11.1:compile
[INFO] | | | \- org.slf4j:jul-to-slf4j:jar:1.7.25:compile
[INFO] | | +- javax.annotation:javax.annotation-api:jar:1.3.2:compile
[INFO] | | +- org.springframework:spring-core:jar:5.1.4.RELEASE:compile
[INFO] | | | \- org.springframework:spring-jcl:jar:5.1.4.RELEASE:compile
[INFO] | | \- org.yaml:snakeyaml:jar:1.23:runtime
[INFO] | +- org.springframework.boot:spring-boot-starter-json:jar:2.1.2.RELEASE:compile
[INFO] | | +- com.fasterxml.jackson.core:jackson-databind:jar:2.9.8:compile
[INFO] | | | +- com.fasterxml.jackson.core:jackson-annotations:jar:2.9.0:compile
[INFO] | | | \- com.fasterxml.jackson.core:jackson-core:jar:2.9.8:compile
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jdk8:jar:2.9.8:compile
[INFO] | | +- com.fasterxml.jackson.datatype:jackson-datatype-jsr310:jar:2.9.8:compile
[INFO] | | \- com.fasterxml.jackson.module:jackson-module-parameter-names:jar:2.9.8:compile
[INFO] | +- org.springframework.boot:spring-boot-starter-tomcat:jar:2.1.2.RELEASE:compile
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-core:jar:9.0.14:compile
[INFO] | | +- org.apache.tomcat.embed:tomcat-embed-el:jar:9.0.14:compile
[INFO] | | \- org.apache.tomcat.embed:tomcat-embed-websocket:jar:9.0.14:compile
[INFO] | +- org.hibernate.validator:hibernate-validator:jar:6.0.14.Final:compile
[INFO] | | +- javax.validation:validation-api:jar:2.0.1.Final:compile
[INFO] | | +- org.jboss.logging:jboss-logging:jar:3.3.2.Final:compile
[INFO] | | \- com.fasterxml:classmate:jar:1.4.0:compile
[INFO] | +- org.springframework:spring-web:jar:5.1.4.RELEASE:compile
[INFO] | | \- org.springframework:spring-beans:jar:5.1.4.RELEASE:compile
[INFO] | \- org.springframework:spring-webmvc:jar:5.1.4.RELEASE:compile
[INFO] | +- org.springframework:spring-aop:jar:5.1.4.RELEASE:compile
[INFO] | +- org.springframework:spring-context:jar:5.1.4.RELEASE:compile
[INFO] | \- org.springframework:spring-expression:jar:5.1.4.RELEASE:compile
[INFO] +- org.springframework.boot:spring-boot-starter-thymeleaf:jar:2.1.2.RELEASE:compile
[INFO] | +- org.thymeleaf:thymeleaf-spring5:jar:3.0.11.RELEASE:compile
[INFO] | | +- org.thymeleaf:thymeleaf:jar:3.0.11.RELEASE:compile
[INFO] | | | +- org.attoparser:attoparser:jar:2.0.5.RELEASE:compile
[INFO] | | | \- org.unbescape:unbescape:jar:1.1.6.RELEASE:compile
[INFO] | | \- org.slf4j:slf4j-api:jar:1.7.25:compile
[INFO] | \- org.thymeleaf.extras:thymeleaf-extras-java8time:jar:3.0.2.RELEASE:compile
[INFO] \- org.springframework.boot:spring-boot-devtools:jar:2.1.2.RELEASE:compile (optional)
[INFO] +- org.springframework.boot:spring-boot:jar:2.1.2.RELEASE:compile
[INFO] \- org.springframework.boot:spring-boot-autoconfigure:jar:2.1.2.RELEASE:compile
3.应用程序.属性
3.1 在application.properties
中配置记录
application.properties
# logging level
logging.level.org.springframework=ERROR
logging.level.com.mkyong=DEBUG
# output to a file
logging.file=app.log
# temp folder example
#logging.file=${
java.io.tmpdir}/app.log
logging.pattern.file=%d %p %c{
1.} [%t] %m%n
logging.pattern.console=%d{
HH:mm:ss.SSS} [%t] %-5level %logger{
36} - %msg%n
## if no active profile, default is 'default'
##spring.profiles.active=prod
# root level
#logging.level.=INFO
3.2 这相当于 YAML 格式。
application.yml
logging:
level:
org.springframework: ERROR
com.mkyong: DEBUG
pattern:
console: "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"
file: "%d %p %c{1.} [%t] %m%n"
file: app.log
4.logback.xml
上面的日志配置对于开发来说已经足够了。对于生产,我们需要更多的日志功能,如文件滚动或 SMTP。在 Spring Boot,我们仍然允许通过标准logback.xml
配置回退
logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="HOME_LOG" value="logs/app.log"/>
<appender name="FILE-ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${
HOME_LOG}</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/archived/app.%d{
yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each archived file, size max 10MB -->
<maxFileSize>10MB</maxFileSize>
<!-- total size of all archive files, if total size > 20GB,
it will delete old archived file -->
<totalSizeCap>20GB</totalSizeCap>
<!-- 60 days to keep -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d %p %c{
1.} [%t] %m%n</pattern>
</encoder>
</appender>
<logger name="com.mkyong" level="debug" additivity="false">
<appender-ref ref="FILE-ROLLING"/>
</logger>
<root level="error">
<appender-ref ref="FILE-ROLLING"/>
</root>
</configuration>
5.按剖面进行 Spring Boot 测井
Note
Read this – Profile-specific configuration
为了利用 Spring Boot 提供的模板特性,我们可以在类路径的根目录下创建一个logback-spring.xml
。
在下面的配置中:
- 如果没有活动的配置文件(默认),则记录到控制台。
- 如果配置文件是
prod
,记录到一个滚动文件。
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<include resource="org/springframework/boot/logging/logback/defaults.xml" />
<springProfile name="default">
<include resource="org/springframework/boot/logging/logback/console-appender.xml"/>
<root level="INFO">
<appender-ref ref="CONSOLE"/>
</root>
</springProfile>
<springProfile name="prod">
<appender name="FILE-ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<fileNamePattern>logs/archived/app.%d{
yyyy-MM-dd}.%i.log</fileNamePattern>
<!-- each archived file, size max 10MB -->
<maxFileSize>10MB</maxFileSize>
<!-- total size of all archive files, if total size > 20GB, it will delete old archived file -->
<totalSizeCap>20GB</totalSizeCap>
<!-- 60 days to keep -->
<maxHistory>60</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d %p %c{
1.} [%t] %m%n</pattern>
</encoder>
</appender>
<logger name="org.springframework" level="INFO"/>
<logger name="com.mkyong" level="DEBUG"/>
<root level="ERROR">
<appender-ref ref="FILE-ROLLING"/>
</root>
</springProfile>
</configuration>
定义一个spring.profiles.active
属性来设置当前活动的配置文件。
application.properties
## if no active profile, default is 'default'
spring.profiles.active=prod
6.你好 Logback
6.1 一个简单的 Spring MVC web 应用程序,记录一些东西。
HelloController.java
package com.mkyong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.Arrays;
import java.util.List;
@Controller
public class HelloController {
private static final Logger logger = LoggerFactory.getLogger(HelloController.class);
@GetMapping("/")
public String hello(Model model) {
List<Integer> data = Arrays.asList(1, 2, 3, 4, 5);
logger.debug("Hello from Logback {}", data);
model.addAttribute("num", data);
return "index"; // index.html
}
}
6.2 模板
src/resources/templates/index.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<title>Spring Boot SLF4j Logback</title>
<link rel="stylesheet" th:href="@{/css/main.css}" href="../../css/main.css"/>
</head>
<body>
<h1>Spring Boot + SLF4j Logback example</h1>
<ul>
<li th:each="n : ${num}" th:text="${n}"></li>
</ul>
</body>
</html>
6.3 CSS
src/resources/static/css/main.css
h1{
color:#0000FF;
}
7.演示
7.1 启动 Spring Boot
StartWebApplication.java
package com.mkyong;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class StartWebApplication {
public static void main(String[] args) {
SpringApplication.run(StartWebApplication.class, args);
}
}
http://localhost:8080
Terminal
15:15:11.588 [http-nio-8080-exec-1] DEBUG com.mkyong.HelloController - Hello from Logback [1, 2, 3, 4, 5]
下载源代码
$ git clone https://github.com/mkyong/spring-boot.git
$ cd logging-slf4j-logback
$ mvn spring-boot:run
访问 localhost:8080
查看控制台记录信息。
参考
- Spring Boot 测井
- 回溯项目
- stack overflow–Spring Boot:我如何用 application.properties 设置日志级别?
- SLF4J 后勤指南
- logback.xml 示例
Spring Boot +春季数据 JPA + Java 8 日期和时间(JSR310)
在 Spring Boot + Spring Data JPA 应用程序中,为了支持 JSR 310java.time.*
API,我们需要手动注册这个Jsr310JpaConverters
。
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;
@EntityScan(
basePackageClasses = {
Application.class, Jsr310JpaConverters.class}
)
@SpringBootApplication
public class Application {
//...
}
用 Spring Boot 1.5.1 .版本测试的 PS,Spring Data JPA 1.11.0 .版本
1.完整示例
1.1 一个模型包含一个java.time.LocalDate
字段。
package com.mkyong.model;
import javax.persistence.*;
import java.time.LocalDate;
@Entity
public class Customer {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "CUST_SEQ")
@SequenceGenerator(sequenceName = "customer_seq", allocationSize = 1, name = "CUST_SEQ")
Long id;
String name;
@Column(name = "CREATED_DATE")
LocalDate date;
//...
1.2 @EntityScan
扫描并记录Jsr310JpaConverters
如下:
package com.mkyong;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;
import java.util.Arrays;
//for jsr310 java 8 java.time.*
@EntityScan(
basePackageClasses = {
Application.class, Jsr310JpaConverters.class}
)
@SpringBootApplication
public class Application {
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@Bean
public CommandLineRunner run(ApplicationContext appContext) {
return args -> {
System.out.println("hello World!");
};
}
}
参考
Spring Boot +春天数据 JPA + MySQL
之前的 Spring Boot + Spring 数据 JPA 将被重用,修改为支持 MySQL 数据库。
使用的技术:
- Spring Boot 2.1.2 .版本
- 弹簧 5.1.4 释放
- 休眠 5.3.7
- HikariCP 3.2.0
- MySQL-连接器-java:jar 8.0.13
- maven3
- Java 8
1.专家
为了连接一个 MySQL,声明mysql-connector-java
pom.xml
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project
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>
<artifactId>spring-boot-data-jpa</artifactId>
<packaging>jar</packaging>
<name>Spring Boot Spring Data JPA</name>
<version>1.0</version>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.2.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</properties>
<dependencies>
<!-- jpa, crud repository -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.22.0</version>
</plugin>
</plugins>
</build>
</project>
2.配置 MySQL
2.1 更新spring.datasource.*
中的 MySQL 设置
application.properties
## MySQL
spring.datasource.url=jdbc:mysql://localhost:3306/wordpress
spring.datasource.username=mkyong
spring.datasource.password=password
#`hibernate_sequence' doesn't exist
spring.jpa.hibernate.use-new-id-generator-mappings=false
# drop n create table, good for testing, comment this in production
spring.jpa.hibernate.ddl-auto=create
完成了。
下载源代码
$ git clone https://github.com/mkyong/spring-boot.git
$ cd spring-data-jpa-mysql
$ mvn spring-boot:run