SpringBoot快速入门

1、SpringBoot的hello,world

  • 使用IDEA创建项目

在这里插入图片描述

在这里插入图片描述

  • 添加web依赖

在这里插入图片描述

等待maven下载依赖
在这里插入图片描述

  • 启动类同级目录下建相应的包,在controller包下创建HelloController.java并添加如下代码
package com.toolate.comtroller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@RequestMapping("/hello")
public class HelloController {
    @RequestMapping("/hello")
    @ResponseBody
    public String hello(){
        return "hello,world";
    }
}
  • 启动项目,访问http://localhost:8080/hello/hello

2、原理初探

2.1、自动装配:

  • 1、pom.xml
    • Spring-boot-dependencies:核心依赖在父工程中
    • 我们在写或者引入Springboot依赖的时候,不需要指定版本是因为有这些版本仓库
  • 2、启动器
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
  • Springboot会将所有的功能场景都变成一个个的启动器

    • 比如spring-boot-starter-web帮我们自动导入web环境所有的依赖
    • 我们要使用什么功能,就只需要找到对应的启动器就可以了
  • 3、主程序

package com.toolate;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Springboot01HelloworldApplication {
    public static void main(String[] args) {
        SpringApplication.run(Springboot01HelloworldApplication.class, args);
    }
}
  • 4、注解:
@SpringBootApplication
	@SpringBootConfiguration:springboot的配置
		@Configuration:spring配置类
		@Component:说明这也是Spring的组件
	@EnableAutoConfiguration:自动配置,自动导入包
		@AutoConfigurationPackage:自动配置包
			@Import(AutoConfigurationPackages.Registrar.class):自动注册“包注册”
		@Import(AutoConfigurationImportSelector.class):自动配置导入选择
			@getAutoConfigurationEntry:或者自动配置的实体
			//获取所有的配置
			List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
			@ComponentScan:扫描当前主启动类同级的包
			@ConditionOnXXX:如果这里面的条件都满足,才会生效
			

获取候选的配置

protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
   List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(),
         getBeanClassLoader());
   Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you "
         + "are using a custom packaging, make sure that file is correct.");
   return configurations;
}

在这里插入图片描述

//所有的资源加载到配置类中
Properties properties = PropertiesLoaderUtils.loadProperties(resource);

结论:springboot所有的自动配置都是在启动的时候自动扫描并加载,所有的自动配置类都在spring.factories 里,但是不一定生效,要判断条件是否成立,只要导入了对应的start,就有对应的启动器,有了启动器,我们自动装配就生效,然后就配置成功

  1. springboot在启动的时候,从类路径下META-INF/spring.factories 获取指定的值
  2. 将自动配置的类导入容器,自动配置类就会生效,帮我们进行自动配置
  3. 以前我们需要自动配置的东西,现在springboot帮我们做了
  4. 整个JavaEE,解决方案和自动配置的都在spring-boot-cutoconfigure-2.4.2.RELEASE.jar下
  5. 它会把所有需要导入的组件,以类名的方式(全限定名)返回,这些组件就会被添加到容器
  6. 容器中也会存在非常多的xxxAutoConfiguration的文件(@Bean),就是这些类给容器中导入了这个场景需要的所有组件,并自动配置@Configuration、JavaConfig
  7. 有了自动配置类,免去了我们手动编写配置文件的工作
  • 关于Springboot,谈谈你的理解:
    • 自动装配
    • run();
      • 判断应用类型是普通项目还是web项目
      • 推断并设置main方法的定义类,找到运行的主类
      • 监听器:获取上下文,处理Bean

3、SpringBoot配置

3.1、配置文件

名称是固定的:修改SpringBoot自动配置的默认值

  • application.properties:key=value,只能保存键值对
  • application.yaml:key:空格value,对空格的要求十分高,可以注入到配置类中

3.2、 yaml语法:

# key-value
name: toolate

# 对象
student:
  name: toolate
  age: 20
  
# 行内写法
student: {name: toolate,age: 20}

# 数组
pets:
  - cat
  - dog

pets: [cat,dog]

3.3、yaml配置文件

  • Person.java
@Component
@ConfigurationProperties(prefix = "person")//与yaml中的配置
@Data
public class Person {
        private String name;
        private Integer age;
        private boolean happy;
        private Date birth;
        private Map<String,Object> maps;
        private List<Object> lists;
        private Dog dog;
}

@ConfigurationProperties(prefix = “person”)//与yaml中的配置

  • Dog.java
@Component
@Data
public class Dog {
    private String name;
    private Integer age;
}
  • application.yaml
person:
  name: toolate
  age: 1
  happy: true
  birth: 2021/1/17
  maps: {k1: v1,k2: v2}
  lists: [code,music,game]
  dog:
    name: 旺财
    age: 3
  • pom.xml
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-configuration-processor</artifactId>
    <optional>true</optional>
