Spring框架学些(三)SpringBoot

关于SpringBoot

SpringBoot官方简介:

Spring Boot makes it easy to create stand-alone, production-grade Spring-based Applications that you can run. We take an opinionated view of the Spring platform and third-party libraries, so that you can get started with minimum fuss. Most Spring Boot applications need very little Spring configuration.

个人理解的SpringBoot做了这几件事:

  • 针对不同场景提供一些基础包(starter),其中处理了各个场景下不同包的版本依赖,简化了写pom文件
  • 提供一系列功能性的辅助包,比如国际化(Localizer/Internationization)、拦截(Interceptor/Filter)、制动(Actuator)等等
  • 最重要的:自动配置。这是SpringBoot的思想,简化配置,尽量做到零配置。并非所有组件没有配置功能,而是用约定替代认为配置,格个组件已经默认使用最常用的配置作为默认值,很多时候并不需要认为手工配置。

所以学习SpringBoot稍微会不太明白究竟学的是什么,内容比较散似乎没有核心,可能向我理解的,核心就是自动配置的思想,外加各种配置吧。

无论怎样,我是参照TutorialPoint上的教程大体了解了一边

核心的一些内容

starter

Spring官方有这样一个Starter页面(地址),在这里选择工程类型、springboot版本和初始依赖后,可以生成一个spring项目下载下来,作为项目开发的起点。

这个想法刚看到其实觉得有点不可思议,第一次看到一个框架会提供这样的功能帮助开展一个项目。不过Spring涉及的组件实在是太多,由这样的功能帮助解决依赖的确会方便不少。

基本的一个web项目内容:

	<!-- Inherit defaults from Spring Boot -->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.0.RELEASE</version>
	</parent>

	<!-- Add typical dependencies for a web application -->
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
	</dependencies>

parent模块包含了spring项目的一系列默认配置(比如再也不用手动指定java1.8版本了),而spring-boot-starter-web依赖项包含了一系列开发web项目需要的包,这里不需要指定版本,而是spring包帮忙维护了。

这些spring-boot-starter-***的依赖,就是springboot的起点,除了web,还有一些其他的依赖封装,代表不同的功能。

自动配置

主入口

不再是SpringCore的ApplicationContext,而是封装在了SpringApplication

package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        // or new SpringApplicationBuilder(Example.class).run(args);
    }

}

传入的Example.class是类似SpringCore中的@Configuration注解类,代表这个类里可以定义Bean等,不过在SpringBoot中,不再是用Configuration,而是使用@SpringBootApplication

这个注解包含了很多默认的配置,比如一个关键的从这个类开始进行component scan,扫描application.properties作为程序的property(bean中也会用到),配置默认的MessageSource读取位置等等。

推荐的项目结构

Spring推荐的项目结构:

com
 +- example
     +- myapplication
         +- Application.java
         |
         +- customer
         |   +- Customer.java
         |   +- CustomerController.java
         |   +- CustomerService.java
         |   +- CustomerRepository.java
         |
         +- order
             +- Order.java
             +- OrderController.java
             +- OrderService.java
             +- OrderRepository.java

简单来说,Spring的主入口(main函数,以及spring程序的主入口)最好也在main函数的类中,而且最好在整个项目的基础包中。

这是因为spring默认的@ComponetScan等功能,会以次类作为扫描起点扫描子包,如果配置成其他的,就需要一些额外的手动配置了。

其他功能

感觉SpringBoot核心就是这些,但是主要相关功能还是一些组件/注解的使用和配置,当然这些可能实际都不属于SpringBoot的范畴了。。

properties

bean注解中也会用到,如

@Value("${prop.field.name}")

默认springboot会读取resources目录下的application.properties文件作为配置属性,当然,属性可以被命令行传入参数替换。

ApplicationRunner/CommandLineRunner

可以配置相应的Bean,或者实现这两个接口中的一个,使Spring启动后,运行这个Bean的Run方法,如:

	@Bean
	public CommandLineRunner run(RestTemplate restTemplate) throws Exception {
		return args -> {
			log.info("Command line runner called");
			Quote quote = restTemplate.getForObject("https://gturnquist-quoters.cfapps.io/api/random", Quote.class);
			log.info(quote.toString());
		};
	}

