首页 > 其他分享 >SpringBoot自动装配

SpringBoot自动装配

时间:2024-07-04 14:10:29浏览次数:14  
标签:装配 return SpringBoot ComponentScan annotationMetadata 自动 link class configuratio

 

没有 Spring Boot 的情况下,如果我们需要引入第三方依赖,需要手动配置,非常麻烦。但是,Spring Boot 中,我们直接引入一个 starter 即可。比如你想要在项目中使用 redis 的话,直接在项目中引入对应的 starter 即可。

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

 

引入 starter 之后,我们通过少量注解和一些简单的配置就能使用第三方组件提供的功能了。

 

在我看来,自动装配可以简单理解为:通过注解或者一些简单的配置就能在 Spring Boot 的帮助下实现某块功能。

源码分析

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
        @Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {

    /**
     * Exclude specific auto-configuration classes such that they will never be applied.
     * @return the classes to exclude
     */
    @AliasFor(annotation = EnableAutoConfiguration.class)
    Class<?>[] exclude() default {};

    /**
     * Exclude specific auto-configuration class names such that they will never be
     * applied.
     * @return the class names to exclude
     * @since 1.3.0
     */
    @AliasFor(annotation = EnableAutoConfiguration.class)
    String[] excludeName() default {};

    /**
     * Base packages to scan for annotated components. Use {@link #scanBasePackageClasses}
     * for a type-safe alternative to String-based package names.
     * <p>
     * <strong>Note:</strong> this setting is an alias for
     * {@link ComponentScan @ComponentScan} only. It has no effect on {@code @Entity}
     * scanning or Spring Data {@link Repository} scanning. For those you should add
     * {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} and
     * {@code @Enable...Repositories} annotations.
     * @return base packages to scan
     * @since 1.3.0
     */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackages")
    String[] scanBasePackages() default {};

    /**
     * Type-safe alternative to {@link #scanBasePackages} for specifying the packages to
     * scan for annotated components. The package of each class specified will be scanned.
     * <p>
     * Consider creating a special no-op marker class or interface in each package that
     * serves no purpose other than being referenced by this attribute.
     * <p>
     * <strong>Note:</strong> this setting is an alias for
     * {@link ComponentScan @ComponentScan} only. It has no effect on {@code @Entity}
     * scanning or Spring Data {@link Repository} scanning. For those you should add
     * {@link org.springframework.boot.autoconfigure.domain.EntityScan @EntityScan} and
     * {@code @Enable...Repositories} annotations.
     * @return base packages to scan
     * @since 1.3.0
     */
    @AliasFor(annotation = ComponentScan.class, attribute = "basePackageClasses")
    Class<?>[] scanBasePackageClasses() default {};

}

@SpringBootApplication@Configuration@EnableAutoConfiguration@ComponentScan 注解的集合。SpringBoot官网解释这三个注解的作用分别是:

  • @EnableAutoConfiguration:启用 SpringBoot 的自动配置机制
  • @Configuration:允许在上下文中注册额外的 bean 或导入其他配置类
  • @ComponentScan:扫描被@Component (@Service,@Controller)注解的 bean,注解默认会扫描启动类所在的包下所有的类 ,可以自定义不扫描某些 bean。

EnableAutoConfiguration 只是一个简单地注解,自动装配核心功能的实现实际是通过 AutoConfigurationImportSelector类。

@Import:将需要的类注册bean到spring容器中。

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

    String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

    /**
     * Exclude specific auto-configuration classes such that they will never be applied.
     * @return the classes to exclude
     */
    Class<?>[] exclude() default {};

    /**
     * Exclude specific auto-configuration class names such that they will never be
     * applied.
     * @return the class names to exclude
     * @since 1.3.0
     */
    String[] excludeName() default {};

}

AutoConfigurationImportSelector进行spring.factories文件的扫描,获取自动装配类。

