SpringBoot框架整理笔记

SpringBoot

  • SSM的问题:jar包容易冲突,配置文件过于臃肿
  • SpringBoot:内置了Tomcat插件,无需配置文件,解决jar包冲突

发展历史

EJB:spring诞生前流行的框架,相对于Spring来说过于臃肿

  • springBoot:构建一切的产品
  • springCloud 协调一切的产品

SpringBoot特点

  • 约定优于配置
  • 专注于业务逻辑之间思维切换
  • 基于spring的开发提供更快入门体验
  • 开箱即用,没有代码生成,无需XML配置
  • 支持修改默认配置,满足要求
  • 提供大型项目中常见的非功能特性,如嵌入tomcat服务,安全,指标,健康检测,外部配置等

SpringBoot核心功能

  • 起步依赖:本质是Maven项目中对象模型中的标签.它定义其SpringBoot对其它库的传递依赖,依赖加在一起课支持某项功能.使得SpirngBoot具备了构建一切的能力,整合所有牛逼的框架
  • 自动配置: 基于约定优于配置思想,配置基本都可以走默认值

SpringBoot入门

方式一
  1. 添加SpringBoot依赖 spring-boot-starter-parent spring-boot-starter-web(web启动器)
  2. 起步依赖(起步引导类) SpringApplication.run(要加载的类的字节码对象,main函数参数),一个工程一个
  3. 自动装配 @SpringBootApplication 标识当前类是SpringBoot启动
@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class,args);
    }
}

SpringBoot配置文件

注意:两种文件只能用一个

application.properties 方式一
##修改tomcat的启动端口号
servier.port=8080   
##设置项目访问根目录  默认值 /
server.servlet.context-path=/demo
application.yml 方式二 推荐
#在yml语法中,空格非常非常敏感 冒号后边有空格隔开

name: Steven

##配置对象数据
User:
	name: LiZhengKai
	age: 18
	addr: ZhuHai
#对象配置方式二
user1: {name: LiZhengKai,age: 18,addr: ZhuHai}

#配置集合
userList: 
  - LiZhengKai
  - WuLiLI
#配置集合方式二
userList2: [LiZhengKai,WuLiLi]

#配置集合重点对象
userListObj:
  - name: LiZhegnKai
    age: 18
    addr: ZhuHai
  - name: WuLiLi
    age: 18
    addr: HeYuan

注意:冒号后边一定要手动加入空格

配置文件与映射类的属性映射方式

使用@Value映射 (简单属性推荐)
//这样子配置文件中的name属性就被赋予到name中
//user.name是springboot内置属性,读取到的是计算机的名字
@Value("${user.name}") 
private String name;  
使用@ConfigurationProperties (较为复杂推荐)
//在实现类中添加@ConfigurationProperties注解 prefix属性表示配置文件中的哪个数据对象
@ConfigurationProperties(prefix="user1")

注意:要使用@Component进行托管,表示这是spring的一个bean对象

使用 Environment (复制属性推荐)
//注入Enviroment
@Autowired
private Environment env;

//获取  可以获取属性,也可以获取属性对象中的属性
env.getProperty("name");
env.getProperty("user.name")

P r o f i l e

企业中不同的环境
  • 开发环境 程序员 本地开发,局域网开发
  • 测试环境 测试工程师
  • 生产环境 真实线上
通过active指定选用配置环境
application.properties
spring.profiles.active=test
application.properties
spring:
  profiles:
    active: test
  • application-dev.properties/yml
  • application-test.properties/yml
  • application-pro.properties/yml

可以在jvm中配置-Dspring.profiles.active=dev 它的级别高于在配置文件中的指定配置


SpringBoot整合Mybatis

  • service层的实现类要使用@Servcie注解
  • doa层接口要使用@Mapper注解
  • resource目录中要有映射文件