interceptor/filter

两个功能上有点类似,都是拦截HTTP请求做处理的,类似SpringCore中的PostProcesser等,但是Filter使用更复杂一些,属于Servlet级别的。而Interceptor是Spring框架自己维护的机制。

这里注册了一个Intercepter,分别有三个接口,在请求处理前,处理后,处理完成时调用。

@Component
public class ProductInterceptor implements HandlerInterceptor {
	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		System.out.println("Pre Handle method is Calling");
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		System.out.println("Post Handle method is Calling");
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler,
			Exception exception) throws Exception {
		System.out.println("Request and Response is completed");
	}
}

Controller Advice

这个注解可以用于处理异常:

@ControllerAdvice
public class ProductExceptionController {
	@ExceptionHandler(value = ProductNotfoundException.class)
	public ResponseEntity<Object> exception(ProductNotfoundException exception) {
		return new ResponseEntity<>("Product not found", HttpStatus.NOT_FOUND);
	}
}

定义这个类,当Controller出现异常时,就会被其中的exception方法捕获,处理响应

@Service和@RestController

其实本来没什么联系,但是放到一起。

@Service用于标记MVC中的服务层。

@RestController类似MVC中的@Controller,不同的是@Controller的返回值会被进一步交给View处理,而@RestController会将结果直接返回

i18n

国际化/多语言配置,需要配置多个bean和注册interceptor:


//定义默认的Local
	@Bean
	public LocaleResolver localeResolver() {
		SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
		sessionLocaleResolver.setDefaultLocale(Locale.US);
		return sessionLocaleResolver;
	}

//处理每个请求对应的不同的locale
	@Bean
	public LocaleChangeInterceptor localeChangeInterceptor() {
		LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
		localeChangeInterceptor.setParamName("language");
		return localeChangeInterceptor;
	}

//定义国际化的资源文件,默认在resources目录下的messages.properties
//这里改为i18n目录下的messages.properties
//注意默认语言外的文件,通过下标来区分,如messages_cn.properties
	@Bean
	public MessageSource messageSource() {
		ReloadableResourceBundleMessageSource messageSource = new ReloadableResourceBundleMessageSource();
		messageSource.setBasenames("classpath:/i18n/messages");
		return messageSource;
	}

注册:

@Component
public class ProductInterceptorConfig implements WebMvcConfigurer {

	@Autowired
	LocaleChangeInterceptor localeChangeInterceptor;

	@Override
	public void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(localeChangeInterceptor);
	}
}

我看的教程,ProductInterceptorConfig是继承的WebMvcConfigurerAdapter类,不过在我的版本中,这个类已经被废弃了,可以直接实现WebMvcConfigurer接口就能起作用。

我定义的一个工具类,用于获取资源:

@Component
public class I18nUtil {
	@Autowired
	MessageSource messageSource;

	public String getMessage(String msg, Object[] args) {
		String localeMessage = "";

		try {
			localeMessage = messageSource.getMessage(msg, args, LocaleContextHolder.getLocale());
		} catch (Exception var4) {
			System.out.println("Exception[" + messageSource + "]:" + var4.getMessage());
		}

		return localeMessage;
	}
}

在Controller中就能获取对应的文字:


	@Autowired
	I18nUtil i18n;
  	@RequestMapping(value = "/hello")
	public ResponseEntity<Object> sayHello() {
		return new ResponseEntity<>(i18n.getMessage("welcome.text", null), HttpStatus.OK);
	}

如果请求中增加?language=zh,就能去查找中文

原文地址:https://www.cnblogs.com/mosakashaka/p/12609117.html

时间: 2024-11-15 10:33:54

Spring框架学些(三)SpringBoot的相关文章

Spring 框架学些(二)Spring AOP

