Spring/SpringBoot 的 自动装配与自动配置
1、概念理解
- 自动装配(Auto - Wiring)
在 Spring 框架(包括 Spring Boot)中,自动装配是指 Spring 容器自动将一个 Bean(组件)注入到另一个 Bean 中。它主要用于解决 Bean 之间的依赖关系。
例如,假设有一个UserService类,它依赖于一个UserRepository类来进行数据库操作。在传统的配置方式下,需要在UserService的配置(如 XML 配置或者 Java 配置类)中显式地声明如何获取UserRepository的实例。而自动装配可以让 Spring 容器自动找到合适的UserRepository实例并注入到UserService中。
自动装配是通过@Autowired(在 Spring 中)或者@Resource等注解来实现的。@Autowired注解默认是按照类型(byType)进行装配,如果存在多个相同类型的 Bean,还可以结合@Qualifier注解按照名称(byName)进行更精确的装配。
- 自动配置(Auto - Configuration)
Spring Boot 自动配置是一种更高级的特性。它的目的是根据项目中添加的依赖(如数据库驱动、消息队列客户端等)和配置自动配置 Spring 应用程序的环境。
例如,当在pom.xml(如果是 Maven 项目)中添加了spring - boot - starter - web依赖,Spring Boot 会自动配置一个嵌入式的 Web 服务器(如 Tomcat),并且配置好相关的 Servlet、Filter 等 Web 组件的 Bean。
自动配置是基于一系列的条件判断和默认配置来实现的。Spring Boot 内部有很多自动配置类,这些类通过@Configuration注解标记,并且会使用@Conditional系列注解(如@ConditionalOnClass、@ConditionalOnMissingBean等)来判断是否需要进行特定的配置。比如,如果classpath下存在HikariCP相关的类,并且没有自定义的数据源配置,Spring Boot 可能会自动配置一个HikariCP数据源。
2、应用场景和目的
- 自动装配
主要用于处理 Bean 之间的依赖关系,让开发者能够更方便地构建复杂的对象图。它简化了对象之间的装配过程,减少了配置代码的数量。
例如,在一个大型的企业级应用中,可能有多个业务层服务(Service)和数据访问层(Repository)的 Bean,自动装配可以确保这些 Bean 之间的依赖正确地建立起来,提高代码的可维护性和可读性。
- 自动配置
用于快速搭建应用程序的运行环境。它使得开发者可以专注于业务逻辑的开发,而不需要花费大量时间在配置底层的框架和基础设施上。
例如,在开发一个微服务应用时,只要添加了相应的spring - boot - starter依赖,Spring Boot 就会自动配置好所需的大部分组件,如 Web 服务、数据库连接、缓存等,大大提高了开发效率。
3、实现机制
3.1自动装配
Spring 容器在启动过程中,会解析带有自动装配注解(如@Autowired)的 Bean。它会通过反射机制查找符合条件的 Bean 来进行注入。具体来说,它首先会根据类型查找,如果找到多个相同类型的 Bean,会根据名称或者其他条件(如@Primary注解指定的首选 Bean)进一步筛选。这个过程涉及到 Spring 的 BeanFactory 和 ApplicationContext 的内部机制,它们维护了 Bean 的定义和实例的创建与管理。
3.2自动配置
Spring Boot 的自动配置是基于@Configuration和@Conditional注解实现的。当 Spring Boot 应用启动时,它会扫描classpath下的自动配置类。这些自动配置类会根据各种条件(如类路径下是否存在特定的类、是否已经定义了某些 Bean 等)来决定是否要应用相应的配置。例如,DataSourceAutoConfiguration类会检查是否添加了数据库驱动依赖并且没有自定义数据源配置,如果满足条件,就会自动配置一个数据源。这个过程涉及到 Spring Boot 的自动配置加载机制,包括@EnableAutoConfiguration注解的作用以及SpringFactoriesLoader类在加载自动配置类中的角色。
3.2.1核心注解与启动机制
- Spring Boot 应用的入口通常是一个带有@SpringBootApplication注解的主类。这个注解是一个组合注解,它包含了@Configuration、@EnableAutoConfiguration和@ComponentScan。
@Configuration:表明这个类是一个配置类,用于定义 Bean 和配置信息,相当于传统 Spring 中的 XML 配置文件的作用。例如,可以在这个配置类中使用@Bean注解定义一个 Bean,如定义一个自定义的数据源:
@Configuration
public class AppConfig {
@Bean
public DataSource dataSource() {
// 配置数据源的相关信息
// 这里只是示例,实际可能会更复杂
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
dataSource.setUsername("root");
dataSource.setPassword("password");
return dataSource;
}
}
@ComponentScan:用于扫描指定包及其子包下的带有@Component、@Service、@Repository、@Controller等注解的组件,将它们注册为 Spring 容器中的 Bean。这样,Spring 就能自动发现和管理这些组件,例如,扫描一个com.example.service包下的所有服务类:
@ComponentScan("com.example.service")
@EnableAutoConfiguration:这是自动配置的关键注解。它实际上是借助@Import注解导入了AutoConfigurationImportSelector类。这个类会在 Spring Boot 应用启动时,从META - INF/spring.factories文件中加载自动配置类。
3.2.2自动配置类的加载
Spring Boot 会通过SpringFactoriesLoader类来加载META - INF/spring.factories文件中的自动配置信息。这个文件是一个键值对形式的配置文件,其中org.springframework.boot.autoconfigure.EnableAutoConfiguration是键,对应的值是一系列自动配置类的全路径名。
例如,当添加了spring - boot - starter - web依赖时,spring.factories文件中相关的自动配置类(如WebMvcAutoConfiguration)就会被加载。这些自动配置类会根据条件判断是否需要进行配置。
3.2.3条件判断机制
自动配置类中大量使用了@Conditional系列注解来决定是否应用配置。
@ConditionalOnClass:用于判断类路径下是否存在指定的类。例如,DataSourceAutoConfiguration类中可能会有这样的条件判断:
@Configuration
@ConditionalOnClass(DataSource.class)
public class DataSourceAutoConfiguration {
// 配置数据源相关的Bean
}
这意味着只有当类路径下存在DataSource类(通常是因为添加了数据库驱动依赖)时,这个自动配置类才会生效。
@ConditionalOnMissingBean:用于判断容器中是否已经存在指定类型的 Bean。如果不存在,才会进行相关 Bean 的配置。例如,在自动配置一个RestTemplate时,可能会有这样的条件:
@Configuration
@ConditionalOnMissingBean(RestTemplate.class)
public class RestTemplateAutoConfiguration {
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
}
这表示如果容器中还没有RestTemplate这个 Bean,就会自动配置一个。通过这种条件判断机制,Spring Boot 可以根据项目的实际情况(如已经存在的 Bean 和类路径下的依赖)来灵活地进行自动配置,避免不必要的配置冲突和重复配置。
源自豆包~