</dependency>

这个依赖是为了解决爆红问题

  • 测试代码
    @Autowired
    private Person person;
    @Test
    void contextLoads() {
        System.out.println(person);
    }
person:
  name: toolate${random.uuid}
  age: ${random.int}
  happy: true
  maps: {k1: v1,k2: v2}
  lists: [code,music,movie]
  hello: happy
  dog:
    name: ${person.hello:hello}_旺财
    age: 3
  • ${person.hello:hello}:person.hello值存在取自己的值,不存的话取hello
  • #{random.xxx}:取随机值

3.4、properties配置文件

@Component
//加载指定的配置文件
@PropertySource(value = "classpath:toolate.properties")
public class Person {
    //spel表达式取出配置文件的值
    @Value("${name}")//需要一个一个内容读取
    private String name;
    private Integer age;
    private boolean happy;
    private Data birth;
    private Map<String,Object> maps;
    private List<Object> lists;
    private Dog dog; 
}
  • 新建一个application.properties在里面赋值,并通过@PropertySource(value = “classpath:application.properties”)来加载指定的配置文件
  • 使用@Value("${name}")需要一个一个内容读取
@ConfigurationProperties@Value
功能批量注入配置文件中的属性一个个指定
松散绑定(松散语法)支持不支持
SpEL不支持支持
JSR303数据检验支持不支持
复杂类型封装支持不支持

结论:

  • 配置文件yml还是properties他们都能获取到值;
  • 如果说,我们只是在某个业务逻辑中需要获取一下配置文件中的某项值,使用@Value;
  • 如果说,我们专门编写了一个JavaBean来和配置文件进行映射,我们就直接使用@ConfigurationProperties;

3.5、松散绑定:yml中的last-name和类中的lastName是一样的,即用-来将小写转换为大写

3.6、JSR303数据校验 :

可以在字段是增加一层过滤器验证 , 可以保证数据的合法性

空检查

  • @Null 验证对象是否为null
  • @NotNull 验证对象是否不为null, 无法查检长度为0的字符串
  • @NotBlank 检查约束字符串是不是Null还有被Trim的长度是否大于0,只对字符串,且会去掉前后空格.
  • @NotEmpty 检查约束元素是否为NULL或者是EMPTY.

Booelan检查

  • @AssertTrue 验证 Boolean 对象是否为 true
  • @AssertFalse 验证 Boolean 对象是否为 false

长度检查

  • @Size(min=, max=) 验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
  • @Length(min=, max=) Validates that the annotated string is between min and max included.

日期检查

  • @Past 验证 Date 和 Calendar 对象是否在当前时间之前
  • @Future 验证 Date 和 Calendar 对象是否在当前时间之后
  • @Pattern 验证 String 对象是否符合正则表达式的规则

数值检查,建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null

  • @Min 验证 Number 和 String 对象是否大等于指定的值
  • @Max 验证 Number 和 String 对象是否小等于指定的值
  • @DecimalMax 被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
  • @DecimalMin 被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
  • @Digits 验证 Number 和 String 的构成是否合法
  • @Digits(integer=,fraction=) 验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
  • @Range(min=, max=) 检查数字是否介于min和max之间.
  • @Range(min=10000,max=50000,message=“range.bean.wage”)
    private BigDecimal wage;
  • @Valid 递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
  • @CreditCardNumber信用卡验证
  • @Email 验证是否是邮件地址,如果为null,不进行验证,算通过验证。
  • @ScriptAssert(lang= ,script=, alias=)
  • @URL(protocol=,host=, port=,regexp=, flags=)

3.7、多配置文件

我们在主配置文件编写的时候,文件名可以是 application-{profile}.yaml
在这里插入图片描述

  • application-dev.yaml
server:
  port: 8081
  • application-test.yaml
server:
  port: 8082
  • application.yaml
spring:
  profiles:
    active: test

在application.yaml中可以选择一个配置文件,spring.profiles.active中填写的值为配置文件application-后面的值

在我们这配置文件中配置的东西,都存在一个固有的规律

  • xxxAutoConfiguration:默认值 xxxProperties和配置文件绑定,我们就可以使用自定义的配置类
    每一个这样的 xxxAutoConfiguration类都是容器中的一个组件,都加入到容器中;用他们来做自动配置

3.8、再探自动装配原理

在这里插入图片描述
HttpEncodingAutoConfiguration 为例

@Configuration(proxyBeanMethods = false)
@EnableConfigurationProperties(ServerProperties.class)
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)
@ConditionalOnClass(CharacterEncodingFilter.class)
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)
public class HttpEncodingAutoConfiguration {

	private final Encoding properties;

