SpringBoot 第二弾

应用程序之类创建

用Spring Initializr创建一个简单的应用程序类.但是,这样未免也太单调了一点.有必要像下面的列表这样改动一下应用程序类.

package com.example.springboot;

import java.util.Arrays;

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;

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

	@Bean
	public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
		return args -> {

			System.out.println("Let's inspect the beans provided by Spring Boot:");

			String[] beanNames = ctx.getBeanDefinitionNames();
			Arrays.sort(beanNames);
			for (String beanName : beanNames) {
				System.out.println(beanName);
			}

		};
	}

}COPY

@SpringBootApplication这个方便的注解可以装配以下所有的注解.

  • @Configuration: 作为应用程序上下文的Bean定义的源码在类上加上标签

  • @EnableAutoConfiguration: 基于类路径设置,其它Bean,各种各样的属性设置指示SpringBoot开始Bean的追加.例:如果在类路径上有spring-webmvc的话,该注解会作为web应用程序在应用程序上创建类,DispatcherServlet 的装配等主要动作会是主动的.

  • @ComponentScan: 在Spring查找com/example包内的其它组件,构成,服务,指示检测出控制器.

    主函数main方法使用SpringBoot的SpringApplication.run() 方法启动应用程序.注意到xml一行都没有了吗?也没有web.xml文件.该web应用程序是100%纯粹的Java,不需要对应处理接续功能和基础架构的构成.

    也有作为@Bean 被标记的CommandLineRunner 方法,启动的时候执行.根据应用程序来创建,或者根据SpringBoot获取自动追加的所有Bean.排序,然后输出.

    执行应用程序

    要执行应用程序,在终端窗口(complete里面)目录执行下面代码.

    ./gradlew bootRun
    

    使用Maven的话,在终端窗口(complete里面)目录执行下面代码.

./mvnw spring-boot:run

显示如下输出

Let's inspect the beans provided by Spring Boot:
application
beanNameHandlerMapping
defaultServletHandlerMapping
dispatcherServlet
embeddedServletContainerCustomizerBeanPostProcessor
handlerExceptionResolver
helloController
httpRequestHandlerAdapter
messageSource
mvcContentNegotiationManager
mvcConversionService
mvcValidator
org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration
org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration$DispatcherServletConfiguration
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration
org.springframework.boot.context.embedded.properties.ServerProperties
org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
propertySourcesBinder
propertySourcesPlaceholderConfigurer
requestMappingHandlerAdapter
requestMappingHandlerMapping
resourceHandlerMapping
simpleControllerHandlerAdapter
tomcatEmbeddedServletContainerFactory
viewControllerHandlerMappingCOPY

org.springframework.boot.autoconfigure可以很清晰看见Bean.

还有tomcatEmbeddedServletContainerFactory.

执行下面的命令,在curl执行服务.(别的终端窗口)(同时显示输出)

$ curl localhost:8080
Greetings from Spring Boot!COPY

添加单体测试

有必要添加追加的后端测试(我觉得是后端,也有可能是终端).SpringTest提供了若干的方式(機構翻译为机构感觉不太合理).

使用Gradle的话,在build.gradle 目录添加如下依赖关系.

testImplementation('org.springframework.boot:spring-boot-starter-test')COPY

使用Maven的话,在pom.xml文件里添加如下依赖.

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-test</artifactId>
	<scope>test</scope>
</dependency>COPY   (突然发现代码里都有个COPY,这个是不需要的)

同下面的代码所示,通过后端模仿Servlet的request和response创建简单的单体测试.

package com.example.springboot;

import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {

	@Autowired
	private MockMvc mvc;

	@Test
	public void getHello() throws Exception {
		mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
				.andExpect(status().isOk())
				.andExpect(content().string(equalTo("Greetings from Spring Boot!")));
	}
}

MockMvc 是从SpringTest衍生而来的,通过便利的builder类装配,发送HTTP request给DispatcherServlet,可以对结果进行调试(assertion 断言. 异常或说是错误也可以, 可以用来调试测试结果,可能说的不准确).