application.properties
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://192.168.13.100/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=root
#映射文件加载
mybatis.mapper-locations=classpath:/mapper/*.xml
#配置别名
mybatis.type-aliases-package=com.itheima.integration.domain

#配置日志输出 主要输出sql语句
logging.level.com.itheima.integration.dao=debug

SpringBoot整合Spring Data Redis

引入依赖
<dependency>
    <groupId>org.springframework.bootgroupId>
    <artifactId>spring-boot-starter-data-redisartifactId>
    <version>2.2.2.RELEASEversion>
dependency>
application.properties 默认是localhost和6379
spring.redis.host=192.168.13.100
spring.redis.port=6379
service层
  @Autowired
    private RedisTemplate redisTemplate;
    @Override
    public List<User> findAll() {
     List<User> userList= (List<User>) redisTemplate.boundValueOps("users").get();
     if (userList==null || userList.size()<1){
         userList= userMapper.findAll();
         redisTemplate.boundValueOps("users").set(userList);
         System.out.println("将数据写入缓存");
     }else {
         System.out.println("从缓存中读取");
     }
     return userList;
    }

注意:实现类一定要被序列化,不然会报出异常 java.NotSerializableException

Redis序列化

  • 由于redis的默认序列化机制导致key出现乱码,数据无法正常显示

  • 默认情况下redisTemplate 使用JDK自带的序列化机制:jdkSerializationRedisSerializer

  • JDK自带的序列化机制中要求需要key和value都需要实现Serializable接口

  • RedusTemplate 支持默认以下几种序列化机制: 机制都实现了RedisSerializer接口

    Ø OxmSerializer:xml格式存储

    Ø GenericJackson2JsonRedisSerializer:跟JacksonJsonRedisSerializer实际上是一样的

    Ø GenericToStringSerializer:可以将任何对象泛化为字符串并序列化

    Ø StringRedisSerializer:简单的字符串序列化

    Ø JdkSerializationRedisSerializer:使用JDK的序列化手段(serializable接口,ObjectInputStrean,ObjectOutputStream),数据以字节流存储

    Ø Jackson2JsonRedisSerializer:序列化object对象为json字符串

自定义序列化机制
@SpringBootApplication
public class IntegrationApplication {
    public static void main(String[] args) {
        SpringApplication.run(com.itheima.IntegrationApplication.class, args);
    }
    
    //自定义序列化机制
    @Bean
    public RedisTemplate<Object,Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        //设置key的序列化机制
        template.setKeySerializer(new StringRedisSerializer());
        //设置值的序列化机制
        template.setValueSerializer(new JdkSerializationRedisSerializer());
        return template;
    }
}

SpringBoot原理分析

起步依赖

spring-boot-start-parent 里面有各种jar包的依赖锁定,在SpringBoot自动帮我们整理和jar包依赖,并且解决冲突

但是这里引入的依赖并不是真实的依赖,如果想要用在工程,必须要使用启动器

起步依赖可以获取到依赖的对象,放到容器中

Condition 接口及其相关注解

核心意义: Condition 接口是spirng4.0之后提供的接口,增加条件判断,用于选择性创建ben到容器中

自定义Condition的实现类
public class OnClassCondition implements Condition {
    /**
     *
     * @param context 上下文信息对象,可以获取环境信息,和容器工程和加载器对象
     * @param metadata 注解的元数据 获取注解的属性信息
     * @return true:表示满足条件  false:表示不满足条件
     */
    @Override
    public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
        try {
            Map<String, Object> annotationAttributes = metadata.getAnnotationAttributes(ConditionalOnMy.class.getName());
            System.out.println(annotationAttributes);
            String[] names=(String[])annotationAttributes.get("name");
            for (String name:names){
                Class.forName(name);
            }
            //如果允许不报错,则返回true
            return true;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            //运行报错,返回false
        }
            return false;
    }
}
  • ConditionalOnBean 当spring容器中有某一个bean时使用
  • ConditionalOnClass 当判断当前类路径下有有一个类时使用
  • ConditionalOnMissingBean 当spring容器中没有某一个bean时使用
  • ConditionalOnMissingClass 当当前文件路径下没有某一个类时候才使用
  • CondirionalOnProperty 当配置问文件中有某一个 key value 的时候才使用

@SpringBootApplication 注解

该注解被以下几个注解修饰

@SpringBootConfiguration

时启动类上的注解中的一个注解,本质上时@configuration,意味着我们的启动类被注解修饰后,意味着它本身也是一个配置类,该配置类就可以当作spring中的applicationContext.xml的文件,用于加载配置使用

@ComponentScan( )

相当于包扫描 代表被这个修饰的注解类注解的类进行包扫描

**注意: 如果不指定扫描路径,那么它默认只扫描该注解修饰的启动类所在的包以及子包 指定包路径 **

例如 @ComponentScan("com")

@EnablAutoConfiguration

Enable* 开头就是springboot中定义的一些动态启用某些功能的注解,他的底层实现原理实际上用的就是@import注解导入一些配置,自动进行配置,加载Bean

自动配置流程

  1. @import 注解 导入配置
  2. selectImports 导入类中的方法中加载配置返回Bean 定义的字符数组
  3. 加载META-INF/spring.factories 中获取Bean定义的全路径名返回
  4. 最终返回回去即可

