SpringBoot常用配置類大全

SpringBoot常用配置類大全

【结合源码看注解】

@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}
)}
)@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
SpringBootConfiguration:标注springboot 配置类
    
  SpringBootConfiguration:标注springboot 配置类 
    
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Configuration
    底层是Configuration: spring 标注配置类的 一开始是做配置文件,有些配置文件就写成配置类 通过改注解告诉程序这个一个配置类,而Configruation 
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component  

@EnableAutoConfiguration 开启自动配置包注解
@AutoConfigurationPackage下的注解 也有import
@AutoConfigurationPackage下的注解 也有import

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@Import({Registrar.class})
导入的组件由Registrar.class
这个Import真正意义是去扫描springboot中 SpringbootApplication标注的类 下的所以组件到spring容器中
    static class Registrar implements ImportBeanDefinitionRegistrar, DeterminableImports {
        Registrar() {
        }

        public void registerBeanDefinitions(AnnotationMetadata metadata, BeanDefinitionRegistry registry) {
            AutoConfigurationPackages.register(registry, (new AutoConfigurationPackages.PackageImport(metadata)).getPackageName());
        }
真正意义是去扫描springboot中 SpringbootApplication标注的类 下的所以组件到spring容器中
所以编写springboot项目的时候,SpingbootApplication 标注的类一定在所有包,类之外
@import
@Import({AutoConfigurationImportSelector.class})
这给imoprt 是说明要导入那些组件
    
    //将需要导入的组件以全类名返回,就会添加到容器
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        if (!this.isEnabled(annotationMetadata)) {
            return NO_IMPORTS;
        } else {
            AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
            AnnotationAttributes attributes = this.getAttributes(annotationMetadata);
            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 StringUtils.toStringArray(configurations);
        }
    }  
    这给String所返回的数据就是 给spring容器导入的xxxAutoConfiguration 自动配置类
    给容器中这个场景所需要的所有组件,并配置号这些组件,有了这些配置,就不用手动比那些配置和组件
      getCandidateConfigurations 中
        SpringFactoriesLoader.loadFactoryNames(this.getSpringFactoriesLoaderFactoryClass(), this.getBeanClassLoader());
第一给参数:EnableAutoConfiguration.class;  开启的配置类
第二个参数:ClassLoader; 类加载器  获取到资源 把资源作为一个proertise 
    
    SpringBoot在启动时候从类路径下META-INFO/spring.factorise中获取EnableConfigration 指定的值,将这些值自动配置类导入到容器中,自动配置类就生效,帮我们进行自动配置,以前需要自动配置的类,自动配置都做了

    springboot 都帮我们整合了:javaee自动整合和配置都在 spring-boot-aotoConfigure:...Release

Spring Boot属性配置文件详解

相信很多人选择Spring Boot主要是考虑到它既能兼顾Spring的强大功能,还能实现快速开发的便捷。我们在Spring Boot使用过程中,最直观的感受就是没有了原来自己整合Spring应用时繁多的XML配置内容,替代它的是在pom.xml中引入模块化的Starter POMs,其中各个模块都有自己的默认配置,所以如果不是特殊应用场景,就只需要在application.properties中完成一些属性配置就能开启各模块的应用。

在之前的各篇文章中都有提及关于application.properties的使用,主要用来配置数据库连接、日志相关配置等。除了这些配置内容之外,本文将具体介绍一些在application.properties配置中的其他特性和使用方法。

自定义属性与加载

我们在使用Spring Boot的时候,通常也需要定义一些自己使用的属性,我们可以如下方式直接定义:

com.didispace.blog.name=程序猿DDcom.didispace.blog.title=Spring Boot教程

然后通过@Value("${属性名}")注解来加载对应的配置属性,具体如下:

