Spring Boot相关

Documentation

resources文件夹中目录结构

  • static:保存所有的静态资源,如:js css images
  • templates:保存所有的模板页面(Spring Boot默认jar包使用嵌入式的Tomcat,默认不支持JSP页面),可以使用模板引擎(freemarker、thymeleaf)
  • application.yml/application.properties:Spring Boot应用的配置文件,可以修改一些默认设置

YAML语法
基本语法

  • k:(空格)v:表示一对键值对(空格必须有),以空格的缩进来控制层级关系,只要是左对齐的一列数据,都是同一个层级的,属性和值大小写敏感

值的写法

  • 字符串默认不用加上单引号或者双引号
  • "":双引号;不会转义字符串里面的特殊字符,特殊字符会作为本身想表示的意思name: "zhangsan \n lisi",输出;zhangsan 换行 lisi
  • '':单引号;会转义特殊字符,特殊字符最终只是一个普通的字符串数据name: ‘zhangsan \n lisi’,输出;zhangsan \n lisi

@Value和@ConfigurationProperties获取配置文件中的值比较

@Component
@ConfigurationProperties(prefix = "person")
@Validated
public class Person {
    //@Email
    //@Value("${person.last‐name}")
    private String lastName;
    //@Value("#{11*2}")
    private Integer age;
    //@Value("true")
    private Boolean boss;

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

@PropertySource&@ImportResource&@Bean

@PropertySource:加载指定的配置文件

@PropertySource(value = {"classpath:person.properties"})
@Component
public class Person {
    private String lastName;
    private Integer age;
}

@ImportResource:导入Spring的配置文件,让配置文件里面的内容生效

//导入Spring的配置文件让其生效
@ImportResource(locations = {"classpath:beans.xml"})

配置类@Configuration(相当于Spring配置文件)
使用@Bean给容器中添加组件

/**
 * @Configuration:指明当前类是一个配置类,替代Spring配置文件
 */
@Configuration
public class MyAppConfig {
    //将方法的返回值添加到容器中;容器中这个组件默认的id就是方法名
    @Bean
    public HelloService helloService(){
        System.out.println("配置类@Bean给容器中添加组件了...");
        return new HelloService();
    }
}

配置文件占位符

person.name=${random.uuid}
person.age=${random.int}
person.dog.name=${person.name}_dog

yml多文档块

server:
  port: 8081
spring:
  profiles:
    active: prod
‐‐‐
server:
  port: 8083
spring:
  profiles: dev
‐‐‐
server:
  port: 8084
spring:
  profiles: prod  #指定属于哪个环境

配置文件加载位置
springboot启动会扫描以下位置的application.properties或者application.yml文件作为Spring boot的默认配置文件

  • –file:./config/
  • –file:./
  • –classpath:/config/
  • –classpath:/

优先级由高到底,高优先级的配置会覆盖低优先级的配置
SpringBoot会从这四个位置全部加载主配置文件,互补配置
通过spring.config.location改变默认的配置文件位置

SLF4j使用

http://www.slf4j.org/

SLF4J user manual

legacy APIs

Hello World

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");
  }
}
//日志的级别,由低到高
logger.trace("这是trace日志...");        
logger.debug("这是debug日志...");        
//SpringBoot默认给我们使用的是info级别的,没有指定级别的就用SpringBoot默认规定的级别
logger.info("这是info日志...");        
logger.warn("这是warn日志...");        
logger.error("这是error日志...");
日志输出格式:
%d表示日期时间        
%thread表示线程名       
%‐5level:级别从左显示5个字符宽度        
%logger{50} 表示logger名字最长50个字符,否则按照句点分割        
%msg:日志消息       
%n是换行符 
例: %d{yyyy‐MM‐dd HH:mm:ss.SSS} [%thread] %‐5level %logger{50} ‐ %msg%n

 SpringBoot修改日志的默认配置

logging.level.com.atguigu=trace

# 不指定路径在当前项目下生成springboot.log日志(指定目录)
logging.path=

# 可以指定完整的路径(指定文件名)
logging.file=G:/springboot.log

# 在当前磁盘的根路径下创建spring文件夹和里面的log文件夹,使用 spring.log 作为默认文件
logging.path=/spring/log

# 在控制台输出的日志的格式
logging.pattern.console=%d{yyyy‐MM‐dd} [%thread] %‐5level %logger{50} ‐ %msg%n

#指定文件中日志输出的格式
logging.pattern.file=%d{yyyy‐MM‐dd} - [%thread] - %‐5level - %logger{50} - %msg%n

Binding with a logging framework at deployment time

Bridging legacy APIs

 

如何让系统中所有的日志都统一到slf4j

  • 将系统中其他日志框架先排除出去
  • 用中间包来替换原有的日志框架
  • 我们导入slf4j其他的实现

SpringBoot能自动适配所有的日志,底层使用slf4j+logback记录日志,引入其他框架的时候,需要把这个框架依赖的日志框架排除掉

Servlet、Filter、Listener

ServletRegistrationBean
 