@EnableAutoConfiguration 的作用启动自动配置, @EnableAutoConfiguration 注解的意思就是 SpringBoot 根据你添加的jar包来配置你项目的默认配置,比如根据spring-boot-starter-web,来判断你的项目是否需要添加webmvc和tomcat,该注解会自动帮你配置web项目中所需要的默认配置.简答点来说就是会根据定义在classpath下的类,自动给你生成一些Bean,并加载到spring和Context中

  • @AutoConfigurationPackage 自动配置被修饰的启动类所在的包下的所有带有@Component,@Service,@Controller…注解修改的对象,注册到Spring容器中
  • @Import(AutoConfigurationImportSelector.class) 从META-INF/spring.factories中获取key: EnableAutoCofiguration…的全路径对应的所有类,进行判断条件成立,注册到Spring容器中

将pojo的实现类注入容器

方法一: 在启动器中加入@ComponentScan 注解 并指定扫描的包(扩大扫描范围)

方法二: 使用@Import 注解 指定实现类所对应的配置类的字节码对象 @Import(UserConfig.class)

/**
 * 相当于spring中的applicationContext.xml文件,配置,加载bean
 */
@Configuration
public class UserConfig {
    @Bean
    public User user(){
        return new User();
    }
}

方法三: 使用自定义的Enable注解

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(UserConfig.class)  //将需要放到容器的实现类对应的配置类的字节码对象作为参数传入Import注解中
public @interface EnableUser {
}

方法四: 在配置类中自定义ImportSelector的实现类 并重写selectImports()方法 返回的是一个String数组

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        //返回要注册到spring容器中的Bean的全路径
        return new String[]{"com.itheima.pojo.User","com.itheima.pojo.Role"};
    }
}

在启动器中使用getBean(实现类字节码对象) 得到容器中的实现类

@Import(MyImportSelector.class)
public class DemoEnable2Application {
    public static void main(String[] args){
        ConfigurableApplicationContext context = SpringApplication.run(DemoEnable2Application.class, args);

        //获取加载第三方依赖中的bena
//        Object user1 = context.getBean("user");

        //MyImportSelector需要使用的配置类型
        Object user = context.getBean(User.class);
        System.out.println(user);
        Object role = context.getBean(Role.class);
        System.out.println(role);

方法五: 在配置类中自定义 ImportBeanDefinitionRegistrar 的实现类,并重写rgisterBeanDefinitions() 方法,再在启动器的Import注解中指定该实现类的字节码对象

public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar {
    /**
     *
     * @param annotationMetadata 注解的元数据 获取注解的属性信息
     * @param beanDefinitionRegistry  注册器
     */
    @Override
    public void registerBeanDefinitions(AnnotationMetadata annotationMetadata, BeanDefinitionRegistry beanDefinitionRegistry) {
        //创建BeanDefinition对象
        AbstractBeanDefinition userDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition();
        AbstractBeanDefinition roleDefinition = BeanDefinitionBuilder.rootBeanDefinition(Role.class).getBeanDefinition();
        //注册Bean到容器中
        beanDefinitionRegistry.registerBeanDefinition("user",userDefinition);
        beanDefinitionRegistry.registerBeanDefinition("Role",roleDefinition);
    }
}

Redis地址动态加载

Redis的实现类 (要加上@ConfigurationProperties(prefix=“redis”) 注解 因为要从配置文件中动态加载 )

RedisAutoConfiguration

@Configuration
@EnableConfigurationProperties(RedisProperties.class)
@ConditionalOnClass(Jedis.class)  //当前项目中有Jedis依赖项时,让配置生效
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(Jedis.class) //当当前容器没有jedis再使用Bean容器的逻辑
    public Jedis jedis(RedisProperties redisProperties){
        System.out.println("SprongBoot自动创建Jedis对象   host:"+redisProperties.getHost()+"| Port:"+redisProperties.getPort());
        return new Jedis(redisProperties.getHost(),redisProperties.getPort());
    }
}

在resources目录下创建META-INF/sprinig.factories文件

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
com.*..RedisAutoConfiguration    #这里是配置类的全路径

在另一个工程创建起步引导类

@SpringBootApplication
public class ItheimaRedisTestApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(ItheimaRedisTestApplication.class, args);
        Jedis bean = context.getBean(Jedis.class);
        System.out.println(bean);
    }
    @Bean
    public Jedis jedis(){
        System.out.println("执行的时Jedis容器");
        return  new Jedis("hostll",888);
    }
}

创建application.yml文件

redis:
  host: 192.168.13.100
  port: 6379