@Componentpublic class BlogProperties {    @Value("${com.didispace.blog.name}")    private String name;    @Value("${com.didispace.blog.title}")    private String title;    // 省略getter和setter}

按照惯例,通过单元测试来验证BlogProperties中的属性是否已经根据配置文件加载了。

@RunWith(SpringJUnit4ClassRunner.class)@SpringApplicationConfiguration(Application.class)public class ApplicationTests {	@Autowired	private BlogProperties blogProperties;	@Test	public void getHello() throws Exception {		Assert.assertEquals(blogProperties.getName(), "程序猿DD");		Assert.assertEquals(blogProperties.getTitle(), "Spring Boot教程");	}}

参数间的引用

application.properties中的各个参数之间也可以直接引用来使用,就像下面的设置:

com.didispace.blog.name=程序猿DDcom.didispace.blog.title=Spring Boot教程com.didispace.blog.desc=${com.didispace.blog.name}正在努力写《${com.didispace.blog.title}》

com.didispace.blog.desc参数引用了上文中定义的nametitle属性,最后该属性的值就是程序猿DD正在努力写《Spring Boot教程》

使用随机数

在一些情况下,有些参数我们需要希望它不是一个固定的值,比如密钥、服务端口等。Spring Boot的属性配置文件中可以通过${random}来产生int值、long值或者string字符串,来支持属性的随机值。

# 随机字符串com.didispace.blog.value=${random.value}# 随机intcom.didispace.blog.number=${random.int}# 随机longcom.didispace.blog.bignumber=${random.long}# 10以内的随机数com.didispace.blog.test1=${random.int(10)}# 10-20的随机数com.didispace.blog.test2=${random.int[10,20]}

通过命令行设置属性值

相信使用过一段时间Spring Boot的用户,一定知道这条命令:java -jar xxx.jar --server.port=8888,通过使用–server.port属性来设置xxx.jar应用的端口为8888。

在命令行运行时,连续的两个减号--就是对application.properties中的属性值进行赋值的标识。所以,java -jar xxx.jar --server.port=8888命令,等价于我们在application.properties中添加属性server.port=8888,该设置在样例工程中可见,读者可通过删除该值或使用命令行来设置该值来验证。

通过命令行来修改属性值固然提供了不错的便利性,但是通过命令行就能更改应用运行的参数,那岂不是很不安全?是的,所以Spring Boot也贴心的提供了屏蔽命令行访问属性的设置,只需要这句设置就能屏蔽:SpringApplication.setAddCommandLineProperties(false)

多环境配置

我们在开发Spring Boot应用时,通常同一套程序会被应用和安装到几个不同的环境,比如:开发、测试、生产等。其中每个环境的数据库地址、服务器端口等等配置都会不同,如果在为不同环境打包时都要频繁修改配置文件的话,那必将是个非常繁琐且容易发生错误的事。

对于多环境的配置,各种项目构建工具或是框架的基本思路是一致的,通过配置多份不同环境的配置文件,再通过打包命令指定需要打包的内容之后进行区分打包,Spring Boot也不例外,或者说更加简单。

在Spring Boot中多环境配置文件名需要满足application-{profile}.properties的格式,其中{profile}对应你的环境标识,比如:

  • application-dev.properties:开发环境
  • application-test.properties:测试环境
  • application-prod.properties:生产环境

至于哪个具体的配置文件会被加载,需要在application.properties文件中通过spring.profiles.active属性来设置,其值对应{profile}值。

如:spring.profiles.active=test就会加载application-test.properties配置文件内容

下面,以不同环境配置不同的服务端口为例,进行样例实验。

  • 针对各环境新建不同的配置文件application-dev.propertiesapplication-test.propertiesapplication-prod.properties
  • 在这三个文件均都设置不同的server.port属性,如:dev环境设置为1111,test环境设置为2222,prod环境设置为3333
  • application.properties中设置spring.profiles.active=dev,就是说默认以dev环境设置
  • 测试不同配置的加载
    • 执行java -jar xxx.jar,可以观察到服务端口被设置为1111,也就是默认的开发环境(dev)
    • 执行java -jar xxx.jar --spring.profiles.active=test,可以观察到服务端口被设置为2222,也就是测试环境的配置(test)
    • 执行java -jar xxx.jar --spring.profiles.active=prod,可以观察到服务端口被设置为3333,也就是生产环境的配置(prod)

按照上面的实验,可以如下总结多环境的配置思路:

