SpringBoot 复习

简介

Spring Boot 是由 Pivotal 团队提供的全新框架,其设计目的是用来简化新 Spring 应用的初始搭 建以及开发过程。该框架使用了特定的方式来进行配置,从而使开发人员不再需要定义样板化的 配置。通过这种方式,Spring Boot 致力于在蓬勃发展的快速应用开发领域(rapid application development)成为领导者。其特点如下:

  1. 创建独立的Spring应用程序
  2. 嵌入的Tomcat,无需部署war文件
  3. 简化Maven配置
  4. 自动配置Spring
  5. 提供生产就绪型功能,如指标、健康检查和外部配置
  6. 没有代码生成和不要求配置xml

环境搭建

  1. 创建maven工程(不用骨架,打包方式jar)

  2. 添加起步依赖

    继承SpringBoot的起步依赖

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.1.RELEASE</version>
    </parent>

    导入web的启动依赖

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>
  3. 编写引导类(任意命名)

    @SpringBootApplication
    public class NewSpringBootApplication{
        public static void main(String[] args){
            SpringApplication.run(NewMySpringBootApplication.class);
        }
    }
  4. 编写Controller

    @Controller
    public class HelloController{
        @RequestMapping("/hello")
        @ResponseBody           //说明返回的是json字符串
        public String hello(){
            return "hello springboot";
        }
    }

注意事项

  1. 所有的SpringBoot项目必须继承SpringBoot的起步依赖

  2. 添加依赖时以功能为单位

  3. @SpringBootApplication 声明该类是一个SpringBoot引导类

  4. SpringApplication.run(引导类.class) 表示运行SpringBoot的引导类(引导类和main方法可以分开)

  5. SpringBoot工程的热部署,更改代码后不需要重启项目即可生效

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
    </dependency>

    导入坐标后设置IDEA自动编译:

    • Settings --> Compiler --> select Build project automatically --> apply

    • press control+shift+/ --> Registry --> select compiler.automake.allow.when.app.running

  6. IDEA快速创建SpringBoot项目

    new project --> Spring Initializr --> select dependencies --> [delete .gitignore & mvnw & mvnw.cmd] --> create Controller

  7. @RestController = @Controller + @ResponseBody

原理分析

起步依赖

  • parent:当前项目 --> 继承spring-boot-starter-parent(处理配置文件,插件管理) --> 继承spring-boot-dependencies(maven 版本约定,依赖管理)

  • web:spring-boot-starter-web-2.0.1.RELEASE.pom中导入了tomcat,json等坐标

自动配置

  • @SpringBootApplication

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @SpringBootConfiguration        //配置类
    @EnableAutoConfiguration        //允许自动配置
    @ComponentScan(                 //自动扫描组件,约定引导类所在的包及子包所有的类都会扫描
        excludeFilters = {@Filter(
        type = FilterType.CUSTOM,
        classes = {TypeExcludeFilter.class}
    ), @Filter(
        type = FilterType.CUSTOM,
        classes = {AutoConfigurationExcludeFilter.class}
    )}
    )
    public @interface SpringBootApplication {...}
  • @SpringBootConfiguration

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Configuration  //spring的配置类注解
    public @interface SpringBootConfiguration {...}
  • @EnableAutoConfiguration

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @AutoConfigurationPackage
    @Import({AutoConfigurationImportSelector.class})    //当前配置类引入其他配置类
    public @interface EnableAutoConfiguration {...}
  • AutoConfiturationImportSelector.class

        public String[] selectImports(AnnotationMetadata annotationMetadata) {
            if (!this.isEnabled(annotationMetadata)) {
                return NO_IMPORTS;
            } else {
                AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
                //调用getAutoConfigurationEntry()
                AutoConfigurationImportSelector.AutoConfigurationEntry autoConfigurationEntry = this.getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
                return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
            }
        }
    
        protected AutoConfigurationImportSelector.AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) {
            if (!this.isEnabled(annotationMetadata)) {
                return EMPTY_ENTRY;
            } else {
                AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
                //调用getCandidateConfigurations(),返回配置类的全包名
                List<String> configurations = this.getCandidateConfigurations(annotationMetadata, attributes);
                configurations = this.removeDuplicates(configurations);
                Set<String> exclusions = this.getExclusions(annotationMetadata, attributes);
                this.checkExcludedClasses(configurations, exclusions);
                configurations.removeAll(exclusions);
                configurations = this.filter(configurations, autoConfigurationMetadata);
                this.fireAutoConfigurationImportEvents(configurations, exclusions);
                return new AutoConfigurationImportSelector.AutoConfigurationEntry(configurations, exclusions);
            }
        }
    
        protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
            List<String> configurations = SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
            //错误信息说明了配置类的信息存在spring.factories中
            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;
        }
  • org.springframework.boot:spring-boot-autoconfigure:2.2.2.RELEASE/spring-boot-autoconfigure-2.2.2.RELEASE.jar/META-INF/spring.factories

    ...
    # Auto Configure
    org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    org.springframework.boot.autoconfigure.admin.SpringApplicationAdminJmxAutoConfiguration,\
    org.springframework.boot.autoconfigure.aop.AopAutoConfiguration,\
    org.springframework.boot.autoconfigure.amqp.RabbitAutoConfiguration,\
    ...
  • 流程

    1. 通过配置文件提前进行默认配置
    2. 用ServerProperties类加载配置
    3. 用XxxAutoConfiguration类引入
    4. 用spring.factories存入多个AutoConfiguration全限定类名
    5. AutoConfigurationImportSelector类加载spring.factories获取配置信息
    6. @EnableAutoConfiguration引入AutoConfigurationImportSelector完成自动配置
  • 覆盖配置

    spring-boot-starter-parent-2.0.1.RELEASE.pom中include标签有application*.yml(.yaml/.properties),可以通过自定义对应配置文件进行覆盖

