spring boot
spring boot自动配置实现原理
1、
Condition是Spring4.0后引入的条件化配置接口,通过实现Condition接口可以完成有条件的加载相应的Bean
Conditon是条件的意思,属于spring的一个接口,抽象方法为matches,返回值为boolean,两个参数分别为
ConditionContext:上下文对象,可以获取属性值,获取类加载器,获取BeanFactory等
AnnotatedTypeMetadata:元数据对象,用于获取注解属性
Conditon接口
1 @FunctionalInterface 2 public interface Condition { 3 boolean matches(ConditionContext var1, AnnotatedTypeMetadata var2); 4 }
Conditional注解
1 @Target({ElementType.TYPE, ElementType.METHOD}) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 public @interface Conditional { 5 Class<? extends Condition>[] value(); 6 }
ConditionalOnClass注解
1 @Target({ElementType.TYPE, ElementType.METHOD}) 2 @Retention(RetentionPolicy.RUNTIME) 3 @Documented 4 @Conditional({OnClassCondition.class}) 5 public @interface ConditionalOnClass { 6 Class<?>[] value() default {}; 7 8 String[] name() default {}; 9 }
通过在配置类上加ConditionalOnClass(“com.alibaba.fastjson.JSON”)就能实现满足导入Json包才能获取类这样的操作,即自动加载bean对象
springboot 提供的常用条件注解
- ConditionalOnProperty:判断配置文件中是否有对应属性和值才初始化Bean
- ConditionalOnClass:判断环境中是否有对应字节码文件才初始化Bean
- ConditionalOnMissingBean:判断环境中没有对应Bean才初始化Bean
2、
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<!--排除tomcat依赖-->
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>org.springframework.boot</groupId>
</exclusion>
</exclusions>
</dependency>
<!--引入jetty的依赖-->
<dependency>
<artifactId>spring-boot-starter-jetty</artifactId>
<groupId>org.springframework.boot</groupId>
</dependency>
3、
1 /** 2 * @ComponentScan 扫描范围:当前引导类所在包及其子包 3 * 4 * com.itheima.springbootenable 5 * com.itheima.config 6 * //1.使用@ComponentScan扫描com.itheima.config包 7 * //2.可以使用@Import注解,加载类。这些类都会被Spring创建,并放入IOC容器 8 * //3.可以对Import注解进行封装。 9 */ 10 11 //@ComponentScan("com.itheima.config") 12 //@Import(UserConfig.class) 13 @EnableUser 14 @SpringBootApplication//组合注解,其中有个Configration注解为配置类 15 public class SpringbootEnableApplication { 16 17 public static void main(String[] args) { 18 ConfigurableApplicationContext context = SpringApplication.run(SpringbootEnableApplication.class, args); 19 20 //获取Bean 21 Object user = context.getBean("user"); 22 System.out.println(user); 23 24 } 25 26 }
-
1 封装的Import注解 2 @Target(ElementType.TYPE) 3 @Retention(RetentionPolicy.RUNTIME) 4 @Documented 5 @Import(UserConfig.class) 6 public @interface EnableUser {}
-
@Enable*这个注解的底层还是@import注解,所以使用@Import导入的类会被Spring加载到IOC容器中。
而@Import提供4中用法:
- 导入Bean 直接@Import(“user.class”)
- 导入配置类 直接导入其他工程中的配置类
- 导入 ImportSelector 实现类。一般用于加载配置文件中的类@Import(MyImportSelector.class)
-
1 public class MyImportSelector implements ImportSelector { 2 @Override 3 public String[] selectImports(AnnotationMetadata importingClassMetadata) { 4 return new String[]{"com.itheima.domain.User", "com.itheima.domain.Role"}; 5 } 6 }
其他工程定义一个类实现ImportSelector这个借口,重写selectImport方法,将需要的类作为返回值返回
-
- 导入 ImportBeanDefinitionRegistrar 实现类 @Import({MyImportBeanDefinitionRegistrar.class})
-
1 public class MyImportBeanDefinitionRegistrar implements ImportBeanDefinitionRegistrar { 2 @Override 3 public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) { 4 AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class).getBeanDefinition(); 5 registry.registerBeanDefinition("user", beanDefinition); 6 } 7 }
-
那么springboot是如何加载管理的那些类呢?怎么样去判断那些类是需要被加载入ioc的呢?
在定义引导类的时候,添加的@SpringBootApplication注解是一个组合注解包含了:
- @SpringBootConfiguration 该注解表示此类是配置类
- @EnableAutoConfiguration 该注解底层就是@import注解,而这个注解会加载AutoConfigurationImportSelector这个类,通过这个类去加载META-INF/spring.factories这个文件,文件在autoconfig下面,该配置文件中定义了大量的配置类,
- 当 SpringBoot 应用启动时,会自动加载这些配置类,初始化Bean,但是有不是所有的类都会被注入ioc容器,这些被spring管理的类在他们的工程中进行了配置文件类,当只有在pom文件中导入了这个类的坐标,才会被注入ioc容器中