SpringBoot基础 (一)

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 1、配置文件SpringBoot使用一个全局的配置文件,配置文件的名称是固定的application.properties语法结构:key=valueapplication.yml语法结构:key:(空格)value配置文件的作用:修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了

一、SpringBoot配置

1、配置文件

SpringBoot使用一个全局的配置文件,配置文件的名称是固定的

  • application.properties
  • 语法结构:key=value
  • application.yml
  • 语法结构:key:(空格)value

配置文件的作用:修改SpringBoot自动配置的默认值,因为SpringBoot在底层都给我们自动配置好了

# 对空格的要求非常高
name: yanheng
# 对象
student1:
  name: cyh
  age: 14
# 行内写法
student2: {name: cyh, age: 14}
# 数组
pets:
  - cat
  - dog
  - pig
pets2: [cat,dog,pig]
server.port=8081
student.name=cyh
student.age=14

2、给属性赋值的几种方式

@ConfigurationProperties

将配置文件中配置的每一个属性的值,映射到这个组件中;


告诉SpringBoot将本类中的所有属性和配置文件中相关的配置进行绑定


参数prefix=”person“:将配置文件中的person下面的所有属性一一对应


只有这个组件是容器中的组件,才能使用容器提供的@ConfigurationProperties功能


<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-configuration-processor</artifactId>
            <optional>true</optional>
</dependency>


@Repository
@ConfigurationProperties(prefix = "person")
public class Person {
    private Integer id;
    private String name;
    private String hello;
    private Dog dog;
}


person:
  id: ${random.uuid}
  name: cyh
  hello: hha
  dog:
    name: ${person.hello:hello}旺财
    age: 3

PropertySource

@PropertySource(value = "classpath:application.properties")
public class Dog {
    @Value("${name}")
    private String name;
    private Integer age;
}


name=cccc

引入environment

@Resource
private Environment env;
@RequestMapping("/hello")
public String hello(){
    String property = env.getProperty("server.port");
    System.out.println(property);
    return "index";
}

对比


  • @ConfigurationPropertie只需要写一次即可,value则需要每一个字段都添加
  • yaml支持松散绑定
  • yaml里last-name和java里的lastName可以绑定
  • yaml支持JSR303数据校验
  • 可以在字段增加一层过滤器验证,保证数据的合法性
  • yaml支持复杂类型封装,可以封装对象


@Repository
@ConfigurationProperties(prefix = "person")
@Validated//JSR303数据校验
public class Person {
    private String id;
    @Email(message = "邮箱错了!!")//数据不合法则控制台提示邮箱错了
    private String name;
    private String hello;
    private Dog dog;

3、多环境配置及配置文件位置

优先级

properties>yaml


  1. 项目路径下的config文件夹配置文件
  2. 项目路径下的配置文件
  3. 资源路径下的config文件夹配置文件
  4. 资源路径下的配置文件

打成jar包之后不会包含项目根路径的config文件夹(不属于springboot的基本项目结构),故使用jar包运行时项目根路径下的config中的配置会失效

多环境配置



默认执行application.properties


  1. profile用来完成不同环境下,配置动态切换功能的
  2. profile配置方式
  • 多profile文件方式:提供多个配置文件,每一个代表一种环境
  • application-dev.properties/yaml开发环境
  • application-pro.properties/yaml生产环境
  • application-test.properties/yaml测试环境


  • yaml多文档方式
  • 在yaml中使用—分隔不同配置
  • 通过spring.config.activate.on-profile:pro/dev/test区分各个分区

3.profile的激活方式

  • 配置文件:在配置文件(application.properties或yaml中的独立分区)中配置:spring.profiles.active=dev
  • 虚拟机参数:在VM options指定:-Dspring.profiles.active=dev
  • 命令行参数:java-jar xxx.jar --spring.profiles.active=dev

使用外部配置文件

  • 在命令行参数:java-jar xxx.jar --spring.config.location=e://application.properties
  • 配置文件放在和jar包同级的目录,运行jar包时配置文件会被自动读取
  • 配置文件放在和jar包同级的config文件夹下,运行jar包时配置文件会被自动读取,优先级大于上者



4、整合其他框架

1)整合Junit
  1. 搭建SpringBoot工程
  2. 引入starter-test起步依赖
  3. 编写测试类


4.添加测试相关注解

  • @RunWith(SpringRunner.class)
  • @SpringBootTest(classes=启动类.class)

5.编写测试方法

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


@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootApplication.class)
public class UserServiceTest {
    @Autowired
    private UserService userService;
   @Test
    public void testAdd(){
        userService.add();
    }
}