@Bean
public ServletRegistrationBean myServlet(){
    ServletRegistrationBean registrationBean = new ServletRegistrationBean(new MyServlet(),"/myServlet");
    return registrationBean;
}

FilterRegistrationBean

@Bean
public FilterRegistrationBean myFilter(){
    FilterRegistrationBean registrationBean = new FilterRegistrationBean();
    registrationBean.setFilter(new MyFilter());
    registrationBean.setUrlPatterns(Arrays.asList("/hello","/myServlet"));
    return registrationBean;
}

ServletListenerRegistrationBean

@Bean
public ServletListenerRegistrationBean myListener(){
    ServletListenerRegistrationBean<MyListener> registrationBean = new
ServletListenerRegistrationBean<>(new MyListener());
    return registrationBean;
}

数据访问
JDBC

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
</dependency>
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://localhost:3306/jdbc
    driver‐class‐name: com.mysql.jdbc.Driver

 Druid

<!--引入druid数据源-->
<!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.1.8</version>
</dependency>
spring:
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.32.22:3306/jdbc
    driver-class-name: com.mysql.jdbc.Driver
    type: com.alibaba.druid.pool.DruidDataSource
#   以下用配置文件配置
    initialSize: 5
    minIdle: 5
    maxActive: 20
    maxWait: 60000
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: SELECT 1 FROM DUAL
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
#   配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    filters: stat,wall,log4j
    maxPoolPreparedStatementPerConnectionSize: 20
    useGlobalDataSourceStat: true
    connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
@Configuration
public class DruidConfig {
    @ConfigurationProperties(prefix = "spring.datasource")
    @Bean
    public DataSource druid(){
        return  new DruidDataSource();
    }
    //配置Druid的监控
    //1、配置一个管理后台的Servlet
    @Bean
    public ServletRegistrationBean statViewServlet(){
        ServletRegistrationBean bean = new ServletRegistrationBean(new StatViewServlet(),"/druid/*");
        Map<String,String> initParams = new HashMap<>();
        initParams.put("loginUsername","admin");
        initParams.put("loginPassword","123456");
        initParams.put("allow","");//默认就是允许所有访问
        initParams.put("deny","192.168.32.22");
        bean.setInitParameters(initParams);
        return bean;
    }
    //2、配置一个web监控的filter
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
        bean.setFilter(new WebStatFilter());
        Map<String,String> initParams = new HashMap<>();
        initParams.put("exclusions","*.js,*.css,/druid/*");
        bean.setInitParameters(initParams);
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
}

整合MyBatis

http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/

<dependency>        
    <groupId>org.mybatis.spring.boot</groupId>            
    <artifactId>mybatis‐spring‐boot‐starter</artifactId>            
    <version>1.3.1</version>            
</dependency>
@Configuration
public class MyBatisConfig {
    @Bean
    public ConfigurationCustomizer configurationCustomizer(){
        return new ConfigurationCustomizer(){
            @Override
            public void customize(Configuration configuration) {
                //映射下划线命名To驼峰命名
                configuration.setMapUnderscoreToCamelCase(true);
            }
        };
    }
}

mybatis:
  # 指定全局配置文件位置
  config-location: classpath:mybatis/mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
</configuration>
//使用MapperScan批量扫描所有的Mapper接口
@MapperScan("com.demo.springboot.mapper")
@SpringBootApplication
    public class SpringBootApplication {
    public static void main(String[] args) {    
    SpringApplication.run(SpringBootApplication.class, args);        
    }    
}

 注解使用


//@Mapper  全局配置了
public interface DepartmentMapper {
    @Select("select * from department where id=#{id}")
    public Department getDeptById(Integer id);
    @Delete("delete from department where id=#{id}")
    public int deleteDeptById(Integer id);
    @Options(useGeneratedKeys = true,keyProperty = "id")
    @Insert("insert into department(departmentName) values(#{departmentName})")
    public int insertDept(Department department);
    @Update("update department set departmentName=#{departmentName} where id=#{id}")
    public int updateDept(Department department);
}

配置文件使用

