Springboot自动配置的实现原理

spring自动配置的原理

要点在于理解@Import和@Conditional注解的作用

@Import导入对象的三种方式
  1. 如何从spring容器中获取,通过@Import方式导入的其实和下面的原理是一样的,都是直接从spring容器中获取,只不过@Import不需要扫描

回忆Spring中如何从容器中获取对象

  • 点击redisTemplate注入的位置左边的小图标,跳转到注入的位置RedisAutoConfiguration配置类
  • ctrl+H查看类的所有子接口以及实现类

启动类中的方法取出的就是容器,ConfigurableApplicationContext context = SpringApplication.run(Springboot03ImportAnnApplication.class, args);

public interface ConfigurableApplicationContext extends ApplicationContext, Lifecycle, Closeable

查看ClassPathXmlApplicationContext的UML图,使用alt+鼠标可以放大

  • ClassPathXmlApplicationContext和ConfigurableApplicationContext都是spring容器的实现类实现类,以下为ClassPathXmlApplicationContext类图

在这里插入图片描述

  1. 第二种:导入一个配置类,配置类中@Bean,会自动的批量导入对象
/**
 * @ComponentScan("com.itheima") 注解作用:组件扫描,扫描指定包下的所有注解,注入对象到spring的ioc容器
 * @Import(JdbcConfiguration.class) 注解作用:导入配置类
 * @EnableTransactionManagement 注解作用:开启事务管理器
 */
@Configuration
@Import(JdbcConfiguration.class)//导入本项目中的配置类
public class SpringConfiguration {
    @Bean
    public UserService getUserService(){
        return new UserServiceImpl();
    }
}
  1. 导入SelectImport接口的实现类对象,把批量的类全限定名称的类,注入到ioc容器 @Import(MySelectImport.class)
public class MySelectImport implements ImportSelector {
    //返回所有需要导入到spirng容器中的字节码文件,这些类的字节码文件将被注入到spring容器中
    @Override
    public String[] selectImports(AnnotationMetadata annotationMetadata) {
        String[] clazzs = {
                "com.ahu.springboot03_import_ann.service.UserServiceImpl",
                "com.ahu.springboot03_import_ann.pojo.User"
        };
        return clazzs;
    }
}
@Configuration条件注解

**思考一个问如果springboot在初始化的时候把spring.factories中的配置类全部加载一遍,那电脑就炸了,所以需要控制配置类的加载

  • @Configuration表示当前的类是一个注解类
  • RedisAutoConfiguration中@ConditionalOnClass({RedisOperations.class}),当前的classpath路径下存在RedisOperations的类对象的时候其他的注解有效
  • 查看源码可以知道,可以作用在类和方法上面
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional({OnClassCondition.class})
public @interface ConditionalOnClass {
    Class<?>[] value() default {};

    String[] name() default {};
}

小案例

  • @ConditionalOnClass classpath下存在这个类的时候生效
  • @ConditionalOnProperty 注解作用:当配置文件application.properties中存在key配置且值为true时,条件生效
    • name 属性名
    • havingValue 设置配置的默认值
    • matchIfMissing 设置value是匹配的值,如果匹配条件生效,如果不匹配则不生效

在这里插入图片描述

@Configuration
public class SpringConfiguration {
    /**
     * @ConditionalOnClass classpath下存在这个类的时候生效
     * @ConditionalOnProperty 注解作用:当配置文件application.properties中存在key配置且值为true时,条件生效
     * name 属性名 ,havingValue 设置配置的默认值 , matchIfMissing 设置value匹配的值,如果匹配条件生效,如果不匹配则不生效
     * @return
     */
    @Bean
//    @ConditionalOnClass(name = "com.ahu.springboot_conditional_ann.pojo.Cat")
    @ConditionalOnProperty(name = "com.ahu.condition", havingValue = "true", matchIfMissing = true)
    public Dog getDog(){
        return new Dog();
    }
}
@SpringBootApplication
public class SpringbootConditionalAnnApplication {

	public static void main(String[] args) {
		ConfigurableApplicationContext context = SpringApplication.run(SpringbootConditionalAnnApplication.class, args);
		Dog dog = context.getBean(Dog.class);
		System.out.println(dog);
	}
}
查看springboot中redis的配置类源码学习如何使用注解

在这里插入图片描述
点击配置文件中的spring.redis.port跳转RedisProperties.class中,查看通过@ConfigurationProperties注入


@ConfigurationProperties(
    prefix = "spring.redis"
)

那么springboot自动配置跟上面知识点有什么关联呢?
  • 查看注解@SpringBootApplication
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
  • 查看注解@EnableAutoConfiguration,含有注解@Import({AutoConfigurationImportSelector.class}),AutoConfigurationImportSelector是SelectImport接口的实现类,只不过它导入的是spring.factories中的配置类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值