Springboot使用方法

1.常用注解
  1. 修饰类
    1. @ SpringBootApplication //标记这是个主程序类,并自动扫描该主类所在包及其子包中的类
    2. @ ConfigurationProperties(prefix = "zhangsan") //表示全局配置文件 文件中 zhangsan 这个父节点下的子节点属性对应该bean类
    3. @PropertySource(value={ " classpath:jdbc.properties " , "classpath:spring.properties" }) //加载指定的配置文件
    4. @ImportResource //在SpringBoot中不支持Spring的xml配置文件,该注解可以引入Spring的XML配置文件
    5. @ Configuration //表示这是一个配置类
    6. @Bean //将方法的返回值添加到容器中,方法名是默认的组件id
    7. @Component //组件,用于给Spring接管
    8. @Controller //表示这是一个控制器,能被Spring接管
    9. @ResponseBody //表示这个类的所有方法的返回值,都写给浏览器(如果是对象则返回json数据)
    10. @ RestController 等价于@ Controller + @ResponseBody
    11. @ validated //启动数据校验,可以给属性添加注解如,@Email该属性必须为email
    12. @ Conditional //满足条件,配置类才会生效
      1.  
  2. 修饰属性
    1. @ Autowired //自动装配
    2. @ value //给容器中的bean的属性注入值,不和@ ConfigurationProperties搭配,支持字面量,SPEL,配置文件
      1. 字面量@value(3)
      2. SPEL@value("#{11*3}")
      3. 配置文件@value("${person.name}")
    3. @Email和@ validated搭配,校验数据JSR303
    4.  
  3. 修饰函数
    1. @ RequestMapping( "/hello") //该函数用于接收/hello请求
    2.   @ResponseBody / / 将方法返回的对象写入到response对象的body区,通常用来返回JSON数据或者是XML
    3. 修饰参数
2.SpringBoot的精髓在于自动配置(xxxAutoConfiguration,自动配置类;xxxProperties,属性类)
  1. springboot会加载大量的自动配置类,可以搜索*AutoConfiguration查看实现类
  2. 查看我们需要的功能有没有SpringBoot默认写好的自动配置类
  3. 再看这个自动配置类中配置了哪些组件
  4. 这些组件的属性会从propeties类中加载属性
3.环境准备
  1. java版本--1.8.0_241
  2. 为Eclipse安装 Spring Tools 4 
  3. Maven版本--3.3.9
4.Spring Boot HelloWorld
@SpringBootApplication //标记这是个主程序类
public class Application {
      public static void main(String[] args) {
           SpringApplication. run(Application. class, args);
     }
}
@Controller
public class HelloWorld {
    @RequestMapping( "/hello")
    @ResponseBody
    public String hello() {
        return "Hello World";
    }
}
  1. 创建SpringBoot工程
  2. resources目录结构
    1. static:保存所有的静态资源。如js,css,image
    2. template:保存所有的模板页面。springBoot默认不支持jsp页面,但是可以使用模板引擎如freemaker,thymeleaf
    3. application.properties:应用配置。用于修改SpringBoot的默认配置,如服务器端口号
  3. 标记主程序
  4. 编写业务代码
  5. 测试
  6. 打包成jar包
    1. run as---maven install
  7. 部署