  • application.properties中配置通用内容,并设置spring.profiles.active=dev,以开发环境为默认配置
  • application-{profile}.properties中配置各个环境不同的内容
  • 通过命令行方式去激活不同环境的配置
springBoot 中自定義全局异常
@ControllerAdvice
public class GlobalException {

    /**
     * TODO  可以升华
     * 自定义全局异常
     *
     * @param ex
     * @return
     */
    @ExceptionHandler(Exception.class)
    @ResponseBody
    public ServerResponse globalHandle(Exception ex) {
        StringBuffer stringBuffer = new StringBuffer();
        /*MyGlobalException 为自定义异常 */
        if (ex instanceof MyGlobalException) {
            return ServerResponse.createByError(ex.getMessage());
        }
        //BindException  为检验的异常  
        if (ex instanceof BindException) {
            BindException bindException = (BindException) ex;
            List<ObjectError> allErrors = bindException.getAllErrors();
            for (ObjectError error : allErrors) {
                String defaultMessage = error.getDefaultMessage();

                stringBuffer.append(error.getDefaultMessage());
            }
            return ServerResponse.createByError(stringBuffer.toString());
        }

        return ServerResponse.createByError(ex.getMessage());
    }
}
自定义异常
继承 Excetion 类 实现自己的异常

public class MyGlobalException extends Exception {
    public MyGlobalException(String message) {
        super(message);
    }
}
拦截器的配置类
通過继承 HandlerInterceptor  实现其下的三个方法
public class UrlInterceptor implements HandlerInterceptor {

    private static final Logger logger = LoggerFactory.getLogger(UrlInterceptor.class);

    private static final String GET_ALL = "/gg";
    private static final String GET_HEADER = "/userjsonview";

    /**
     * 进入Controller层之前拦截请求,默认是拦截所有请求
     *
     * @param request
     * @param response
     * @param handler
     * @return 是否拦截当前请求,true表示拦截当前请求,false表示不拦截当前请求
     * @throws Exception 可能出现的异常
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        logger.info("go into preHandle.....");
        String requestURI = request.getRequestURI();
        logger.info(requestURI);
        if (requestURI.contains(GET_ALL)) {
            throw new MyGlobalException("没有权限");
        }
        if (requestURI.contains(GET_HEADER)) {
            response.sendRedirect("/login");
            return true;
        }
        return true;
    }

    /**
     * 处理完请求后但还未渲染试图之前进行的操作
     *
     * @param request
     * @param response
     * @param handler
     * @param modelAndView mv
     * @throws Exception E
     */

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

        logger.info("go into postHandle ...");

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        logger.info("go into afterCompletion ...");


        logger.info("ex: " + ex);

    }
    
    实现WebMvcConfigurer接口 在addInterceptors方法中
 
    
    

实现WebMvcConfigurer接口 的addInterceptors方法

   @Configuration
   //标注为sringboot的配置类

public class MvcConfig implements WebMvcConfigurer {
    /*UrlInterceptor
    将它注入到Sprig容器,交给spring管理
    * */
  /*  @Bean
    public UrlInterceptor urlInterceptor() {

        return new UrlInterceptor();
    }*/

    
    
    /*将UrlInterceptor注册到
    addInterceptor
    * */
   
    @Override
    public void addInterceptors(InterceptorRegistry registry) {

        /*
       addPathPatterns()  需要拦截的路径
       excludePathPatterns 不需要拦截的路径
       addInterceptor 返回的是InterceptorRegistration对象
        */
        registry.addInterceptor(new UrlInterceptor()).addPathPatterns("/**");

    }

    @Override
    public void configurePathMatch(PathMatchConfigurer configurer) {
        UrlPathHelper urlPathHelper = new UrlPathHelper();
        urlPathHelper.setRemoveSemicolonContent(false);
        configurer.setUrlPathHelper(urlPathHelper);

    }
    
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        /* 跨域设置‘
         * addMapping   跨域的映射地址
         * allowedOrigins : 允许跨域的请求源
         * allowedMethods: 允许跨域的方法
         * allowedHeaders :允许跨域的头部
         * allowCredentials : 设置允许cookie session...数据跨域
         * */
        registry.addMapping("/localhost:8080")
                .allowedMethods("/user/**")
                .allowedOrigins("/")
                .allowedHeaders("token")
                .allowCredentials(true);
    }
Swagger 接口文档 的配置

在pom中导入依赖