public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
        ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

    private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();

    private static final String[] NO_IMPORTS = {};

    private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);

    private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";

    private ConfigurableListableBeanFactory beanFactory;

    private Environment environment;

    private ClassLoader beanClassLoader;

    private ResourceLoader resourceLoader;

  //实现了DeferredImportSelector接口,selectImports返回一个包含了类全限定名的数组,这些类会注入到Spring容器当中 @Override public String[] selectImports(AnnotationMetadata annotationMetadata) {
     //判断自动装配开关是否打开。默认spring.boot.enableautoconfiguration=true,可在 application.properties 或 application.yml中设置 if (!isEnabled(annotationMetadata)) { return NO_IMPORTS; } AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader .loadMetadata(this.beanClassLoader); AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata); return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations()); } /** * Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata} * of the importing {@link Configuration @Configuration} class. * @param autoConfigurationMetadata the auto-configuration metadata * @param annotationMetadata the annotation metadata of the configuration class * @return the auto-configurations that should be imported */ protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata, AnnotationMetadata annotationMetadata) { if (!isEnabled(annotationMetadata)) { return EMPTY_ENTRY; } AnnotationAttributes attributes = getAttributes(annotationMetadata); List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes); configurations = removeDuplicates(configurations); Set<String> exclusions = getExclusions(annotationMetadata, attributes); checkExcludedClasses(configurations, exclusions); configurations.removeAll(exclusions);
     //按需加载,根据@Condition注解过滤 configurations = filter(configurations, autoConfigurationMetadata); fireAutoConfigurationImportEvents(configurations, exclusions); return new AutoConfigurationEntry(configurations, exclusions); }