配置文件

  • 位置:resources目录下

  • 顺序:多个配置文件时,yml > yaml > properties,后加载的会覆盖之前的

  • yml语法

    # 普通数据
    name: whteway
    # 对象(常用)
    user:
        username: root
        password: 1234
    # 行内对象配置
    user: {username: root,password: 1234}
    
  • 读取配置信息

    @Value 精确,繁琐

    @Value("${name}")
    private String name;
    @Value("${user.username}")
    private String username;

    @ConfigurationProperties 自动封装,需要配置configuration processor

    @Controller
    @ConfigurationProperties(prefix="user")
    public class LoginController{
        private String username;
        private String password;
        //generate getters and setters
    }
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>

集成Mybatis

  1. 添加起步依赖

    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.1.1</version>
    </dependency>
  2. 添加数据库驱动坐标

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
  3. 添加数据库连接信息,application.yml

    spring:
        datasource:
            driverClassName=com.mysql.jdbc.Driver
            url=jdbc:mysql://localhost:3306/dbName?useUnicode=true?characterEncoding=utf8
            username=root
            password=root
  4. 建库建表

  5. 配置映射关系

    UserMapper.xml

  6. SpringBoot的配置文件中配置Mybatis的信息

    mybatis:
        type-aliases-package=com.whteway.entity
        mapper-locations=classpath:mapper/*Mapper.xml

集成Junit

  1. 添加起步依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
  2. 编写测试类

    @RunWith(SpringRunner.class)
    @SpringBootTes(classes="引导类全包名")
    public class Test{
        @Test
        public void test(){...}
    }

集成SpringDataJPA

  1. 添加起步依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
  2. 添加数据库驱动坐标

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
  3. 添加数据库连接信息,application.yml

    spring:
        datasource:
            driverClassName=com.mysql.jdbc.Driver
            url=jdbc:mysql://localhost:3306/dbName
            username=root
            password=root
  4. 建库建表

  5. 建实体类

    @Entity
    public class User{
        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Long id;
        private String username;
        ...
    }
  6. 建接口

    public interface UserRepository extends JpaRepository<User, Long>{
        public List<User> findAll();
    }
  7. SpringBoot的配置文件中配置Mybatis的信息

    spring:
        jpa:
            database: MySQL
            show-sql: true
            generate-ddl: true
            hibernate:
                ddl-auto: update
                naming_strategy: org.hibernate.cfg.ImprovedNamingStrategy

集成Redis

  1. 添加起步依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
  2. 配置连接信息

    spring:
        redis:
            host=127.0.0.1
            port=6379
  3. 测试

    @RunWith(SpringRunner.class)
    @SpringBootTes(classes="引导类全包名")
    public class Test{
    
        @Autowired
        private RedisTemplate<String, String> redisTemplate;
    
        @Autowired
        private UserRepository userRepository;
    
        @Test
        public void test(){
            String userListJson = redisTemplate.boundValueOps("user.findAll").get();
            if(null==userListJson){
                List<User> all = userRepository.findAll();
                ObjectMapper objectMapper = new ObjectMapper();
                userListJson = objectMapper.writeValueAsString(all);
                redisTemplate.boundValueOps("user.findAll").set(userListJson);   
            }
            System.out.println(userListJson);
        }
    }

猜你喜欢

转载自www.cnblogs.com/whteway/p/12064644.html