5.配置文件语法
  1. Springboot 使用一个全局的配置文件application.properties或者application.yml(application.yaml)
  2. 示例
  3. server:
      port: 8080
      address: localhost
  4. 语法
     
    1. 基本语法
      1. 大小写敏感
      2. 以空格的缩进代表层级关系
      3. k:(空格)v表示-对键值对
    2. 值的写法
      1. 字面量的写法(数字,布尔值,字符串)
        1. 直接写就可以了,字符串默认可以不带单引号或者双引号
        2. 单引号括起来的字符串会自动转里面的转义字符
        3. 双引号括起来的字符串不转特殊的转义字符
      2. 对象,Map(键,值)(键值对)
        1. 对象
          friend:
              name: zhangsan
              age: 18
          friend: { name: zhangsan, age: 18
          1. 写法1
          2. 写法2
      3.  
    3. 数组(List,Set)
      1. 用-表示一个元素
        pets:
         - cat
         - dog
         - duck
        pets: [ cat, dog, duck]
        1. 写法1
        2. 写法2
      2.  
6.利用配置文件自动配置bean
< dependency >
    < groupId >org.springframework.boot </ groupId >
     < artifactId >spring-boot-configuration-processor </ artifactId >
     < optional >true </ optional >
</ dependency >
@Component //组件,用于给Spring接管
@ConfigurationProperties(prefix = "zhangsan") //表示 yml 文件中 zhangsan 这个父节点下的子节点属性对应该类
public class Person {
    private String name;
    private int age;
    private boolean alive; //这些属性不能用is开头,不然生成的getter,setter方法不太对
    private Date birth;
    private Map<String,Object> maps;
    private List<Object> list;
zhangsan:
  name: zhangsan
  age: 18
  alive: true
  birth: 2019/2/2
  maps: { k1: v1, k2: v2}
  list: [ v1, v2, v3]
@SpringBootTest
class ApplicationTests {
    @Autowired
    Person person;
      @Test
      void contextLoads() {
         System. out.println( person);
     }
}
  1. pom文件引入配置处理器,这样写yml文件时有提示
  2. 编写bean的类,同时自动生成getter,setter方法
  3. 编写yml文件(这里不知道为什么eclipse不提示,还显示报错,但是可以正常运行)
  4. 运行查看是否注入
  5. @ConfigurationProperties与@valuez注入值的区别
  6. @ ConfigurationProperties与@PropertySource的区别
    1. @Component //组件,用于给Spring接管
      //@ConfigurationProperties(prefix = " zhangsan ")//表示 yml 文件中 zhangsan 这个父节点下的子节点属性对应该类
      @PropertySource(value= { "classpath:person.properties"})
      public class Person {
          private String name;
          private int age;
      1. @ ConfigurationProperties从全局配置文件中加载属性
      2. @PropertySource可以指定配置文件
  7. @ImportResource //在SpringBoot中不支持Spring的xml配置文件,该注解可以引入Spring的XML配置文件
    @ImportResource(locations = { "classpath:spring.xml"})
    @SpringBootApplication //标记这是个主程序类
    public class Application {
          public static void main(String[] args) {
               SpringApplication. run(Application. class, args);
         }
    1.  
7.SpringBoot向容器中添加组件的方式是通过配置类
  1. 创建配置类
  2. @Configuration //指明当前类是一个配置类,取代了之前的SpringXML文件
    public class MyConfiguration {
        @Bean //将方法的返回值添加到容器中,方法名是默认的组件id
        public Person person() {
            return new Person();
        }
    }
  3. 获取组件
  4.      @Autowired
         private ApplicationContext ac;
        @Test
        void testPerson() {
            System. out.println( ac.getBean( "person"));
        }
8.Profile可以快速切换环境
  1. 对于application.properties可以采用多文档方式application-{profile}.properties
    spring.profiles.active= dev
    server.port= 8080
    1. 创建application-dev.properties
    2. 在application.properties中激活指定配置文件
  2. 对于application.yml可以采用文档块方式
9.日志模块
  1. 日志抽象类与实现类
    1. 意味着我们如果使用日志框架,需要选一个抽象类jar包(SLF4j)。一个实现类jar包(logback)
  2. 如何使用
     
    1. Springboot的web自动含有日志jar包,如果没有导入jar包
      1. slf4j-api.jar
      2. lobback-classic.jar
      3. logback-core.jar
    2. 代码
    3. import org.slf4j.Logger;
      import org.slf4j.LoggerFactory;
      public class HelloWorld {
        public static void main(String[] args) {
          Logger logger = LoggerFactory.getLogger(HelloWorld. class);
          logger.info( "Hello World");
        }
      }
  3. SpringBoot日志模块的依赖关系
  4. Springboot输出日志
    1. 日志的类一定要使用slf4j包内的类
      1. import org.junit.jupiter.api.Test;
      2. import org.slf4j.Logger;
      3. import org.slf4j.LoggerFactory;
      4. import org.springframework.boot.test.context.SpringBootTest;
      5. @SpringBootTest
      6. class BootApplicationTests {
      7.     Logger logger = LoggerFactory. getLogger( this.getClass());
      8.       @Test
      9.       void contextLoads() {
      10.          //日志级别,由低到高 trace<debug<info<warn<error
      11.          //可以调整日志的级别,这样日志只会在>=该级别才输出
      12.          logger.trace( "这是trace日志");
      13.          logger.debug( "这是debug日志");
      14.          //Spring默认是info级别的
      15.          logger.info( "这是info日志");
      16.          logger.warn( "这是warn日志");
      17.          logger.error( "这是error日志");
      18.      }
      19. }
    2. 日志模块的配置
      1. 日志输出级别
        1. logging:
        2.   level:
        3.     com.example.demo: trace //com.example.demo这个包下的所有类的输出级别为trace
      2. 日志输出路径:不要和file.name一起用,不然不生效
        1. logging:
        2.   file:
        3.     path: log //会在当前项目路径下生成log文件夹,/log/spring.log
      3. 日志输出文件
        1. logging:
        2.   file:
        3.     name: spring/log.log //会在当前项目下创建/spring/log.log,并将日志输出到log.log
      4. 日志输出格式
        1. logging:
        2.   pattern:
        3.     file: '%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %m%n'
        4. %d{yyyy-MM-dd HH:mm:ss.SSS}:表示年月日时分秒毫秒
        5. [%thread]:线程名
        6. %-5level:左对齐,输出日志级别,最多占5个字符
        7. %logger{50}:最多50个字符,输出类名(也就是this.getClass()  LoggerFactory. getLogger( this.getClass());
        8. %m%n:消息内容和换行
10.Springboot进行web开发
11.Springboot整合MyBatis进行数据库交互
  1. Mybatis访问数据库
    1. 注解方式
      1. 创建项目
        1. 勾选mysql Driver; JDBC API;Mybatis
      2. 配置数据源
        1. spring:
        2.   datasource:
        3.     url: jdbc:mysql://192.168.1.103:3306/jdbc?serverTimezone=Asia/Shanghai
        4.     username: root
        5.     password: yahang.521
        6.     driver-class-name: com.mysql.cj.jdbc.Driver
        7.    
        8.     # Hikari 连接池配置
        9.     hikari:
        10.       minimum-idle: 5 # 最小空闲连接数量    
        11.       idle-timeout: 180000 # 空闲连接存活最大时间,默认600000(10分钟)    
        12.       maximum-pool-size: 10 # 连接池最大连接数,默认是10   
        13.       auto-commit: true  # 此属性控制从池返回的连接的默认自动提交行为,默认值:true    
        14.       pool-name: HikariPool # 连接池名称     
        15.       max-lifetime: 1800000 # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟    
        16.       connection-timeout: 30000 # 数据库连接超时时间,默认30秒,即30000
        17.       connection-test-query: SELECT 1
      3. 创建操作不同表对应的Mapper接口
        1.      @Mapper
        2. public interface StudentMapper {
        3.    
        4.     @Select( "select * from student where id=#{id}")
        5.     Student queryStudentById(Integer id);
        6.    
        7.     @Delete( "delete from student where id = #{id}")
        8.     int deleteStudentById(Integer id);
        9.       
        10. }
      4. 编写业务代码
        1.      @Controller
        2. public class StController {
        3.    
        4.     @Autowired
        5.     private StudentMapper studentMapper;
        6.    
        7.     @ResponseBody
        8.     @RequestMapping( "/getStudentById")
        9.     public Student getStudentById(Integer id) {
        10.         Student student = studentMapper.queryStudentById( id);
        11.         return student;
        12.     }
        13. }
      5. 其他
        1. 批量扫描包下的mapper类
        2. @MapperScan(value = "com.njupt.mapper")
        3. @SpringBootApplication
        4. public class MybatisApplication {
        5.       public static void main(String[] args) {
        6.            SpringApplication. run(MybatisApplication. class, args);
        7.      }
        8. }
    2. 配置文件方式
      1. 创建项目
        1. 勾选mysql Driver; JDBC API;Mybatis
      2. 配置数据源
        1. spring:
        2.   datasource:
        3.     url: jdbc:mysql://192.168.1.103:3306/jdbc?serverTimezone=Asia/Shanghai
        4.     username: root
        5.     password: yahang.521
        6.     driver-class-name: com.mysql.cj.jdbc.Driver
        7.    
        8.     # Hikari 连接池配置
        9.     hikari:
        10.       minimum-idle: 5 # 最小空闲连接数量    
        11.       idle-timeout: 180000 # 空闲连接存活最大时间,默认600000(10分钟)    
        12.       maximum-pool-size: 10 # 连接池最大连接数,默认是10   
        13.       auto-commit: true  # 此属性控制从池返回的连接的默认自动提交行为,默认值:true    
        14.       pool-name: HikariPool # 连接池名称     
        15.       max-lifetime: 1800000 # 此属性控制池中连接的最长生命周期,值0表示无限生命周期,默认1800000即30分钟    
        16.       connection-timeout: 30000 # 数据库连接超时时间,默认30秒,即30000
        17.       connection-test-query: SELECT 1
      3. 在resources目录下创建两个目录
        1. resources/mybatis/config:mybatis全局配置文件目录
          1. 新建mybatis-config.xml文件: 该文件无需配置环境,也无需引用mapper文件,直接配置就可以
            1. <? xml version= "1.0" encoding= "UTF-8" ?>
            2. <! DOCTYPE configuration
            3.   PUBLIC "-// mybatis.org//DTD Config 3.0//EN"
            4. < configuration >
            5.     < settings >
            6.         < setting name= "mapUnderscoreToCamelCase" value= "true" />
            7.     </ settings > 
            8. </ configuration >
        2. resources/mybatis/mapper:mybatis sql映射文件目录
          1. 新建StudentMapper.xml
            1. <? xml version= "1.0" encoding= "UTF-8" ?>
            2. <! DOCTYPE mapper
            3.   PUBLIC "-// mybatis.org//DTD Mapper 3.0//EN"
            4. < mapper namespace= "com.njupt.mapper.StudentMapper" > <!-- 接口全类名 -->
            5.       < select id= "getStudentById" resultType= "com.njupt.entities.Student" >
            6.            select * from student where id=#{id}
            7.       </ select >
            8. </ mapper >
      4. 让SpringBoot查找到这两个xml文件,需要在application.yml中配置以下两项
        1. mybatis:
        2.   config-location: classpath:mybatis/config/mybatis-config.xml
        3.   mapper-locations:
        4.   - classpath:mybatis/mapper/*.xml
      5. 创建操作不同表对应的Mapper接口
        1. public interface StudentMapper {
        2.     public Student getStudentById(Integer id);
        3. }
      6. 批量扫描包下的mapper类
        1. @ SpringBootApplication
        2. @MapperScan(value = "com.njupt.mapper")
        3. public class MybatisApplication {
        4.       public static void main(String[] args) {
        5.            SpringApplication. run(MybatisApplication. class, args);
        6.      }
        7. }
      7. 编写业务代码
        1. @Controller
        2. public class StudentController {
        3.    
        4.     @Autowired
        5.     private StudentMapper studentMapper;
        6.     private Logger logger = LoggerFactory. getLogger( this.getClass());
        7.    
        8.     @RequestMapping( "/getStudentById/{id}")
        9.     @ResponseBody
        10.     public Student getStudentById( @PathVariable( "id") Integer id) {
        11.         logger.info( "enter getStudentById");
        12.         return studentMapper.getStudentById( id);
        13.     }
        14. }
      8. 测试
12.springboot整合多数据源
  1. 引入数据源依赖
  2. 写自定义数据源配置
  3. spring:
        datasource:
            mybatis-datasource:
                jdbc-url: jdbc:mysql://192.168.1.103:3306/mybatis?serverTimezone=Asia/Shanghai
                driver-class-name: com.mysql.cj.jdbc.Driver
                username: root
                password: yahang.521
                # Hikari connection pool
                type: com.zaxxer.hikari.HikariDataSource
                auto-commit: true
                minimum-idle: 50
                maximum-pool-size: 100
                pool-name: packageDatasourcePool
            jdbc-datasource:
                jdbc-url:jdbc:mysql://192.168.1.103:3306/jdbc?serverTimezone=Asia/Shanghai
                driver-class-name: com.mysql.cj.jdbc.Driver
                username:root
                password: yahang.521
                # Hikari connection pool
                type: com.zaxxer.hikari.HikariDataSource
                auto-commit: true
                minimum-idle: 50
                maximum-pool-size: 100
                pool-name: datailDatasourcePool

     

  4. 新建各个数据源的配置类
     
     
    1. MybatisDBConfiguration.java
    2. @Configuration
      @MapperScan(basePackages = "com.njupt.mappers.mybatisMapper",sqlSessionFactoryRef = "mybatisSqlSessionFactory")
      public classMybatisDBConfiguration{
          @Primary
          @Bean("mybatisDataSource")
          @ConfigurationProperties(prefix = "spring.datasource.mybatis-datasource")
          public DataSource packageDataSource(){
              return DataSourceBuilder.create().build();
          }
          @Primary
          @Bean("mybatisSqlSessionFactory")
          public SqlSessionFactory mybatisSqlSessionFactory(@Qualifier("mybatisDataSource")         DataSource dataSource) throws Exception{
              SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
              bean.setDataSource(dataSource);
              bean.setMapperLocations(new         PathMatchingResourcePatternResolver().getResource("classpath:mybatis/mappers/mybatisMapper/mybatisMapper.xml"));
              org.apache.ibatis.session.Configuration configuration = new         org.apache.ibatis.session.Configuration();
              configuration.setMapUnderscoreToCamelCase(true);//开启驼峰
              bean.setConfiguration(configuration);
              return bean.getObject();
          }
          @Primary
          @Bean("mybatisTransactionManager")
          public DataSourceTransactionManager mybatisTransactionManager(@Qualifier("mybatisDataSource") DataSource dataSource){
              return new DataSourceTransactionManager(dataSource);
          }
          @Primary
          @Bean("mybatisSqlSessionTemplate")
          public SqlSessionTemplate mybatisSqlSessionTemplate(@Qualifier("mybatisSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
              return new SqlSessionTemplate(sqlSessionFactory);
          }
      }
    3. JDBCDBConfiguration.java
    4. @Configuration
      @MapperScan(basePackages = "com.njupt.mappers.jdbcMapper",sqlSessionFactoryRef = "jdbcSqlSessionFactory")
      public class JDBCDBConfiguration{
          @Bean("jdbcDataSource")
          @ConfigurationProperties(prefix = "spring.datasource.jdbc-datasource")
          public DataSource detailDataSource(){
              return DataSourceBuilder.create().build();
          }
      
          @Bean("jdbcSqlSessionFactory")
          public SqlSessionFactory jdbcSqlSessionFactory(@Qualifier("jdbcDataSource") DataSource dataSource) throws Exception{
              SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
              bean.setDataSource(dataSource);
              org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
              configuration.setMapUnderscoreToCamelCase(true);
              bean.setConfiguration(configuration);
              bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResource("classpath:mybatis/mappers/jdbcMapper/JDBC1Mapper.xml"),new PathMatchingResourcePatternResolver().getResource("classpath:mybatis/mappers/jdbcMapper/JDBC2Mapper.xml"));
              return bean.getObject();
          }
          @Bean("jdbcTransactionManager")
          public DataSourceTransactionManager jdbcTransactionManager(@Qualifier("jdbcDataSource") DataSource dataSource){
              return new DataSourceTransactionManager(dataSource);
          }
          @Bean("jdbcSqlSessionTemplate")
          public SqlSessionTemplate jdbcSqlSessionTemplate(@Qualifier("jdbcSqlSessionFactory") SqlSessionFactory sqlSessionFactory){
              return new SqlSessionTemplate(sqlSessionFactory);
          }
      }
    5. 正常使用Mapper执行对应方法即可
12.SpringBoot整合redis
  1. RedisTemplate和StringRedisTemplate
    1. RedisTemplate放的key和value是对象,因此放入的对象需要实现序列化接口
    2. StringRedisTemplate放的key和value是String
  2. 使用
    @Autowired
    StringRedisTemplate stringRedisTemplate ;
    @Test
    void contextLoads() {
    stringRedisTemplate .opsForValue().set( "key" , "value" );
    }
    1. 引入依赖
      1. <dependency>
      2.     <groupId>org.springframework.boot</groupId>
      3.     <artifactId>spring-boot-starter-data-redis</artifactId>
      4.     <version>2.2.5.RELEASE</version>
      5. </dependency>
    2. 配置配置文件
      1. spring.redis.host=192.168.1.100
      2. spring.redis.port=6379
      3. spring.redis.database=0
    3. 操作数据库
  3. 相关操作
    1. 操作key
      1. stringRedisTemplate.delete("key"):删除key
      2. stringRedisTemplate .hasKey("key"):是否存在key
      3. stringRedisTemplate .type("key"):key的类型
      4. stringRedisTemplate .keys("*"):返回所有key
      5. stringRedisTemplate .getExpire( "key" ):获取key的超时时间。-1:永不超时,-2:key不存在,>=0:过期时间
    2. opsForValue:操作字符串
      1. set("key","value");设置key,value
      2. set( "key" , "value" , 60 , TimeUnit. SECONDS );设置超时时间
    3. opsForHash:操作散列表
    4. opsForList:操作List
    5. opsForSet:操作Set
    6. opsForZset:操作ZSet
  4. bound Api
    1. 由于opsForXX的每次操作都要输入一个key,当我们后续操作都对同一个key进行的操作,可以使用boundApi,绑定key
    2. 示例代码
      1. BoundValueOperations<String,String> boundValueOperations = stringRedisTemplate.boundValueOps( "key");
      2. boundValueOperations.get()
    3. boundValueOps():绑定一个字符串
    4. boundHashOps():绑定散列表
    5. boundListOps():绑定List
    6. boundSetOps():绑定Set
    7. boundZSetOps():绑定ZSet
  5. 经常使用RedisTemplate,可以更改RedisTemplate的序列化器,默认是jdk序列化,我们改为Json序列化
    1. @Bean
    2. public RedisTemplate<Object, Object> redisTemplateWithJson(RedisConnectionFactory redisConnectionFactory) throws UnknownHostException {
      1. RedisTemplate<Object, Object> template = new RedisTemplate<>();
      2. template.setConnectionFactory(redisConnectionFactory);
      3. RedisSerializer<Person> redisSerializer = new Jackson2JsonRedisSerializer<Person>(Person. class );
      4. template.setDefaultSerializer(redisSerializer);
      5. return template;
    3. }
13.Springboot缓存
  1. Spring缓存抽象
    1. 重要概念以及缓存注解
      1. Cache:缓存接口,定义缓存操作,实现又:RedisCache,EhCacheCache,ConcurrentMapCache等
      2. CacheManager:缓存管理器,管理各种缓存组件
      3. @Cacheable:修饰方法,能够根据方法的请求参数和返回结果进行缓存
      4. @CacheEvict:修饰方法,清空缓存,例如从数据库删除某个用户,那就需要把相应的缓存也删除掉
      5. @CachePut:修饰方法,调用函数,更新缓存
        1. @Cacheable一旦缓存命中,就不再调用修饰的函数了
        2. @CachePut一定会调用函数,并把值放到缓存,常用于更新操作,先调用函数,在更新缓存
      6. @EnableCaching:开启基于注解的缓存模式
      7. keyGenerator:缓存数据时key的生成策略
      8. serialize:缓存数据时value序列化策略
    2. 搭建环境
      1. 引入包
        1. < dependency>
        2. < groupId > org.springframework.boot </ groupId >
        3. < artifactId > spring-boot-starter-cache </ artifactId >
        4. </ dependency >
      2. 使用缓存
        @Cacheable
        public String getUser( int id){
        System. out .println( " 缓存未命中 " );
        return "zhangsan" ;
        }
        1. 开启基于注解的缓存
        2. 使用缓存
    3. @Cacheable
      @Caching(
      cacheable={ @Cacheable (), @Cacheable ()},
      put={},
      evict = {}
      )
      1. 属性
        1. cacheNames/value :数组,缓存名字,因为缓存管理器下有许多缓存,所以这个指定从哪个缓存中查找数据,或者将数据存入哪个缓存中,可以将一份数据存到多个缓存
          1. @Cacheable(cacheNames="emp")
        2. key:存缓存或者查找缓存value时用的键,支持spel表达式。默认key为参数的值
          1. @Cacheable的key不能用#result
        3. keyGenerator:key的生成器,可以指定key生成器的组件id,key和 keyGenerator两个属性二选一
          @Configuration
          public class CacheAutoConfiguration{
          @Bean ( "myKeyGenerator" )
          public KeyGenerator keyGenerator(){
          return new KeyGenerator() {
          @Override
          public Object generate(Object target, Method method, Object... params) {
          return "hahaha" ;
          }
          }
          }
          }
          1. 自定义 keyGenerator
          2. 使用自定义的 keyGenerator
            1. @Cacheable (cacheNames = "emp" , keyGenerator = "myKeyGenerator" )
        4. cacheManager:指定从哪个缓存管理器中拿到缓存,
        5. cacheResolver:指定寻找 cacheManager的策略, cacheResolver与 cacheManager二选一
        6. condition:可以使用spel表达式,满足条件才缓存
        7. unless:满足unless条件,则不缓存,可以获取到结果进行判断
          1. @Cacheable(unless="#result == null")
        8. sync:是否使用异步模式,默认false.意思是。在put数据时,是异步还是同步
      2. 原理
        1. 自动配置类: CacheAutoConfiguration
        2. Import选择器: CacheConfigurationImportSelector
          1. org.springframework.boot.autoconfigure.cache.GenericCacheConfiguration
          2. org.springframework.boot.autoconfigure.cache.JCacheCacheConfiguration
          3. org.springframework.boot.autoconfigure.cache.EhCacheCacheConfiguration
          4. org.springframework.boot.autoconfigure.cache.HazelcastCacheConfiguration
          5. org.springframework.boot.autoconfigure.cache.InfinispanCacheConfiguration
          6. org.springframework.boot.autoconfigure.cache.CouchbaseCacheConfiguration
          7. org.springframework.boot.autoconfigure.cache.RedisCacheConfiguration
          8. org.springframework.boot.autoconfigure.cache.CaffeineCacheConfiguration
          9. org.springframework.boot.autoconfigure.cache.SimpleCacheConfiguration
          10. org.springframework.boot.autoconfigure.cache.NoOpCacheConfiguration
        3. 哪个配置生效呢?
          1. 每个CacheConfiguration上面都用注解标识了生效条件
          2. SimpleCacheConfiguration这个有可能生效
        4. SimpleCacheConfiguration给容器中注入了一个CacheManager( ConcurrentMapCacheManager)的bean
          1. ConcurrentMapCacheManager维护了一个Map<String, ConcurrentMapCache>,String为缓存的名字
        5. ConcurrentMapCacheManager可以获取和创建 ConcurrentMapCache组件,并将数据放到 ConcurrentMapCache中
          1. ConcurrentMapCache就是一个类,属性有name和 ConcurrentMap
        6. 整个流程
      3. @CachePut
        1. 先调用函数在更新缓存
        2. 注意点
          1. @Cacheable添加缓存
            1. @Cacheable(cacheNames = "emp", keyGenerator = "myKeyGenerator")
            2. public String getUser( int id){
          2. @ CachePut添加缓存
            1. @CachePut (cacheNames = "emp" )
            2. public Employee update(Employee emp){
          3. 这两个缓存的key的生成可能不一杨,可能会导致他们更新的缓存原本应该是同一个,但是却由于生成key不一样,导致缓存更新错误
      4. @CacheEvict
        1. key:指定要清除的key
        2. allEntries=true:清除缓存中的所有数据,默认false
        3. beforeInvocation=true:实在方法执行之前清除缓存,还是在方法执行之后清除缓存,默认为false,
          1. 如果在方法执行之后清除缓存,一旦方法出现异常,那么缓存不会被清除
      5. @Caching可以使用组合注解
      6. @CacheConfig修饰类,可以将 Cacheable, CachePut, CacheEvict的公共属性提取出来
  2. 整合redis使用缓存
     
    1. 引入依赖
      1. <!-- springboot整合redis的starter- ->
      2. < dependency>
      3. < groupId > org.springframework.boot </ groupId >
      4. < artifactId > spring-boot-starter-data-redis </ artifactId >
      5. </ dependency >
      6. <!-- redis如果要使用连接池技术,需要依赖这个包- ->
      7. < dependency >
      8. < groupId > org.apache.commons </ groupId >
      9. < artifactId > commons-pool2 </ artifactId >
      10. </ dependency >
      11. <!-- 由于我们需要更改对象序列化为json存到redis中,需要这个包 -->
      12. < dependency >
      13. < groupId > com.fasterxml.jackson.core </ groupId >
      14. < artifactId > jackson-core </ artifactId >
      15. < version > 2.9.8 </ version >
      16. </ dependency >
      17. <!-- 从redis读取数据,反序列化为对象时,绑定数据需要这个包  -->
      18. < dependency >
      19. < groupId > com.fasterxml.jackson.core </ groupId >
      20. < artifactId > jackson-databind </ artifactId >
      21. < version > 2.9.8 </ version >
      22. </ dependency >
    2. 配置redis连接池
      1. spring:
        1. redis :
          1. host : 127.0.0.1
          2. port : 6379
          3. database : 0
          4. lettuce :
            1. pool :
              1. # 连接池最大连接数 默认 8 ,负数表示没有限制
              2. max-active : 20
              3. # 连接池中的最大空闲连接 默认 8
              4. max-idle : 10
              5. # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1
              6. max-wait : 1000
          5. timeout : 10000
    3. 修改cacheManager的默认配置
    4. public CacheManager cacheManager(LettuceConnectionFactory redisConnectionFactory) {
      // 初始化一个 RedisCacheWriter
      RedisCacheWriter redisCacheWriter = RedisCacheWriter. nonLockingRedisCacheWriter (redisConnectionFactory);
      // 设置 CacheManager 的值序列化方式为 json 序列化
      Jackson2JsonRedisSerializer<Person> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Person. class );
      RedisSerializationContext.SerializationPair<Person> pair = RedisSerializationContext.SerializationPair
      . fromSerializer (jackson2JsonRedisSerializer);
      RedisCacheConfiguration defaultCacheConfig= RedisCacheConfiguration. defaultCacheConfig ()
      .serializeValuesWith(pair)
      .entryTtl(Duration. ofSeconds ( 30 )) // 设置默认超过期时间是 30
      .disableCachingNullValues();
       
      // 初始化 RedisCacheManager
      return new RedisCacheManager(redisCacheWriter, defaultCacheConfig);
      }
    5. 使用注解即可
      1. 开启缓存@EnableCaching
      2. 在相应方法上添加注解
        1. @Cacheable(cacheNames = "statuschecker")
        2. public Person request( int id){
          1. System. out .println( "Cache 未命中 " );
          2. return new Person( "www" , 24 );
        3. }
13.SpringData统一数据库交互
13.Springboot整合线程池
  1. 添加线程池bean
  2. @Bean
    public TaskExecutor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    // 设置核心线程数
    executor.setCorePoolSize( 5 );
    // 设置最大线程数
    executor.setMaxPoolSize( 10 );
    // 设置队列容量
    executor.setQueueCapacity( 20 );
    // 设置线程活跃时间(秒)
    executor.setKeepAliveSeconds( 60 );
    // 设置默认线程名称
    executor.setThreadNamePrefix( "hello-" );
    // 设置拒绝策略
    executor.setRejectedExecutionHandler( new ThreadPoolExecutor.CallerRunsPolicy());
    // 等待所有任务结束后再关闭线程池
    executor.setWaitForTasksToCompleteOnShutdown( true );
    return executor;
    }
  3. 开启异步调用
    1. @Configuration
    2. @EnableAsync
    3. public class BeanConfig {
  4. 在需要异步调用的方法添加注解
    1. @Async( "taskExecutor")//里面的字符串表示使用哪个线程池
    2. public List<Student> queryStudentByPage(){
  5. 使用异步调用
  6. @SpringBootApplication
    @MapperScan ( "com.njupt.mybatis.mappers" )
    public class MybatisApplication implements CommandLineRunner {
    @Autowired
    private MyService myService ;
           @Autowired
    private ThreadPoolTaskExecutor taskExecutor ;
    public static void main(String[] args) {
    SpringApplication. run (MybatisApplication. class , args);
     
    }
     
    @Override
    public void run(String... args) throws Exception {
    System. out .println( " 主线程 : " +Thread. currentThread ().getName());
    System. out .println( "hahah" );
    myService .queryStudentByPage();
    System. out .println( " 主线程结束 " );
    taskExecutor .shutdown()//虽然我们关闭了线程池,但是线程池还是会把任务执行完毕在关掉
    }
    }
  7. 注意事项
    1. @SpringbootTest修饰的类,主线程停止,子线程也会停止,因为 Juint跑完主线程的逻辑后就把整个JVM都关掉了
14.Springboot整合RabbitMQ
  1. 引入依赖
  2. <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-amqp</artifactId>
    </dependency>

     

  3. 自定义消息转换器
  4. public class MyMessageConvert implements MessageConverter {
        @Override
        public Message toMessage(Object o, MessageProperties messageProperties) throws                             MessageConversionException {
            messageProperties.setContentType("application/json");
            messageProperties.setDeliveryMode(MessageDeliveryMode.PERSISTENT);
            Message message=null;
            try {
                message = new Message(o.toString().getBytes("UTF-8"),messageProperties);
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            return message;
        }
    
        @Override
        public Object fromMessage(Message message) throws MessageConversionException {
            return null;
        }
    }

     

  5. 配置Properties
  6. spring:
    myrabbitmq :
    host : 192.168.0.104
    port : 5672
    username : guest
    password : guest
    virtual-host : /
    channel-cache-size : 10
    channel-time-out : 1000
     
    @ConfigurationProperties (prefix = "spring.myrabbitmq" )
    public class RabbitMQProperties {
    private String host ;
    private int port ;
    private String username ;
    private String password ;
    private String virtualHost ;
    private int channelCacheSize ;
    private Long channelTimeOut ;
  7. 配置bean
  8. @Configuration
    @EnableConfigurationProperties({RabbitMQProperties.class})
    public class RabbitMQAutoConfig {
    
        @Autowired
        RabbitMQProperties rabbitMQProperties;
        @Bean("connectionFactory")
        public ConnectionFactory connectionFactory() {
            CachingConnectionFactory connectionFactory = new CachingConnectionFactory(rabbitMQProperties.getHost(), rabbitMQProperties.getPort());
            connectionFactory.setUsername(rabbitMQProperties.getUsername());
            connectionFactory.setPassword(rabbitMQProperties.getPassword());
            connectionFactory.setVirtualHost(rabbitMQProperties.getVirtualHost());
            connectionFactory.setCacheMode(CachingConnectionFactory.CacheMode.CHANNEL);
            connectionFactory.setChannelCacheSize(rabbitMQProperties.getChannelCacheSize());
            connectionFactory.setChannelCheckoutTimeout(rabbitMQProperties.getChannelTimeOut());
            return connectionFactory;
        }
        @Bean
        public RabbitAdmin rabbitAdmin(@Qualifier("connectionFactory") ConnectionFactory connectionFactory){
            RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
            TopicExchange topicExchange = new TopicExchange("topic",true,false,null);
            rabbitAdmin.declareExchange(topicExchange);
            Queue queue = new Queue("queue",true,false,false,null);
            rabbitAdmin.declareQueue(queue);
            Binding binding = new Binding("queue", Binding.DestinationType.QUEUE,"topic","aha",null);
            rabbitAdmin.declareBinding(binding);
            return rabbitAdmin;
        }
        @Bean
        public RabbitTemplate rabbitTemplate(@Qualifier("connectionFactory") ConnectionFactory connectionFactory) {
            RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
            rabbitTemplate.setMessageConverter(new MyMessageConvert());
            return  rabbitTemplate;
        }
    }

     

  9. 使用
  10. @Override
    public void run(String... args) throws Exception {
        rabbitTemplate.convertAndSend("topic","aha",new String("Hello World"));
        connectionFactory.destroy();//如果不销毁ConnectionFactory,那么Connection不会断开,Springboot项目会一直委会这该Connection,导致项目运行无法结束。
    
    }

     

14.自定义启动器
  1. 新建maven工程yahang-spring-boot-starter (starter是一个空JAR包,仅仅作为maven下载jar包的启动器)
  2. 新建maven工程yahang-spring-boot-starter-autoconfigure (实际工作的模块)
  3. yahang-spring-boot-starter作为一个启动器,设置依赖于yahang-spring-boot-starter-autoconfigure
  4.     <dependency>
           <groupId>com.njupt</groupId>
           <artifactId>yahang-spring-boot-starter-autoconfigure</artifactId>
           <version>0.0.1-SNAPSHOT</version>
        </dependency>

     

  5. yahang-spring-boot-starter-autoconfigure模块下,设置依赖于spring-boot-starter
  6.      <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter</artifactId>
             <version>2.3.0.RELEASE</version>
         </dependency>

     

  7. yahang-spring-boot-starter-autoconfigure模块下,新建包com.njupt,然后新建一个实体类,该实体类为要配置为bean的类
    1. public class MyDataSource {
    2.     public String url;
    3.     public String username;
    4.     public String password;
    5.     public MyDataSource(String url, String username, String password) {
    6.         super();
    7.         this. url = url;
    8.         this. username = username;
    9.         this. password = password;
    10.     }  
    11. }
  8. yahang-spring-boot-starter-autoconfigure模块下的com.njupt包下,然后新建一个MyDataSourceProperties类,该实体类为读取yml文件的类,并设置getter,setter方法。
    1. @ConfigurationProperties(prefix = "yahang.mydatasource")
    2. public class MyDataSourceProperties {
    3.     private String url;
    4.     private String username;
    5.     private String password;
  9. yahang-spring-boot-starter-autoconfigure模块下的com.njupt包下,然后新建一个MyDataSourceAutoConfigure类,该类使用MyDataSourceProperties对象的属性,new MyDataSource对象,并注入为Bean
    1. @Configuration
    2. @ConditionalOnWebApplication
    3. @EnableConfigurationProperties(MyDataSourceProperties. class)
    4. public class MyDataSourceAutoConfigure {
    5.    
    6.     @Autowired
    7.     private MyDataSourceProperties myDataSourceProperties;
    8.    
    9.     @ Bean
    10.     public MyDataSource getDataSource() {
    11.         String url= myDataSourceProperties.getUrl();
    12.         String username= myDataSourceProperties.getUsername();
    13.         String password= myDataSourceProperties.getPassword();
    14.         return new MyDataSource( url, username, password);
    15.     }
    16. }
  10. 为了让Springboot加载MyDataSourceAutoConfigure,需要在resources目录下新建META-INF/spring.factories
    1. org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
    2. com.njupt.MyDataSourceAutoConfigure
  11. 使用maven install 安装autoconfigure和starter模块。
  12. 测试
            < dependency >
              < groupId >com.njupt </ groupId >
              < artifactId >yahang-spring-boot-starter </ artifactId >
              < version >0.0.1-SNAPSHOT </ version >
              </ dependency >
    1. 新建Springboot的web应用,pom文件引入自定义的starter
    2. 编写application.yml
      1. yahang:
      2.   mydatasource:
      3.     url: localhaost
      4.     username: yahang
      5.     password: 123456
    3. 编写测试代码
      1. @Controller
      2. public class MyController {
      3.    
      4.     @Autowired
      5.     private MyDataSource dataSource;
      6.     @ResponseBody
      7.     @RequestMapping( "/test")
      8.     public String getDatasource() {
      9.         return dataSource. url+ " : "+ dataSource. username+ " : "+ dataSource. password;
      10.     }
      11. }
    4. 测试
15.SpringBoot对事务的支持
  1. 使用事务的步骤
    1. 第一步在启动类上开启事务
      1. 提示:@EnableTransactionManagement注解其实在大多数情况下,不是必须的,因为SpringBoot在TransactionAutoConfiguration类里为我们自动配置启用了@EnableTransactionManagement注解。不过自动启用该注解有两个前提条件,分别是:@ConditionalOnBean(PlatformTransactionManager.class)和@ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class),而一般情况下,这两个条件都是满足的,所以一般的,我们在启动类上写不写@EnableTransactionManagement都行。
    2. 在相关方法上使用注解
  2. Transactional注解常用属性
    1. isolation:隔离级别,默认值采用DEFAULT
    2. propagation:传播行为,默认值采用REQUIRED
    3. timeout:事务超时时间,默认为-1.即永不超时,如果超时,就回滚事务
    4. readOnly:只读事务,默认false
    5. rollbackFor: 用于指定能够触发事务回滚的异常类型,如果有多个异常类型需要指定,各类型之间可以通过逗号分隔。{xxx1.class, xxx2.class,……}
    6. noRollbackFor: 出 no-rollback-for 指定的异常类型,不回滚事务。{xxx1.class, xxx2.class,……}
  3. 事务的传播行为
    1. TransactionDefinition.PROPAGATION_REQUIRED:如果当前存在事务,则加入该事务;如果当前没有事务,则创建一个新的事务。这是默认值。
    2. TransactionDefinition.PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,则把当前事务挂起。
    3. TransactionDefinition.PROPAGATION_SUPPORTS:如果当前存在事务,则加入该事务;如果当前没有事务,则以非事务的方式继续运行。
    4. TransactionDefinition.PROPAGATION_NOT_SUPPORTED:以非事务方式运行,如果当前存在事务,则把当前事务挂起。
    5. TransactionDefinition.PROPAGATION_NEVER:以非事务方式运行,如果当前存在事务,则抛出异常。
    6. TransactionDefinition.PROPAGATION_MANDATORY:如果当前存在事务,则加入该事务;如果当前没有事务,则抛出异常。
    7. TransactionDefinition.PROPAGATION_NESTED:如果当前存在事务,则创建一个事务作为当前事务的嵌套事务来运行;如果当前没有事务,则该取值等价于TransactionDefinition.PROPAGATION_REQUIRED。
  4. 注意事项
    1. service实现类(一般不建议在接口上)上添加@Transactional,可以将整个类纳入spring事务管理,在每个业务方法执行时都会开启一个事务,这些事务采用相同的管理方式。
    2. Transactional 注解只能应用到 public 可见度的方法上。 如果应用在protected、private或者 package可见度的方法上,也不会报错,不过事务设置不会起作用。
    3. 默认情况下,Transactional 注解的事物所管理的方法中,如果方法抛出运行时异常或error,那么会进行事务回滚;如果方法抛出的是非运行时异常,那么不会回滚。
      1. SQL异常属于检查异常(有的框架将SQL异常重写为了运行时异常),但是有时我们写SQL时,检查异常并不会提示;而默认情况下,事物对检查异常不会作出回滚处理。
      2. 在很多时候,我们除了catch一般的异常或自定义异常外,我们还习惯于catch住Exception异常;然后再抛出Exception异常。但是Exception异常属于非运行时异常(即:检查异常),因为默认是运行时异常时事物才进行回滚,那么这种情况下,是不会回滚的。我们可以在@Transacional注解中,通过rollbackFor = {Exception.class} 来解决这个问题。即:设置当Exception异常或Exception的所有任意子类异常时事物会进行回滚。
    1. 被catch处理了的异常,不会被事物作为判断依据;如果异常被catch 了,但是又在catch中抛出了新的异常,那么事物会以这个新的异常作 为是否进行回滚的判断依据。
 
 
 
 
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值