`

Spring Boot自动配置

 
阅读更多

在上篇文章如何运行Spring Boot应用中,已经熟悉了如何通过maven或者gradle创建一个Spring Boot应用,这篇文章主要学习Spring Boot的自动配置,包括注解的使用以及一些配置约束等等。

关于Spring Boot的特性介绍,可以参考Spring Boot特性

主应用类

在Spring Boot应用中,我们通常将主应用类放置于应用的根包中,例如,com.javachen.example。主应用类有main方法,并且使用了@EnableAutoConfiguration注解,并暗地里定义了一个基础的包路径,Spring Boot会在该包路径来搜索类。例如,如果你正在编写一个JPA应用,被@EnableAutoConfiguration注解的类所在包将被用来搜索带有@Entity注解的实体类。

在主应用类上指定@ComponentScan,同样也隐式的指定了扫描时basePackage的路径。

如何运行Spring Boot应用中Application.java类声明了main方法,还使用了@EnableAutoConfiguration注解。

@RestController
@EnableAutoConfiguration
public class Application {
  @RequestMapping("/")
  String home() {
    return "Hello World!";
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }
}

说明:

  • @RestController@RequestMapping注解是Spring MVC注解,它们不是Spring Boot的特定部分,具体查看Spring参考文档的MVC章节。
  • @EnableAutoConfiguration这个注解告诉Spring Boot根据添加的jar依赖猜测你想如何配置Spring。由于spring-boot-starter-web添加了Tomcat和Spring MVC,所以auto-configuration将假定你正在开发一个web应用并相应地对Spring进行设置。

配置类

在该类上也可以使用@Configuration注解,用来对spring boot进行配置,当然,你也可以使用一个XML源来调用SpringApplication.run()进行配置。

标有@Configuration注解的类为配置类。你不需要将所有的@Configuration放进一个单独的类。@Import注解可以用来导入其他配置类。另外,你也可以使用@ComponentScan注解自动收集所有的Spring组件,包括@Configuration类。

如果你需要使用基于XML的配置,你可以在注有@Configuration的类上使用附加的@ImportResource注解加载XML配置文件。

你可以通过将@EnableAutoConfiguration@SpringBootApplication注解添加到一个@Configuration类上来选择自动配置。自动配置的意思是Spring Boot尝试根据你添加的jar依赖自动配置你的Spring应用。

如果需要找出当前应用了哪些自动配置及应用的原因,你可以使用--debug开关启动应用,这将会记录一个自动配置的报告并输出到控制台。

如果发现应用了你不想要的特定自动配置类,你可以使用@EnableAutoConfiguration注解的排除属性来禁用它们。

import org.springframework.boot.autoconfigure.*;
import org.springframework.boot.autoconfigure.jdbc.*;
import org.springframework.context.annotation.*;

@Configuration
@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class MyConfiguration {
}

总结,上面提到了几个注解,用途分别如下:

  • @Configuration。标注一个类为配置类。
  • @EnableAutoConfiguration。开启自动配置。
  • @SpringBootApplication。等价于以默认属性使用@Configuration@EnableAutoConfiguration@ComponentScan

如果启动类在根包下面,则你可以在该类上添加@ComponentScan注解而不需要添加任何参数,Spring Boot会在根包下面搜索注有@Component@Service@Repository,@Controller注解的所有类,并将他们注册为Spring Beans,否则,你需要在@ComponentScan注解上定义basePackages或者其他属性。

这样Application.java可以定义为:

package com.javachen.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Configuration
@ComponentScan
@EnableAutoConfiguration
public class Application {
  @RequestMapping("/")
  String home() {
    return "Hello World!";
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }
}

或者:

package com.javachen.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class Application {
  @RequestMapping("/")
  String home() {
    return "Hello World!";
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }
}

命令行参数

启动类可以实现CommandLineRunner接口,通过run方法处理main方法传入的参数,并且你能够使用@Value注解将命令行参数传入的值或者properties资源文件中定义的值注入到程序中。例如,创建一个HelloWorldService类:

package com.javachen.example.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class HelloWorldService {
  @Value("${name:World}")
  private String name;

  public String getMessage() {
    return "Hello " + this.name;
  }
}

并添加资源文件application.properties:

name: JavaChen

修改Application类为如下:

package com.javachen.example;

import com.javachen.example.service.HelloWorldService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@SpringBootApplication
public class Application implements CommandLineRunner {
  @Autowired
  private HelloWorldService helloWorldService;

  @RequestMapping("/")
  String home() {
    return "Hello World!";
  }

  @Override
  public void run(String... args) {
    System.out.println(this.helloWorldService.getMessage());
    if (args.length > 0 && args[0].equals("exitcode")) {
      throw new ExitException();
    }
  }

  public static void main(String[] args) throws Exception {
    SpringApplication.run(Application.class, args);
  }
}

运行该类的main方法,则默认会输出:

Hello JavaChen

再次运行main方法,并传入参数--name=whatever,则会输出:

Hello whatever

如果一些CommandLineRunner beans被定义必须以特定的次序调用,你可以额外实现org.springframework.core.Ordered接口或使用@Order注解。

利用command-line runner的这个特性,再配合依赖注入,可以在应用程序启动时后首先引入一些依赖bean,例如data source、rpc服务或者其他模块等等,这些对象的初始化可以放在run方法中。不过,需要注意的是,在run方法中执行初始化动作的时候一旦遇到任何异常,都会使得应用程序停止运行,因此最好利用try/catch语句处理可能遇到的异常。

每个SpringApplication在退出时为了确保ApplicationContext被优雅的关闭,将会注册一个JVM的shutdown钩子。所有标准的Spring生命周期回调(比如,DisposableBean接口或@PreDestroy注解)都能使用。

此外,如果beans想在应用结束时返回一个特定的退出码,可以实现org.springframework.boot.ExitCodeGenerator接口,例如上面例子中的ExitException异常类:

package com.javachen.example;

import org.springframework.boot.ExitCodeGenerator;

public class ExitException extends RuntimeException implements ExitCodeGenerator {
  @Override
  public int getExitCode() {
    return 10;
  }
}

自动配置

在启动类上使用@EnableAutoConfiguration注解,就会开启自动配置,简单点说就是它会根据定义在classpath下的类,自动的给你生成一些Bean,并加载到Spring的Context中。

它的神秘之处,不在于它能做什么,而在于它会生成什么样的Bean对于开发人员是不可预知(或者说不容易预知)。

例如,上面例子中引入了对spring-boot-starter-web的依赖,则会开启Spring MVC自动配置,观察启动日志,可以发现应用启动了tomcat和spring mvc。

Spring Boot为Spring MVC提供适用于多数应用的自动配置功能。在Spring默认基础上,自动配置添加了以下特性:

  • 引入ContentNegotiatingViewResolver和BeanNameViewResolver beans。
  • 对静态资源的支持,包括对WebJars的支持。
  • 自动注册Converter,GenericConverter,Formatter beans。
  • 对HttpMessageConverters的支持。
  • 自动注册MessageCodeResolver。
  • 对静态index.html的支持。
  • 对自定义Favicon的支持。

如果想全面控制Spring MVC,你可以添加自己的@Configuration,并使用@EnableWebMvc对其注解。如果想保留Spring Boot MVC的特性,并只是添加其他的MVC配置(拦截器,formatters,视图控制器等),你可以添加自己的WebMvcConfigurerAdapter类型的@Bean(不使用@EnableWebMvc注解)。

再举个例子:要开发一个基于Spring JPA的应用,会涉及到下面三个Bean的配置,DataSource,EntityManagerFactory,PlatformTransactionManager。

@Configuration
@EnableJpaRepositories
@EnableTransactionManagement
public class Application {
  @Bean
  public DataSource dataSource() {
      ...
  }

  @Bean
  public EntityManagerFactory entityManagerFactory() {
      ..
      factory.setDataSource(dataSource());
      return factory.getObject();
  }

  @Bean
  public PlatformTransactionManager transactionManager() {
      JpaTransactionManager txManager = new JpaTransactionManager();
      txManager.setEntityManagerFactory(entityManagerFactory());
      return txManager;
  }
}

说明:

  • @EnableJpaRepositories会查找满足作为Repository条件(继承父类或者使用注解)的类。
  • @EnableTransactionManagement的作用:Enables Spring’s annotation-driven transaction management capability, similar to the support found in Spring’s <tx:*> XML namespace。

但是,如果你使用了@EnableAutoConfiguration,那么上面三个Bean,你都不需要配置。在classpath下面只引入了MySQL的驱动和SpringJpa。

compile 'mysql:mysql-connector-java:5.1.18'
compile 'org.springframework.boot:spring-boot-starter-data-jpa'

在生产环境中,数据库连接可以使用DataSource池进行自动配置。下面是选取一个特定实现的算法:

  • 由于Tomcat数据源连接池的性能和并发,在tomcat可用时,我们总是优先使用它。
  • 如果HikariCP可用,我们将使用它。
  • 如果Commons DBCP可用,我们将使用它,但在生产环境不推荐使用它。
  • 最后,如果Commons DBCP2可用,我们将使用它。

如果你使用spring-boot-starter-jdbc或spring-boot-starter-data-jpa,你将会自动获取对tomcat-jdbc的依赖。

DataSource配置通过外部配置文件的spring.datasource.*属性控制。示例中,你可能会在application.properties中声明下面的片段:

spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

其他可选的配置可以查看DataSourceProperties。同时注意你可以通过spring.datasource.*配置任何DataSource实现相关的特定属性:具体参考你使用的连接池实现的文档。

既然Spring Boot能够从大多数数据库的url上推断出driver-class-name,那么你就不需要再指定它了。对于一个将要创建的DataSource连接池,我们需要能够验证Driver是否可用,所以我们会在做任何事情之前检查它。比如,如果你设置spring.datasource.driverClassName=com.mysql.jdbc.Driver,然后这个类就会被加载。

Spring的JdbcTemplate和NamedParameterJdbcTemplate类是被自动配置的,你可以在自己的beans中通过@Autowire直接注入它们。

如果数据源是jndi,则定义:

spring.datasource.jndi-name=java:jboss/datasources/customers

XML配置

如果不想使用注解进行配置,则可以使用xml配置文件,修改main方法如下:

  public static void main(String[] args) throws Exception {
    SpringApplication.run("classpath:/META-INF/application-context.xml", args);
  }

META-INF/application-context.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?><beansxmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:annotation-config/><context:property-placeholder/><beanid="helloService"class="com.javachen.example.service.HelloWorldService"/><beanid="application"class="com.javachen.example.Application"/></beans>

https://yq.aliyun.com/articles/25411?spm=5176.100239.blogcont25409.8.7ApYoY
分享到:
评论

相关推荐

    面试官:说一说 Spring Boot 自动配置原理吧,我懵逼了..docx

    面试官:说一说 Spring Boot 自动配置原理吧,我懵逼了

    Spring Boot 的自动配置,到底是怎么做到?.docx

    Spring Boot 自动配置机理详解 1. Spring Boot 概述 Spring Boot 是基于 Spring 框架的自动配置工具,旨在提高开发者的体验和效率。它的主要功能是自动配置 Spring 框架,降低项目搭建的复杂度。Spring Boot 并不...

    Spring Boot讲义.pdf

    了解Spring Boot自动配置原理 Spring Boot通过`@EnableAutoConfiguration`注解来启用自动配置功能,它利用类路径中的jar包依赖,根据添加的jar依赖猜测如何配置Spring。根据项目的类路径上的jar依赖,Spring Boot...

    Spring-Boot-Reference-Guide, Spring Boot Reference Guide中文翻译 -《Spring Boot参考指南》.zip

    三、Spring Boot自动配置 1. @EnableAutoConfiguration:标记在主类上启用自动配置。 2. AutoConfigurationPackages:用于识别应用的主包,方便自动配置扫描。 3. Conditional注解:如@ConditionalOnClass、@...

    Spring Boot 自动配置的实现

    Spring Boot 自动配置的实现 概述: Spring Boot 自动配置的实现是 Spring Boot 框架中的一项重要功能,它可以自动地配置应用程序中的各个组件,从而提高开发效率和简化配置过程。在本文中,我们将深入探讨 Spring...

    spring boot 相关技术

    2. **Spring Boot 自动配置**:解释 Spring Boot 如何通过 @EnableAutoConfiguration 注解进行自动配置,以及如何自定义自动配置。 3. **Web 开发**:讲解如何使用 Spring Boot 开发 Web 应用,包括 RESTful API 和...

    spring-boot-中文参考手册

    ### 一、Spring Boot自动配置 自动配置是Spring Boot的一大亮点,它根据项目中的类路径和已添加的jar依赖,自动配置相应的Bean。例如,如果在类路径下发现`HSQLDB`,那么Spring Boot会自动配置一个内存数据库;如果...

    Spring cloud和Spring boot介绍

    - **自动配置**:Spring Boot 自动配置了很多常用的组件和技术栈,如数据库连接、安全框架、邮件发送等,大大降低了开发者的工作量。 - **组件支持广泛**:对于开发者希望集成到应用中的几乎所有常用框架和技术栈,...

    localstack-spring-boot:适用于LocalStack的Spring Boot自动配置

    Smartup LocalStack Spring Boot自动配置 介绍 此自动配置库的范围是提供一种使用localstack配置AWS客户端的简单方法。 要求 要使用此自动配置,您需要JDK8 。 用法 首先,您必须在项目中包含localstack-spring-boot...

    spring boot面试题及答案.docx

    Spring Boot自动配置的原理 Spring Boot的自动配置原理是通过`@SpringBootApplication`或`@EnableAutoConfiguration`注解触发的。其核心步骤如下: 1. 在启动时,Spring Boot会读取依赖的JAR包中的`spring....

    spring-boot-reference

    ### Spring Boot 参考指南知识点概述 #### 一、Spring Boot 文档概览与入门 ... - **逐步替换自动配置**:提供了如何逐步替换 Spring Boot 自动配置的指南。 - **禁用自动配置**:解释了如何禁用特定的自动配置组件。

    Java Spring Boot面试题

    Spring Boot 自动配置原理是通过 @EnableAutoConfiguration 注解来实现的,该注解可以打开自动配置的功能,也可以关闭某个自动配置的选项。 YAML 是一种轻量级的数据交换格式,Spring Boot 使用 YAML 配置文件来配置...

    spring-boot-reference.pdf

    知识点四:Spring Boot自动配置的机制 Spring Boot的核心特性之一是其自动配置机制。Spring Boot通过分析类路径下的jar包以及类定义,配合spring.factories文件中配置的自动配置类,智能地推断出需要自动配置的组件...

    基于Spring Boot框架的购物篮管理系统.zip

    1. Spring Boot自动配置利用SpringBootApplication注解,项目能够自动配置Spring Boot应用所需的组件,简化了应用的启动和配置过程。 2. 应用启动通过SpringApplication.run(DemoApplication.class, args)方法,项目...

    Spring Boot实战与原理分析视频课程包含14-18

    8 Spring Boot 自动配置32:44 9 Spring Boot @Enable*注解的工作原理47:07 10 Spring Boot @EnableAutoConfiguration深入分析30:55 11 Spring Boot 事件监听27:53 --四种方式讲解如何配置事件监听 12 Spring ...

    spring-boot-jade:Jade 的 Spring Boot 自动配置

    Jade4j 的 Spring Boot 自动配置支持 通过 Maven 使用 1. 在你的pom.xml添加以下快照依赖 &lt; groupId&gt;com.github.instaweb&lt;/ groupId&gt; &lt; artifactId&gt;spring-boot-jade &lt; version&gt;0.9.0-SNAPSHOT 2. 确保将 ...

    Spring Boot技术培训

    - **`@EnableAutoConfiguration`**:启用 Spring Boot 自动配置功能。 - **`@ComponentScan`**:扫描指定包及其子包中的组件。 ##### 2.3 Spring Boot 配置文件 - **Properties 配置文件**:使用 `key=value` 格式...

    Spring.Boot.in.Action.2015.12.pdf

    - **自动配置**:Spring Boot 自动配置是其最大的特点之一,它可以根据添加到项目中的依赖库自动配置Spring Bean。这意味着开发者不需要手动编写大量的配置代码,可以专注于业务逻辑的实现。 - **起步依赖**:起步...

Global site tag (gtag.js) - Google Analytics