@SpringBootTest中的classes参数为springboot启动类的字节码文件


如果该Test文件所在的包和springboot启动类所在包一致或为其子包(都为cn.ken),则可以省略该参数



2)整合redis

实现步骤:


  1. 搭建SpringBoot工程
  2. 引入redis起步依赖
  3. 配置redis相关属性(默认本机6379端口)
  4. 注入RedisTemplate模板
  5. 编写测试方法,测试


@SpringBootTest
class SpringbootRedisApplicationTests {
    @Autowired
    private RedisTemplate redisTemplate;
    @Test
    void testSet() {
        redisTemplate.boundValueOps("name").set("cyh");
    }
    @Test
    void testGet() {
        Object name = redisTemplate.boundValueOps("name").get();
        System.out.println(name);
    }
}



需先运行redis-server.exe

3)整合MyBatis
  1. 搭建SpringBoot工程
  2. 引入MyBatis起步依赖,添加mysql驱动
  3. 编写DataSource和MyBatis相关配置
  4. 定义表和实体类
  5. 编写dao和mapper文件/纯注解开发
  6. 测试


spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?serverTimeZone=UTC
    username: root
    password: 129496
mybatis:
  #config-location: #指定mybatis的核心配置文件
  mapper-locations: classpath:mapper/*Mapper.xml #mapper映射文件地址
  type-aliases-package: cn.ken.springbootmybatis.domain


// 注解方式(也不需要上面yaml的配置)
@Mapper
public interface UserMapper {
    @Select("select * from user")
    List<User> findAll();
}


// 配置文件方式
@Mapper
public interface UserXmlMapper {
    List<User> findAll();
}


<?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="cn.ken.springbootmybatis.mapper.UserXmlMapper">
    <select id="findAll" resultType="user">
        select * from user;
    </select>
</mapper>


// 测试
@SpringBootTest
class SpringbootMybatisApplicationTests {
    @Resource
    private UserMapper userMapper;
    @Resource
    private UserXmlMapper userXmlMapper;
    @Test
    public void testUserMapper(){
        System.out.println(userMapper.findAll());
    }
    @Test
    public void testUserMapper2(){
        System.out.println(userXmlMapper.findAll());
    }
}



二、SpringBoot自动配置

1、condition

Condition是在Spring4.0增加的条件判断功能,通过这个功能可以实现选择性创建Bean的操作


public class ClassCondition implements Condition {
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        boolean flag = true;
        try {
            Class<?> aClass = Class.forName("redis.clients.jedis.Jedis");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            flag = false;
        }
        return flag;
    }
}


如果已经导入了Jedis坐标,则返回true,否则返回false


@Configuration
public class UserConfig {
    @Bean
    @Conditional(ClassCondition.class)
    public User user(){
        return new User();
    }
}

参数是一个实现了Condition接口的类,只有参数ClassCondition中的matches方法返回true时才创建

@Bean返回的bean的id为函数名

@SpringBootApplication
public class SpringbootMybatisApplication {
   public static void main(String[] args) {
        ConfigurableApplicationContext run = SpringApplication.run(SpringbootMybatisApplication.class, args);
        Object user = run.getBean("user");
        System.out.println(user);
    }
}


@ConditionalOnClass等注解则是在@Conditional注解外面再包一层,传入需要的类的字节码文件,而在Conditional注解的OnClassCondition类上通过反射(该类实现matches方法,其中有两个参数context和metadata,metadata就可以通过反射获取到注解的属性)获取这些需要的字节码文件,来判断是否满足创建bean的需求,实现动态判断。


SpringBoot提供的常用条件注解:


  1. ConditionalOnProperty(name=“x”, havingValue=“xx”):判断配置文件中是否有对应属性和值才初始化Bean
  2. ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
  3. ConditionalOnMissingBean:判断环境中没有对应的Bean才初始化Bean

2、切换内置Web服务器

<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>


排除内置tomcat,引入jetty依赖


3、Enable*注解

SpringBoot提供了很多Enable开头的注解,这些注解都是用于动态开启某些功能的,而其底层原理是使用@Import注解导入一些类配置类,实现Bean的动态加载。


@SpringBootApplication注解中包含的@ComponentScan的扫描范围为当前类所在包及其子包,故导入其他依赖中的bean无法直接使用,因为对应的bean所在的包不是当前包所在包的子包。


为了解决这个问题可以采取:


  1. 增加@Component扫描对应bean的包
  2. 使用@Import注解加载对应的类,这些类都会被Spring创建并放入IOC容器
  3. 定义@Enable*注解对@Import注解进行封装


@Import


@Enable*底层依赖于@Import注解导入一些类,使用@Import导入的类会被Spring加载到IOC容器中,@Import提供了四种用法:


导入Bean

导入配置类(配置类里注册的Bean也会被导入)

导入ImportSelector实现类,一般用于加载配置文件中的配置类

导入ImportBeanDefinitionRegistrar实现类


EnableAutoConfiguration注解


@EnableAutoConfiguration注解内部使用@Import(AutoConfigurationImportSelector.class)来加载配置类(selectImports方法返回要加载的类的字符串数组)


配置文件位置:META/spring.properties(SpringFactoriesLoader类去加载),该配置文件中定义了大量的配置类,当SpringBoot应用启动时,会自动加载这些配置类,初始化Bean


并不是所有的Bean都会被初始化,在配置类中使用Condition来加载满足的Bean


4、自动装配原理

SpringBoot启动会加载大量的自动配置类,自动装配类中配置了一些组件,配置时从properties类中获取属性,我们只需要在配置文件中指定这些属性的值即可。


xxxAutoConfiguration:自动装配类


xxxProperties:封装配置文件中相关属性


可以通过debug=true查看哪些配置类生效,哪些没有生效


@Configuration(
    proxyBeanMethods = false
)
@ConditionalOnClass({MongoClient.class, MongoTemplate.class})
@EnableConfigurationProperties({MongoProperties.class})
@Import({MongoDataConfiguration.class, MongoDatabaseFactoryConfiguration.class, MongoDatabaseFactoryDependentConfiguration.class})
@AutoConfigureAfter({MongoAutoConfiguration.class})
public class MongoDataAutoConfiguration {
    public MongoDataAutoConfiguration() {
    }
}


@Configuration:配置类


@ConditionalOnClass:满足具有后面类地条件才生效(即导入了该依赖)


@EnableConfigurationProperties({MongoProperties.class}):封装配置文件


@Import:导入其他配置类


SpringBoot基础(二)+https://developer.aliyun.com/article/1390593?spm=a2c6h.13148508.setting.15.7e0d4f0e107vfb

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
2月前
|
XML JSON Java
SpringBoot基础
SpringBoot基础
28 4
|
5月前
|
XML JSON Java
SpringBoot(四)之基础配置
application.yml为主配置文件,如果要分环境,则需要创建 application-{profile}.yml的环境配置。
38 0
|
6月前
|
监控 JavaScript Java
SpringBoot基础(二)
SpringBoot的监听机制其实是对Java提供的事件监听机制的封装 Java的事件监听机制中定义了以下几个角色: 事件(Event):继承Java.util.EventObject类的对象 事件源(Source):任意对象Object 监听器(Listener):实现java.util.EventListener接口的对象
|
运维 监控 前端开发
springboot基础
springboot基础
53 0
|
Java
学习Springboot框架一 之最简单的Springboot项目
学习Springboot框架一 之最简单的Springboot项目
70 0
|
XML Java 关系型数据库
SpringBoot 开发总结思考(一)
从面向对象的角度理解XML,是以类和对象作为XML的配置SpringBoot 使用的是配置类加上普通/常规配置的形式,参数不是直接固定在配置类中,而可以写在配置文件中,例如application.properties
137 0
SpringBoot 开发总结思考(一)
|
XML NoSQL Java
SpringBoot 开发总结思考(二)
模块装配:假设要注入MongoDB,那么就加上@Configuration注解,有可能一个配置类没办法解决某个方向的问题,往往是很多@Configuration的类组合在一起SpringBoot是使用Enable注解,然后再通过@import导入Selector,通过Selector读取 .factories 文件,最终加载的Configuration
164 0
SpringBoot 开发总结思考(二)
|
SQL 存储 Java
SpringBoot基础学习文章
SpringBoot基础学习文章
191 0
SpringBoot基础学习文章
|
Java 应用服务中间件 Maven
《SpringBoot篇》01.Springboot超详细入门(基础篇)(一)
《SpringBoot篇》01.Springboot超详细入门(基础篇)(一)
231 0
《SpringBoot篇》01.Springboot超详细入门(基础篇)(一)
|
druid Java 关系型数据库
《SpringBoot篇》01.Springboot超详细入门(基础篇)(三)
《SpringBoot篇》01.Springboot超详细入门(基础篇)(三)
495 0
《SpringBoot篇》01.Springboot超详细入门(基础篇)(三)