        <!--swagger 文档接口支持-->
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger-ui</artifactId>
            <version>2.9.0</version>
        </dependency>
        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>2.9.0</version>
        </dependency>

具体配置

@Configuration
@EnableSwagger2
public class SwaggerConfig {


    /**
     * 链式编程 来定制API样式 后续会加上分组信息
     */
    @Bean
    public Docket createSwagger() {
        HashSet<String> hashSet = new HashSet<>();
        hashSet.add("ContentType:Application");
                         //文档类型
        return new Docket(DocumentationType.SWAGGER_2)
        //自定义展示的信息)
        .apiInfo(MyApiInfo())
        // 启动api选择的生成器
         .select().
        //扫描com路径下的api文档
         .apis(RequestHandlerSelectors.basePackage("com"))
         .build();

    }
 // 用来创建该API的基本信息,展示在文档的页面中(自定义展示的信息)
    private ApiInfo MyApiInfo() {
     
        return new ApiInfoBuilder()
        //设置标题
        .title("swagger 测试文档 ")
        //接口描述
        .description("springboot Rest风格 接口测试")
        //设置开发人员一些信息
                .contact(new Contact("作者:hzy", "http//8080", "联系:                   1372265573@qq.com"))
                //设置版本
                .version("1.1").build();
    }

}
        
常用注解和
@Api(tags("改接口描述"))  标注 该类是swagger 文档接口 类
@ApiImplicitParams  加 ·s· 可以在里面的花括号写多个  @ApiImplicitParam 用逗号分隔
@ApiModel  标注实体类  在swagger中的那个实体 
......... 具体自己去看看
------------------------------------
@Controller
@Api(tags = "Usr 接口 ------")
public class indexController {

    // @RequestMapping(value = "/login",method = RequestMethod.GET)
    @PostMapping("/login")
    @ResponseBody
    @ApiImplicitParams({
            @ApiImplicitParam(name = "username", value = "用戶名稱", dataType = "String"),
            @ApiImplicitParam(name = "password", value = "密碼", dataType = "String")
    })
    public Map<String, String> login(String username, String password) {

        Map<String, String> loginMap = new HashMap<>();
        loginMap.put("用户名", username);
        loginMap.put("密码", password);
        loginMap.put("code", "200");
        loginMap.put("STATUS", "登录成功");
        return loginMap;
    }
springboot yml 基本配置
#服務其配置
server:
  port: 9000

    #servlet:
  # context-path: /book

#数据库相关配置
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    username: root
    password: root
    url: jdbc:mysql://localhost:3306/spring_bookssys?characterEncoding=utf8&amp&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT&useSSL=false

    # 数据源配置
    druid:
      # druid连接池监控
      stat-view-servlet:
        enabled: true
        url-pattern: /druid/*
        login-username: admin
        login-password: admin
        # 初始化时建立物理连接的个数
        initial-size: 5
        # 最大连接池数量
        max-active: 30
        # 最小连接池数量
        min-idle: 5
        # 获取连接时最大等待时间,单位毫秒
        max-wait: 60000
        # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
        time-between-eviction-runs-millis: 60000
        # 连接保持空闲而不被驱逐的最小时间
        min-evictable-idle-time-millis: 300000
        # 用来检测连接是否有效的sql,要求是一个查询语句
        validation-query: select count(*) from dual
        # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
        test-while-idle: true
        # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
        test-on-borrow: false
        # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
        test-on-return: false
        # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
        pool-prepared-statements: false
        # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。
        max-pool-prepared-statement-per-connection-size: 50
        # 配置监控统计拦截的filters,去掉后监控界面sql无法统计
        filters: stat,wall
        # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
        connection-properties:
          druid.stat.mergeSql: true
          druid.stat.slowSqlMillis: 500
        # 合并多个DruidDataSource的监控数据
        use-global-data-source-stat: true
        filter:
          stat:
            log-slow-sql: true
            slow-sql-millis: 1000
            merge-sql: true
          wall:
            config:
              multi-statement-allow: true


  #解析resources /静态资源
mvc:
  static-path-pattern: /**


#mybatis -plus 配置
#xml 扫描,多个目录用逗号或者分隔号(告Mapper所对应的xml 文件位置)
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true
    auto-mapping-behavior: full
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
  mapper-locations: classpath*:mapper/**/*Mapper.xml

configuration:
  # 是否开启自动驼峰命名规则映射:从数据库列名到Java属性驼峰命名的类似映射
  map-underscore-to-camel-case: true
  # 如果查询结果中包含空值的列,则 MyBatis 在映射的时候,不会映射这个字段
  call-setters-on-nulls: true
  # 这个配置会将执行的sql打印出来,在开发或测试的时候可以用
  log-impl: org.apache.ibatis.logging.stdout.StdOutImpl


debug: true


pom有关