protected List<String> getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) {
     //所有 SpringBootStarter下的META-INF/spring.factories都会被读取到。 List<String> configurations = SpringFactoriesLoader.loadFactoryNames(getSpringFactoriesLoaderFactoryClass(), getBeanClassLoader()); Assert.notEmpty(configurations, "No auto configuration classes found in META-INF/spring.factories. If you " + "are using a custom packaging, make sure that file is correct."); return configurations; } }

 Spring Boot 提供的条件注解

  • @ConditionalOnBean:当容器里有指定 Bean 的条件下
  • @ConditionalOnMissingBean:当容器里没有指定 Bean 的情况下
  • @ConditionalOnSingleCandidate:当指定 Bean 在容器中只有一个,或者虽然有多个但是指定首选 Bean
  • @ConditionalOnClass:当类路径下有指定类的条件下
  • @ConditionalOnMissingClass:当类路径下没有指定类的条件下
  • @ConditionalOnProperty:指定的属性是否有指定的值
  • @ConditionalOnResource:类路径是否有指定的值
  • @ConditionalOnExpression:基于 SpEL 表达式作为判断条件
  • @ConditionalOnJava:基于 Java 版本作为判断条件
  • @ConditionalOnJndi:在 JNDI 存在的条件下差在指定的位置
  • @ConditionalOnNotWebApplication:当前项目不是 Web 项目的条件下
  • @ConditionalOnWebApplication:当前项目是 Web 项 目的条件下

以RedisAutoConfiguration为例:

@Configuration
@ConditionalOnClass(RedisOperations.class)
@EnableConfigurationProperties(RedisProperties.class)
@Import({ LettuceConnectionConfiguration.class, JedisConnectionConfiguration.class })
public class RedisAutoConfiguration {

    @Bean
    @ConditionalOnMissingBean(name = "redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

    @Bean
    @ConditionalOnMissingBean
    public StringRedisTemplate stringRedisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        StringRedisTemplate template = new StringRedisTemplate();
        template.setConnectionFactory(redisConnectionFactory);
        return template;
    }

}

 

标签:装配,return,SpringBoot,ComponentScan,annotationMetadata,自动,link,class,configuratio
From: https://www.cnblogs.com/zhengbiyu/p/18283750

相关文章

  • 巴图自动化Profinet协议转Modbus协议网关模块连接智能仪表与PLC通讯
    一、功能及优势:巴图自动化Profinet协议转Modbus协议网关模块(BT-MDPN10)的主要功能是实现Modbus协议和Profinet协议之间的转换和通信。Profinet协议转Modbus协议网关模块(BT-MDPN10)集成了Modbus和Profinet两种协议以及网口和串口,可接485/232设备,支持ModbusRTU主站/从站。二、现场......
  • 太阳能自动追光系统
    摘要随着能源危机的严重性和可再生能源的重要性日益凸显,太阳能作为一种清洁、可再生的能源逐渐受到人们的关注。为了提高太阳能发电效率,本文设计并实现了一种基于51单片机的太阳能自动追光系统。该系统通过光电传感器实时检测光照强度,并利用单片机控制步进电机实现太阳能......
  • 日志自动提取---七牛Logkit&观星应急工具
    目录七牛Logkit(Windows&Linux&Mac等)下载:文档:windows配置过程:1-下载2-修改logkit-community基本配置3-启动!4-浏览器访问5-添加配置吧观星应急工具 (Windows系统日志)七牛Logkit(Windows&Linux&Mac等)--简单直观,   专业版的功能更多...支持的数......
  • 招募贴 | 第四期自动驾驶OS开发初阶营报名开启
    招募贴|第四期自动驾驶OS开发初阶营报名开启第四期国家智能网联汽车创新中心自动驾驶OS开发初阶训练营将于2024年7月22日开营,现已开启报名,诚邀对自动驾驶底层软件开发感兴趣的学员加入,一起驶入自动驾驶的快车道,共同探索未来的无限可能。从训练营能学到什么?训练营课程涵盖三......
  • python自动化内存管理
    引用在编程中,引用是指用来标识、访问或操作某个对象的值的标识符或变量。我们可以将引用看作是对象的别名,通过引用可以操作对象,包括读取、修改和传递对象的值。举例来说,假设我们有一个字符串对象`name`,我们可以创建一个变量`person`来引用这个字符串对象。在这个例子中,`perso......
  • 福利来了!MoneyPrinterPlus可以自动配置环境和自动运行了
    之前开源了MoneyPrinterPlus,可以实现批量混剪视频,一键生成视频和自动发布视频的功能。但是经常会看到小伙伴在安装过程中遇到很多问题。所以这篇文章的目的就是告诉大家怎么使用MoneyPrinterPlus的自动环境配置工具和自动启动工具。让小白用户也能用上这么好的AI工具。都是满满......
  • springboot项目国产化适配,jar改war包碰到的坑-tomcat版本要适配(非法访问:此Web应用程序
    项目原来是jar包运行,国产化适配要改成war包。可以参考https://blog.csdn.net/NAMELZX/article/details/138123405或者其他jar 改成 war 的文章。改成war后,在本地tomcat8上运行,一直报org.apache.catalina.loader.WebappClassLoaderBase.checkStateForResourceLoading非法......
  • springboot基于web的酒店客房管理系统
    文章目录目录文章目录论文目录项目介绍开发环境系统实现论文参考论文目录1系统概述1.1研究背景1.2研究目的1.3系统设计思想2相关技术2.1 MYSQL数据库2.2 B/S结构2.3 SpringBoot框架简介2.4 VUE框架简介3系统分析3.1可行性分析3.1.1技术......
  • springboot+伊犁地区游客小助手-小程序-计算机毕设定制-附项目源码(可白嫖) 20888
    摘 要提起伊犁,很多人常说,不去新疆,你就不知道中国有多美,不去伊犁,你就不知道新疆有多美。在这里你可以看到中国最美的景色。如果可可托海海是一个野性和粗犷的战士,那么那拉提一定是一个温柔和玉般的绅士。新疆的南边给了它不同寻常的品质。赛里木湖位于新疆西部的博尔塔拉县......
  • 基于SpringBoot+Vue+基于微信小程序的音乐播放器系统设计和实现(源码+LW+部署讲解)
    博主介绍:✌全网粉丝50W+,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和学生毕业项目实战,高校老师/讲师/同行前辈交流✌技术范围:SpringBoot、Vue、SSM、HLMT、Jsp、PHP、Nodejs、P......