关于AOP AOP,面向切面编程是OOP之后出现的概念(大概). 面向对象基本上就是针对类来设计代码,类中定义方法,逻辑中调用不同的类中不同的方法构成业务. 切面 而面向切面中的切面到底是什么.在业务逻辑中,我们会分很多不同的模块,也有不同的类,而这些类的一些方法中,有一些共性功能.比如认证.日志.限流等功能,在各个模块都需要,那每一个功能可以被认为是一个切面. 类似一个三明治,面包.火腿.菜叶.番茄等等每一层都是一个功能模块,一刀切下去这个切面贯穿整个三明治各层,这一刀就形成一个切面,而这个切

spring框架学习(三)junit单元测试

spring框架学习(三)junit单元测试 单元测试不是头一次听说了,但只是听说从来没有用过.一个模块怎么测试呢,是不是得专门为一单元写一个测试程序,然后将测试单元代码拿过来测试? 我是这么想的.学到spring框架这才知道单元测试原来是这么回事儿. 下面以上一篇文章中set注入的第一个实例为测试对象.进行单元测试. 1,拷贝jar包 junit-3.8.2.jar(4.x主要增加注解应用) 2,写业务类 [java] view plaincopyprint? public class Use

Spring框架笔记(三)——Spring容器、属性注入和构造器注入详解

Spring 容器 在 Spring IOC 容器读取 Bean 配置创建 Bean 实例之前, 必须对它进行实例化. 只有在容器实例化后, 才可以从 IOC 容器里获取 Bean 实例并使用. Spring 提供了两种类型的 IOC 容器实现. BeanFactory: IOC 容器的基本实现. ApplicationContext: 提供了更多的高级特性. 是 BeanFactory 的子接口. BeanFactory 是 Spring 框架的基础设施,面向 Spring 本身: Appli

Spring框架深入(三)--事务

一.事务的概念 1.事务是什么 (1).作为单个逻辑工作单元执行的一系列操作(一组SQL会成为一个事务),是并发控制的单位,要么全部成功,要么全部失败 (2).如银行转账(需要两个update)/网上商城购物 2.事务的特征 (1).原子性:所有的操作会被看成一个逻辑单元,要么全部成功,要么全部失败 (2).一致性:事务在完成时,必须使所有的数据都保持一致状态,保证数据的完整性 (3).隔离性:与并发有关,事务之间的相互影响—隔离级别 (4).持久性:事务结束后,结果是可以固化的 二.事务隔离

Spring框架学习(三) SpringMVC

SpringMVC是Spring中用于开发MVC项目的一个框架. 关于MVC Model-View-Controller,曾经以为构成了一整个应用程序,不过这篇文章里的说明,让我的看法有了一些变化,MVC可以是应用的上层,而在M层之下,还可以有类似于Repository.UnitOfWord等数据访问层与Controller层交互. SpringMVC SpringMVC做了这几件事: 定义了请求入口处理程序DispatcherServlet,并由它来分发请求到不同的Controller 定义C

Spring框架学习(三)Spring的注解开发

Spring-注解开发 1.在applicationContext.xml中添加这一句代码能够让IOC容器加载的时候去扫描对应4种注解的类: <context:component-scan base-package="com.bjsxt.tmall"></context:component-scan> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns=

spring框架学习(三)spring与junit整合测试

package cn.mf.b_test; import javax.annotation.Resource; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.test.context.ContextConfiguration; import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; impo

使用SpringBoot快速构建Spring框架应用

从SpringBoot项目名称中的 Boot 可以看出来,SpringBoot的作用在于创建和启动新的基于Spring框架的项目.它的目的是帮助开发人员很容易的创建出独立运行和产品级别的基于 Spring框架的应用.SpringBoot会选择最适合的Spring子项目和第三方开源库进行整合.大部分SpringBoot应用只需要非常少的 配置就可以快速运行起来. SpringBoot包含的特性如下: 创建可以独立运行的Spring应用. 直接嵌入 Tomcat 或 Jetty 服务器,不需要部署

Spring框架第三天

html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,abbr,acronym,address,big,cite,code,del,dfn,em,img,ins,kbd,q,s,samp,small,strike,strong,sub,sup,tt,var,b,u,i,center,dl,dt,dd,ol,ul,li,fieldset,form,label,legend,table,caption