 <!--阿里的数据库连接池支持-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.6</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.25</version>
        </dependency>
        
        
检验Validation 对实体类的一些字段做检验
    pom中依赖的导入
    
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
        </dependency>

使用測試:


      // 所有都验证
    @NotNull(message = "不能为空")
    private Integer id;

    // First 才验证
    @NotBlank(message = "字符串类型不能为空字符串(去除后面的空格后)")
    @NotNull(message = "对象不能为NULL", groups = {First.class})
     @Size(message = "字符串长度为[5-16]", min = 5, max = 16, groups = {Second.class})
    @Pattern(regexp = "[a-zA-z]*",message = "正则校验")
    private String username;

    // First 或 Second 才验证
    @NotBlank(message = "字符串类型不能为空字符串(去除后面的空格后)")
    @NotNull(message = "对象不能为NULL", groups = {First.class, Second.class})
    private String password;

    @NotNull(message = "对象不能为NULL", groups = {First.class})
    private Integer age;

    @NotEmpty(message = "字符串数组集合等不能为空,长度不能为零")
    @NotBlank(message = "字符串类型不能为空字符串(去除空格后)")
    @NotNull(message = "用户名不能为空")

在控制层使用注解 @Validated 来标注
    @PostMapping("/validated")
    public Teacher validated(@RequestBody @Validated Teacher teacher) {
        return teacher;
    }


Spring Aop切面
pom的导入
  <!--spring -->
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
        </dependency>
    

測試: 首先@Aspect 标注从哪儿去切 定义切面

@Aspect
@Component

//切面
public class AspectTest {
    //切点
    @Pointcut("execution(* spring.springboot.aspect.AspectTestConfig.*(..))")
    public void pointcut() {
    }

    @Before("pointcut()")
    public void before() {
        System.out.println("before :  前");
    }

    @After("pointcut()")
    public void after() {
        System.out.println("after :   后");
    }

    @AfterReturning("pointcut()")
    public void afterReturning() {
        System.out.println("afterReturning : 在最后一句代码结束的时候");
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing() {
        System.out.println("afterThrowing : 有异常出现的时候");
    }

    @Around("pointcut()")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        System.out.println("环绕前");
        proceedingJoinPoint.proceed();
        System.out.println("环绕后");
    }

}

和上面定义的异常来测试用

@Component
public class AspectTestConfig {

    public String aspectTest() throws MyGlobalException {

        System.out.println("A  Is Aspect-----");
        String t = null;
        if (t == null) {
            throw new MyGlobalException("aop测试异常");
        }
        return "return 值";
    }
}

定义控制层controller来测试


@RestController
@Api(tags = "aspect 切面测试")
public class AspectController {
    @Autowired
    AspectTestConfig aspectTestConfig;
    @ApiImplicitParam(value = "ONLY TEST  ", name = "AOP----的切面测试------")
    @GetMapping("/aspect")
    public String aspectController() throws MyGlobalException {

        return aspectTestConfig.aspectTest();
    }

}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值