使用@AutoConfigureMockMvc以及@SpringBootTest 请注意注入 MockMvc实例.由于使用了@SpringBootTest ,要求可以创建应用程序Context整体.别的函数,使用@WebMvcTest只 创建Context的web层也要依赖SpringBoot.不管怎样,SpringBoot会自动查找应用程序的主应用程序类,构造别的东西的话,是否重写,还是可以锁定的.

不仅是测试HTTP request循环,使用SpringBoot,还可以做成简单的全栈式统一测试.例:代替前面展示的Mock测试(和之前一样),可以进行下面的测试.

package com.example.springboot;

import static org.assertj.core.api.Assertions.*;

import java.net.URL;

import org.junit.jupiter.api.BeforeEach;
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.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {

	@LocalServerPort
	private int port;

	private URL base;

	@Autowired
	private TestRestTemplate template;

    @BeforeEach
    public void setUp() throws Exception {
        this.base = new URL("http://localhost:" + port + "/");
    }

    @Test
    public void getHello() throws Exception {
        ResponseEntity<String> response = template.getForEntity(base.toString(),
                String.class);
        assertThat(response.getBody()).isEqualTo("Greetings from Spring Boot!");
    }
}

webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT嵌入式服务器使用随机的端口启动,执行的时候使用 @LocalServerPort 检测实际的端口.

アプリケーションクラスを作成する

Spring Initializr は、簡単なアプリケーションクラスを作成します。ただし、この場合は単純すぎます。次のリストに一致するようにアプリケーションクラスを変更する必要があります(src/main/java/com/example/springboot/Application.java から)。

package com.example.springboot;

import java.util.Arrays;

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;

@SpringBootApplication
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

	@Bean
	public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
		return args -> {

			System.out.println("Let's inspect the beans provided by Spring Boot:");

			String[] beanNames = ctx.getBeanDefinitionNames();
			Arrays.sort(beanNames);
			for (String beanName : beanNames) {
				System.out.println(beanName);
			}

		};
	}

}COPY

@SpringBootApplication は、次のすべてを追加する便利なアノテーションです。

  • @Configuration: アプリケーションコンテキストの Bean 定義のソースとしてクラスにタグを付けます。
  • @EnableAutoConfiguration: クラスパス設定、他の Bean、さまざまなプロパティ設定に基づいて Bean の追加を開始するよう Spring Boot に指示します。例: spring-webmvc がクラスパスにある場合、このアノテーションはアプリケーションに Web アプリケーションとしてフラグを立て、DispatcherServlet のセットアップなどの主要な動作をアクティブにします。
  • @ComponentScan: Spring に、com/example パッケージ内の他のコンポーネント、構成、サービスを探して、コントローラーを検出させるように指示します。

main() メソッドは、Spring Boot の SpringApplication.run() メソッドを使用してアプリケーションを起動します。XML が 1 行もないことに気付きましたか? web.xml ファイルもありません。この Web アプリケーションは 100% 純粋な Java であり、接続機能やインフラストラクチャの構成に対処する必要はありませんでした。

@Bean としてマークされた CommandLineRunner メソッドもあり、これは起動時に実行されます。アプリケーションによって作成された、または Spring Boot によって自動的に追加されたすべての Bean を取得します。ソートし、出力します。

アプリケーションの実行

アプリケーションを実行するには、ターミナルウィンドウ(complete 内)ディレクトリで次のコマンドを実行します。

./gradlew bootRun

Maven を使用する場合は、ターミナルウィンドウ(complete 内)ディレクトリで次のコマンドを実行します。

./mvnw spring-boot:run

次のような出力が表示されます。