	public HttpEncodingAutoConfiguration(ServerProperties properties) {
		this.properties = properties.getServlet().getEncoding();
	}
	@Bean
	@ConditionalOnMissingBean
	public CharacterEncodingFilter characterEncodingFilter() {
		CharacterEncodingFilter filter = new OrderedCharacterEncodingFilter();
		filter.setEncoding(this.properties.getCharset().name());
		filter.setForceRequestEncoding(this.properties.shouldForce(Encoding.Type.REQUEST));
		filter.setForceResponseEncoding(this.properties.shouldForce(Encoding.Type.RESPONSE));
		return filter;
	}

	@Bean
	public LocaleCharsetMappingsCustomizer localeCharsetMappingsCustomizer() {
		return new LocaleCharsetMappingsCustomizer(this.properties);
	}

	static class LocaleCharsetMappingsCustomizer
			implements WebServerFactoryCustomizer<ConfigurableServletWebServerFactory>, Ordered {

		private final Encoding properties;
		LocaleCharsetMappingsCustomizer(Encoding properties) {
			this.properties = properties;
		}
		@Override
		public void customize(ConfigurableServletWebServerFactory factory) {
			if (this.properties.getMapping() != null) {
		factory.setLocaleCharsetMappings(this.properties.getMapping());
			}
		}
		@Override
		public int getOrder() {
			return 0;
		}
	}
}
//表示这是一个配置类
@Configuration(proxyBeanMethods = false)
//自动配置属性,指定配置哪个类 eg:ServerProperties.class
@EnableConfigurationProperties(ServerProperties.class)
//Spring的底层注解,根据不同的条件,来判断当前配置或者类是否生效
@ConditionalOnWebApplication(type = ConditionalOnWebApplication.Type.SERVLET)//判断当前应用是否是web应用,如果是,当前配置类生效
@ConditionalOnClass(CharacterEncodingFilter.class)
//判断当前项目有没有这个类CharacterEncodingFilter;SpringMVC中进行乱码解决的过滤器
@ConditionalOnProperty(prefix = "server.servlet.encoding", value = "enabled", matchIfMissing = true)//判断配置文件中是否存在某个配置  spring.http.encoding.enabled;如果不存在,判断也是成立的;即使我们配置文件中不配置spring.http.encoding.enabled=true,也是默认生效的;

@conditionalOnXXXX是通过一些条件来判断是否加载这个类

总结:

  • SpringBoot启动会加载大量的自动配置类
  • 我们看我们需要的功能有没有SpringBoot默认写好的自动配置类
  • 我们再来看这个自动配置类中到底配置了哪些组件(只要我们要用的组件有,我们就不需要再来配置了)
  • 给容器中自动配置类添加组件的时候,会从properties类中获取某些属性,我们就可以在配置文件中指定这些属性的值;

xxxxAutoConfigurartion:自动配置类,给容器中添加组件

xxxxProperties:封装配置文件中相关属性,springboot配置修改这些属性

4、SpringBoot Web开发

4.1、静态资源导入问题

