SpringBoot自动配置原理: 1. Condition接口: Condition接口是spring4.0之后提供的接口,增加条件判断功能,用于选择性的创建Bean对象到spring容器中。 在Condition接口有一个方法:matches(),该方法用于判断,当加入了相关坐标依赖后,返回值为true,没有加入依赖, 则返回值为false。 2.相关注解说明: @Configuration:标记该类是一个配置类 @Bean:用在方法上,将方法的返回值(一般是Bean)注册给spring容器管理 @Conditional(OnCondition.class):用在方法上,用于判断,如果类OnCondition中的方法matches()返回值为true, 则执行下面的代码,否则不执行 @Import: import注解用于导入其他的配置,让spring容器进行加载和初始化。import的注解有以下的几种方式使用: 1. @Import(User.class): 直接导入Bean,注意使用该注解,类User要使用注解@Component注册给spring容器; 2. @Import(UserConfig.class): 3. @Import(MyImportSelector.class):导入ImportSelector接口的实现类,实现类中重写方法selectImports(), 该方法返回要注册到spring容器中的Bean的全路径,即: return new String[]{"com.itheima.pojo.Role", "com.itheima.pojo.User"}; 4. @Import(MyImportBeanDefinitionRegistrar.class):导入ImportBeanDefinitionRegistrar实现类,重写 registerBeanDefinitions()方法: @Override public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { //创建BeanDefiniation AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition(); //注册bean 目前只注册User registry.registerBeanDefinition("user",beanDefinition); } @SpringBootApplication: 该注解由以下三个注解所组成: 1. @SpringbootConfiguration: 该注解等价于@Configuration,用于标记该类是一个配置类; 2. @ComponentScan: 该注解用于组件扫描(包扫描),类似于xml中的context-componet-scan,如果不指定扫描路径, 那么就扫描该注解修饰的启动类所在的包以及子包。 3. @EnableAutoConfiguration 1.组合了@import注解,导入配置 2.使用了@Import的第三种用法,导入ImportSelector接口的实现类,selectImports导入类中的方法中加载配置返回Bean定义的字符数组 3.加载META-INF/spring.factories ,获取Bean定义的全路径名返回 4.最终返回回去即可 需求: 当加入了jedis依赖后,自动创建User存入spring容器中;没有jedis依赖坐标,则不创建User; 实现: 1. 创建工程,导入坐标: <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.it</groupId> <artifactId>springboot-condition</artifactId> <version>1.0-SNAPSHOT</version> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.4.RELEASE</version> </parent> <dependencies> <!--加入springboot的starter起步依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>3.2.0</version> </dependency> </dependencies> </project> 2. 创建pojo--User package com.it.pojo; /** * ToDo * * @author Lyle * @date 2020/4/1 */ public class User { } 3. 创建启动类 package com.it; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.context.ConfigurableApplicationContext; /** * ToDo * * @author Lyle * @date 2020/4/1 */ @SpringBootApplication public class ConditionApplication { public static void main(String[] args) { ConfigurableApplicationContext context = SpringApplication.run(ConditionApplication.class, args); Object user = context.getBean("user"); System.out.println(user); } } 4. 创建配置类,用于向spring容器中注册对象: package com.it.config; import com.it.condition.OnCondition; import com.it.pojo.User; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Conditional; import org.springframework.context.annotation.Configuration; /** * ToDo * * @author Lyle * @date 2020/4/1 */ @Configuration//标记该类是一个配置类 public class UserConfig { //注册Bean--User交给spring来管理 //当导入了相关坐标依赖的时候 @Bean @Conditional(OnCondition.class)//用于判断,如果OnCondition中的matches()返回值为true,则执行下面的代码,否则不执行 public User user(){//注意方法名不能改 return new User(); } } 5. 创建类OnCondition,用于判断 package com.it.condition; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; import org.springframework.core.type.AnnotatedTypeMetadata; /** * ToDo * * @author Lyle * @date 2020/4/1 */ public class OnCondition implements Condition { //用于判断,符合条件,返回true,不符合条件,返回false @Override public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) { //jedis坐标存在,返回true try { Class.forName("redis.clients.jedis.Jedis");//执行成功,说明类加载到了,类存在 } catch (ClassNotFoundException e) {//否则,说明类不存在 e.printStackTrace(); return false; } //jedis坐标不存在,返回false return true; } } 3. 切换内置的web容器Tomcat 1. 排除Tomcat的起步依赖: <exclusions> <exclusion> <artifactId>spring-boot-starter-tomcat</artifactId> <groupId>org.springframework.boot</groupId> </exclusion> </exclusions> 2. 加入其它web容器的依赖:例如:jetty,netty等 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jetty</artifactId> </dependency>
来源:https://www.cnblogs.com/lyle-liu/p/12618820.html