Let's inspect the beans provided by Spring Boot:
application
beanNameHandlerMapping
defaultServletHandlerMapping
dispatcherServlet
embeddedServletContainerCustomizerBeanPostProcessor
handlerExceptionResolver
helloController
httpRequestHandlerAdapter
messageSource
mvcContentNegotiationManager
mvcConversionService
mvcValidator
org.springframework.boot.autoconfigure.MessageSourceAutoConfiguration
org.springframework.boot.autoconfigure.PropertyPlaceholderAutoConfiguration
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration$DispatcherServletConfiguration
org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat
org.springframework.boot.autoconfigure.web.ServerPropertiesAutoConfiguration
org.springframework.boot.context.embedded.properties.ServerProperties
org.springframework.context.annotation.ConfigurationClassPostProcessor.enhancedConfigurationProcessor
org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalRequiredAnnotationProcessor
org.springframework.web.servlet.config.annotation.DelegatingWebMvcConfiguration
propertySourcesBinder
propertySourcesPlaceholderConfigurer
requestMappingHandlerAdapter
requestMappingHandlerMapping
resourceHandlerMapping
simpleControllerHandlerAdapter
tomcatEmbeddedServletContainerFactory
viewControllerHandlerMappingCOPY

org.springframework.boot.autoconfigure Bean をはっきりと見ることができます。tomcatEmbeddedServletContainerFactory もあります。

次のコマンドを実行して、curl でサービスを実行します(別のターミナルウィンドウで)(出力とともに表示)。

$ curl localhost:8080
Greetings from Spring Boot!COPY

単体テストを追加する

追加したエンドポイントのテストを追加する必要があります。Spring Test はそのためのいくつかの機構を提供します。

Gradle を使用する場合は、build.gradle ファイルに次の依存関係を追加します。

testImplementation('org.springframework.boot:spring-boot-starter-test')COPY

Maven を使用する場合は、pom.xml ファイルに次を追加します。

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

次のリスト(src/test/java/com/example/springboot/HelloControllerTest.java から)が示すように、エンドポイントを介してサーブレットのリクエストとレスポンスを模倣する単純な単体テストを作成します。

package com.example.springboot;

import static org.hamcrest.Matchers.equalTo;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

import org.junit.jupiter.api.Test;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;

@SpringBootTest
@AutoConfigureMockMvc
public class HelloControllerTest {

	@Autowired
	private MockMvc mvc;

	@Test
	public void getHello() throws Exception {
		mvc.perform(MockMvcRequestBuilders.get("/").accept(MediaType.APPLICATION_JSON))
				.andExpect(status().isOk())
				.andExpect(content().string(equalTo("Greetings from Spring Boot!")));
	}
}COPY

MockMvc は Spring Test に由来し、便利なビルダークラスのセットを介して、HTTP リクエストを DispatcherServlet に送信し、結果についてアサーションを作成できます。@AutoConfigureMockMvc および @SpringBootTest を使用して MockMvc インスタンスを注入することに注意してください。@SpringBootTest を使用したため、アプリケーションコンテキスト全体を作成するように求めています。別のメソッドは、@WebMvcTest を使用してコンテキストの Web レイヤーのみを作成するように Spring Boot に依頼することです。いずれの場合も、Spring Boot はアプリケーションのメインアプリケーションクラスを自動的に見つけようとしますが、別のものを構築する場合は、それをオーバーライドするか、絞り込むことができます。

HTTP リクエストサイクルをモックするだけでなく、Spring Boot を使用して、簡単なフルスタック統合テストを作成することもできます。例: 前に示したモックテストの代わりに(または同様に)、次のテストを作成できます(src/test/java/com/example/springboot/HelloControllerIT.java から)。

package com.example.springboot;

import static org.assertj.core.api.Assertions.*;

import java.net.URL;

import org.junit.jupiter.api.BeforeEach;
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.web.client.TestRestTemplate;
import org.springframework.boot.web.server.LocalServerPort;
import org.springframework.http.ResponseEntity;

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class HelloControllerIT {

	@LocalServerPort
	private int port;

	private URL base;

	@Autowired
	private TestRestTemplate template;

    @BeforeEach
    public void setUp() throws Exception {
        this.base = new URL("http://localhost:" + port + "/");
    }

    @Test
    public void getHello() throws Exception {
        ResponseEntity<String> response = template.getForEntity(base.toString(),
                String.class);
        assertThat(response.getBody()).isEqualTo("Greetings from Spring Boot!");
    }
}COPY

webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT のため、組み込みサーバーはランダムなポートで起動し、実行時に @LocalServerPort で実際のポートが検出されます。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值