@Override
		public void addResourceHandlers(ResourceHandlerRegistry registry) {
      //如果自定义一个目录:如:spring.mvc.static-pattern=/hello/,class path:/hxh/,源码会失效
			if (!this.resourceProperties.isAddMappings()) {
				logger.debug("Default resource handling disabled");
				return;
			}
			Duration cachePeriod = this.resourceProperties.getCache().getPeriod();
			CacheControl cacheControl = this.resourceProperties.getCache().getCachecontrol().toHttpCacheControl();
			if (!registry.hasMappingForPattern("/webjars/**")) {
				customizeResourceHandlerRegistration(registry.addResourceHandler("/webjars/**")
						.addResourceLocations("classpath:/META-INF/resources/webjars/")
						.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
			}
			String staticPathPattern = this.mvcProperties.getStaticPathPattern();
			if (!registry.hasMappingForPattern(staticPathPattern)) {
				customizeResourceHandlerRegistration(registry.addResourceHandler(staticPathPattern)
						.addResourceLocations(getResourceLocations(this.resourceProperties.getStaticLocations()))
						.setCachePeriod(getSeconds(cachePeriod)).setCacheControl(cacheControl));
			}
		}

在SpringBoot中,我们可以使用以下的方式处理静态资源

  • webjars:localhost:8080/webjars/
  • resources包下新建package:resources>static>public(优先级) localhost:8080/

4.2、模版引擎-Thymeleaf

  • 导入thymeleaf的依赖
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
  • 在要显示的html页面加入thymeleaf的相关命名空间
<html lang="en" xmlns:th="http://www.thymeleaf.org">
  • 编写相关的controller
@Controller
public class IndexController {

    @RequestMapping("/test")
    public String index(Model model){
        model.addAttribute("msg","Hello,Thymeleaf");
        return "test";
    }
}
  • 在显示的html中取出相应的值
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<!--所有的html元素都可以被thymeleaf替换接管,th:元素名-->
<h1 th:text="${msg}"></h1>
</body>
</html>
  • 访问接口
    在这里插入图片描述

4.3、Thymeleaf语法

  • ${…}:获取变量值
  • *{…}:选择表达式
  • #{…}:获取国际化内容
  • @{…}:定义URL
  • ~{…}:片段引用表达式
  • Literals(字面量)
    Text literals: ‘one text’ , ‘Another one!’ ,…
    Number literals: 0 , 34 , 3.0 , 12.3 ,…
    Boolean literals: true , false
    Null literal: null
    Literal tokens: one , sometext , main ,…
  • Text operations:(文本操作)
    String concatenation: +
    Literal substitutions: |The name is ${name}|
  • Arithmetic operations:(数学运算)
    Binary operators: + , - , * , / , %
    Minus sign (unary operator): -
  • Boolean operations:(布尔运算)
    Binary operators: and , or
    Boolean negation (unary operator): ! , not
  • Comparisons and equality:(比较运算)
    Comparators: > , < , >= , <= ( gt , lt , ge , le )
    Equality operators: == , != ( eq , ne )
  • Conditional operators:条件运算(三元运算符)
    If-then: (if) ? (then)
    If-then-else: (if) ? (then) : (else)
    Default: (value) ?: (defaultvalue)
  • Special tokens:
    No-Operation: _ //分割表达式
@Controller
public class IndexController {

    @RequestMapping("/test")
    public String index(Model model){
        model.addAttribute("users", Arrays.asList("张三","李四","王五"));
        return "test";
    }
}
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h3 th:each="user:${users}" th:text="${user}"></h3>
</body>
</html>

4.4、SpringMVC

  • 扩展试图解析器

编写一个配置类@Configuration继承WebMvcConfigurer

不要标注@EnableWebMvc

//拓展SpringMVC
@Configuration
public class MyMVCConfig implements WebMvcConfigurer {
    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/toolate").setViewName("test");
    }
}

在这里插入图片描述
实现了页面跳转

5、 Druid

配置mysql相关参数,切换数据源为Druid

spring:
  datasource:
    username: "root"
    password: "123456"
    url: jdbc:mysql://localhost:3306/mybatis?userUnicode=true&chctacterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
  • 编写配置类DruidConfig
@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druidDataSource(){
        return new DruidDataSource();
    }

    //后台监控
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(),"/druid/*");
        HashMap<String, String> initParameters = new HashMap<>();
        initParameters.put("loginUsername","admin");
        initParameters.put("loginPassword","123456");
        //允许访问
        initParameters.put("allow","");
        bean.setInitParameters(initParameters);
        return bean;
    }

    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        HashMap<String, String> initParameters = new HashMap<>();
        //这些不进行统计
        initParameters.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParameters);
        return bean;
    }
}

访问 http://localhost:8080/druid
在这里插入图片描述
填上在配置类中配置好的用户名和密码
在这里插入图片描述
自带的数据监控功能,非常强大
在这里插入图片描述

6、整合Mybatis

6.1、创建实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String pwd;
}

6.2、编写UserMapper

@Mapper
@Repository
public interface UserMapper {

    List<User> queryUserList();

    User queryUserById(int id);

    int addUser(User user);

    int updateUser(User user);

    int deleteUser(int id);
}

注意:在SpringBoot中Mapper类加上一个@Mapper的注解就能把这个接口给Spring容器管理,不再需要写对应的实现类

6.3、UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.toolate.mapper.UserMapper">

    <select id="queryUserList" resultType="User">
        select * from mybatis.user;
    </select>

    <select id="queryUserById" resultType="User" parameterType="int">
        select * from mybatis.user where id = #{id};
    </select>

    <insert id="addUser" parameterType="User">
        insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd})
    </insert>

    <update id="updateUser" parameterType="User">
        update user set name = #{name},pwd=#{pwd}, where id = #{id}
    </update>

    <delete id="deleteUser" parameterType="int">
        delete from user where id = #{id}
    </delete>
</mapper>

6.4、配置文件

spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/mybatis?useUnicode=true&useSSL=false&characterEncoding=utf-8
    driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
  type-aliases-package: com.toolate.pojo
  mapper-locations: classpath:mybatis/mapper/*.xml

6.5、UserController

@RestController
public class UserController {
    @Autowired
    private UserMapper userMapper;

    @GetMapping("/queryUserList")
    public List<User> queryUserList(){
        List<User> userList = userMapper.queryUserList();
        return userList;
    }

    @GetMapping("/queryUserById/{id}")
    public User queryUserById(@PathVariable("id")int id){
        User user = userMapper.queryUserById(id);
        return user;
    }
}

6.6、测试

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值