原理
  1. application.yml的配置数据会被传到Redis的实现类中,因为加了@ConfigurationProperties(prefix=“redis”) 注解,并且指定了数据对象名redis
  2. 在RedisAutoConfiguration类中由于在类上定义了@ConditionalOnClass(Jedis.class) 注解 表示若是有Jedis对象,就会执行这个类的配置,将这个Jedis对象的数据放到容器中
  3. 但是类中的方法 jedis() 上有ConditionalOnMissingBean(Jedis.class) 注解 表示如果没有这个jedis对象就执行这个方法(执行这个Bean容器中的逻辑)
  4. 这样就会直接将实现类中已经得到了配置文件中的数据传到这个方法里,在放到容器中

SpirngBoot的监控

Actuator (不推荐,看着头晕)

是Springboot官方自带的组件,可以用来监控,Bean加载情况,环境变量,日志信息,线程信息等等

application.properties
#配置健康信息的详情内容  aways表示显示所有健康信息
mamagement.endoint.health.show-details=aways

#配置info信息 http://localhost:8080/actuator/info  前缀必须是info
info.name-Lizhengkai
info.sex=1
info.age=22

#配置 暴露所有web相关的端点信息
management.endpoints.web.expsoure.include=*
页面显示的信息
  • /beans 查看上下文当中所有的Bean,以及他们的关系
  • /env 获取全部环境属性
  • /env/{name} 过呢据名称获取特定的环境属性值
  • /health 报告应用程序的健康指标,这些值由HealthIndicaator的实现提供
  • /info 获取应用程序的定制信息,这些信息由info打头的属性提供
  • /mappings 描述全部的URL路径,以及他们和控制器(包含Actuator端点)的映射关系
  • /metrics 报告各种以用程序度量信息,比如内存用量和Http请求计数
  • /metrics{name} 报告指定名称的应用程序度量值
  • /trace 提供基本的HTTP请求跟踪信息(时间戳,HTTP头等)
SpirngBooot admin (推荐)
介绍
  • Spring Boot Admin 是一个开源社区项目,用于管理和监控SpringBoot应用程序
  • Spring Boot Admin 由两个角色,客户端(Client)和服务端(Server)
  • 应用程序作为Spring Boot Admin Client 向为Spring Boot Admin Server 注册
  • Spring Boot Admin Server 通过图形化界面方式展示Spirng Boot Admin Client 的监控信息
使用
  • admin server 用于收集统计所有相关Client 的注册过来的信息进行汇总展示

  • admin client 每一个spring boot 工程都是一个clent 相关的功能展示需要汇总到server

版本锁定
<dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>de.codecentricgroupId>
                <artifactId>spring-boot-admin-dependenciesartifactId>
                <version>2.1.6version>
                <type>pomtype>
                <scope>importscope>
            dependency>
        dependencies>
    dependencyManagement>
服务端依赖
<dependency>
            <groupId>de.codecentricgroupId>
            <artifactId>spring-boot-admin-starter-serverartifactId>
        dependency>
客户端依赖
 <dependency>
            <groupId>de.codecentricgroupId>
            <artifactId>spring-boot-admin-clientartifactId>
        dependency>
客户端配置文件
#配置注册到server的ip端口地址
spring.boot.admin.client.url=http://localhost:9000
#配置健康信息的详情内容  aways表示显示所有健康信息
mamagement.endoint.health.show-details=aways
#启动健康检查,默认是true
management.endpoint.health.enabled=true
#配置info信息 http://localhost:8080/actuator/info  前缀必须是info
info.name-Lizhengkai
info.sex=1
info.age=22
#配置 暴露所有web相关的端点信息
management.endpoints.web.expsoure.include=*

SpringBoot监听机制与启动流程

SpringBoot提供了四个监听器

  • ApplicationContextInitializer 在spring容器刷新之前,调用该方法 用于:做些初始化工作,通常用于web环境,用于激活配置,web上下文的属性注册 注意: 需要配置WETA-INF/spring.factories 配置之后才能调用
  • SpringApplicationRunListener 也需要配置META-INF/spring.factories 之后才能调用,它是SpringApplication run 方法的监听器,当我们使用SpringApplication调用Run方法时触发该监听器的回调方法 注意: 它需要一个公共的构造函数,并且每一次RUN的时候都需要重新创建实列
  • CommandLirneRunner 在容器准备好了之后可以回调 @Componet 注解修饰
  • ApplicationRunner 在容器准备好了之后可以回调 @Componet 注解修饰

你可能感兴趣的:(笔记,框架)