mybatis:
  # 指定全局配置文件位置
  config-location: classpath:mybatis/mybatis-config.xml
  # 指定sql映射文件位置
  mapper-locations: classpath:mybatis/mapper/*.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.demo.springboot.mapper.EmployeeMapper">
    <select id="getEmpById" resultType="com.demo.springboot.bean.Employee">
        SELECT * FROM employee WHERE id=#{id}
    </select>
    <insert id="insertEmp">
        INSERT INTO employee(lastName,email,gender) VALUES (#{lastName},#{email},#{gender})
    </insert>
</mapper>

整合SpringData JPA

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
spring:
  datasource:
    url: jdbc:mysql://192.168.32.22/jpa
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
  jpa:
    hibernate:
#   更新或者创建数据表结构
        ddl-auto: update
#   控制台显示SQL
    show-sql: true
//使用JPA注解配置映射关系
@Entity //告诉JPA这是一个实体类(和数据表映射的类)
@Table(name = "tbl_user") //@Table来指定和哪个数据表对应;如果省略默认表名就是user;
public class User {
    @Id //这是一个主键
    @GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键
    private Integer id;
    @Column(name = "last_name",length = 50) //这是和数据表对应的一个列
    private String lastName;
    @Column //省略默认列名就是属性名
    private String email;
}
//继承JpaRepository来完成对数据库的操作
public interface UserRepository extends JpaRepository<User,Integer> {
    //继承就有可用的操作,<User,Integer>
}

Spring Boot与缓存

  • CachingProvider 创建、配置、获取、管理和控制多个CacheManager。一个应用可以在运行期访问多个CachingProvider。
  • CacheManager 创建、配置、获取、管理和控制多个唯一命名的Cache,这些Cache存在于CacheManager的上下文中。一个CacheManager仅被一个CachingProvider所拥有。
  • Cache 是一个类似Map的数据结构并临时存储以Key为索引的值。一个Cache仅被一个CacheManager所拥有。
  • Entry 是一个存储在Cache中的key-value对。
  • Expiry 每一个存储在Cache中的条目有一个定义的有效期。一旦超过这个时间,条目为过期的状态。一旦过期,条目将不可访问、更新和删除。缓存有效期可以通过ExpiryPolicy设置。

Cache

缓存接口,定义缓存操作。实现有:RedisCache、EhCacheCache、ConcurrentMapCache等

CacheManager

缓存管理器,管理各种缓存(Cache)组件

@Cacheable

主要针对方法配置,能够根据方法的请求参数对其结果进行缓存

@CacheEvict

清空缓存

@CachePut

保证方法被调用,又希望结果被缓存。

@EnableCaching

开启基于注解的缓存

keyGenerator

缓存数据时key生成策略

serialize

缓存数据时value序列化策略

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-cache</artifactId>
</dependency>
@MapperScan("com.demo.cache.mapper")
@SpringBootApplication
@EnableCaching //开启基于注解的缓存
public class SpringbootApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringbootApplication.class, args);
    }
}
@Configuration
public class MyCacheConfig {
    @Bean("myKeyGenerator")
    public KeyGenerator keyGenerator(){
        return new KeyGenerator(){
            @Override
            public Object generate(Object target, Method method, Object... params) {
                return method.getName()+"["+ Arrays.asList(params).toString()+"]";
            }
        };
    }
}
@CacheConfig(cacheNames="emp"/*,cacheManager = "employeeCacheManager"*/) //抽取缓存的公共配置
@Service
public class EmployeeService {

    @Autowired
    EmployeeMapper employeeMapper;



    /**
     *   @Cacheable
     *      cacheNames/value:指定缓存组件的名字,将方法的返回结果放在哪个缓存中,是数组的方式,可以指定多个缓存
     *      key:缓存数据使用的key,可以用它来指定。默认是使用方法参数的值
     *      keyGenerator:key的生成器,可以自己指定key的生成器的组件id
     *      key/keyGenerator:二选一使用
     *      cacheManager:指定缓存管理器,或者cacheResolver指定获取解析器
     *      condition:指定符合条件的情况下才缓存,condition = "#id>0",condition = "#a0>1":第一个参数的值>1的时候才进行缓存
     *      unless:否定缓存,当unless指定的条件为true,方法的返回值就不会被缓存,可以获取到结果进行判断,unless = "#a0==2":如果第一个参数的值是2,结果不缓存;
     *      sync:是否使用异步模式
     */
    @Cacheable(value = {"emp"},keyGenerator = "myKeyGenerator",condition = "#a0>1",unless = "#a0==2")
    public Employee getEmp(Integer id){
        Employee emp = employeeMapper.getEmpById(id);
        return emp;
    }



    /**
     * @CachePut:既调用方法,又更新缓存数据
     */
    @CachePut(/*value = "emp",*/key = "#result.id")
    public Employee updateEmp(Employee employee){
        employeeMapper.updateEmp(employee);
        return employee;
    }



    /**
     * @CacheEvict:缓存清除
     *  key:指定要清除的数据
     *  allEntries = true:指定清除这个缓存中所有的数据
     *  beforeInvocation = false:缓存的清除是否在方法之前执行,默认代表缓存清除操作是在方法执行之后执行,如果出现异常缓存就不会清除
     *  beforeInvocation = true:代表清除缓存操作是在方法运行之前执行,无论方法是否出现异常,缓存都清除
     */
    @CacheEvict(value="emp",beforeInvocation = true/*key = "#id",*/)
    public void deleteEmp(Integer id){
        employeeMapper.deleteEmpById(id);
    }



    /**
     * @Caching 定义复杂的缓存规则
     */
    @Caching(
         cacheable = {
             @Cacheable(/*value="emp",*/key = "#lastName")
         },
         put = {
             @CachePut(/*value="emp",*/key = "#result.id"),
             @CachePut(/*value="emp",*/key = "#result.email")
         }
    )
    public Employee getEmpByLastName(String lastName){
        return employeeMapper.getEmpByLastName(lastName);
    }
}
发布了43 篇原创文章 · 获赞 12 · 访问量 9876

猜你喜欢

转载自blog.csdn.net/OrangeHap/article/details/103113327
今日推荐