问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

springboot自动注入原理(springboot如何注入自定义类)

发布网友 发布时间:2024-09-26 04:52

我来回答

1个回答

热心网友 时间:2024-11-19 12:32

SpringBoot自动配置的原理及实现/SpringBoot之@Import注解正确使用方式

了解SpringBoot之@Import注解正确使用方式

SpringBoot的核心就是自动配置,自动配置又是基于条件判断来配置Bean。关于自动配置的源码在spring-boot-autoconfigure-2.0.3.RELEASE.jar

在通常需要我们在property中配置信息时,通常使用@ConfigurationProperties(pefix=“前缀”)注解的方式从配置文件中获取配置,如下:

application.yml中配置信息

访问url获取配置信息返回的值

如果把application.yml中的配置信息注释掉则默认使用default值,否则使用配置信息中的值,以上便是普通配置方式

SpringBoot运行原理

先看@SpringBootApplication

主要关注的几个注解如下

@SpringBootConfiguration:标记当前类为配置类

@EnableAutoConfiguration:开启自动配置

@ComponentScan:扫描主类所在的同级包以及下级包里的Bean

关键是@EnableAutoConfiguration

最关键的要属@Import(EnableAutoConfigurationImportSelector.class),借助**EnableAutoConfigurationImportSelector**,@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器:通过@Import(AutoConfigurationImportSelector.class)导入的配置功能,

AutoConfigurationImportSelector中的方法getCandidateConfigurations,得到待配置的class的类名集合,这个集合就是所有需要进行自动配置的类,而是是否配置的关键在于META-INF/spring.factories文件中是否存在该配置信息

打开,如下图可以看到所有需要配置的类全路径都在文件中,每行一个配置,多个类名逗号分隔,而\表示忽略换行

整个流程如上图所示

以SpringApplicationAdminJmxAutoConfiguration类来看其主要构成部分

都能看到各种各样的条件判断注解,满足条件时就加载这个Bean并实例化

此类的条件注解是:@ConditionalOnProperty

@ConditionalOnBean:当容器里有指定Bean的条件下

@ConditionalOnClass:当类路径下有指定的类的条件下

@ConditionalOnExpression:基于SpEL表达式为true的时候作为判断条件才去实例化

@ConditionalOnJava:基于JVM版本作为判断条件

@ConditionalOnJndi:在JNDI存在的条件下查找指定的位置

@ConditionalOnMissingBean:当容器里没有指定Bean的情况下

@ConditionalOnMissingClass:当容器里没有指定类的情况下

@ConditionalOnWebApplication:当前项目时Web项目的条件下

@ConditionalOnNotWebApplication:当前项目不是Web项目的条件下

@ConditionalOnProperty:指定的属性是否有指定的值

@ConditionalOnResource:类路径是否有指定的值

@ConditionalOnOnSingleCandidate:当指定Bean在容器中只有一个,或者有多个但是指定首选的Bean

这些注解都组合了@Conditional注解,只是使用了不同的条件组合最后为true时才会去实例化需要实例化的类,否则忽略

这种spring4.X带来的动态组合很容易后期配置,从而避免了硬编码,使配置信息更加灵活多变,同时也避免了不必要的意外异常报错。使用的人只要知道配置的条件即可也不用去阅读源码,方便快捷,这也是sprignboot快捷方式带来的好处

参考HttpEncodingAutoConfiguration配置信息如下

案例扩展

项目

需要实例化的服务类

配置信息对应的属性映射类,需要pom中加入spring-boot-starter依赖

自动配置文件

在创建如下路径文件src/main/resources/META-INF/spring.factories

必须是自动配置类的全路径

mvninstall该项目

创建一个springboot-mvc项目pom依赖上面的jar

/则返回当前服务的默认值

在applicaton.yml中加,重启刷新则会更新为如下信息

SpringBoot自动化配置关键组件关系图

mybatis-spring-boot-starter、spring-boot-starter-web等组件的META-INF文件下均含有spring.factories文件,自动配置模块中,SpringFactoriesLoader收集到文件中的类全名并返回一个类全名的数组,返回的类全名通过反射被实例化,就形成了具体的工厂实例,工厂实例来生成组件具体需要的bean。

在springboot中有时候需要控制配置类是否生效,可以使用@ConditionalOnProperty注解来控制@Configuration是否生效.

boot自动配置的原理

SpringBoot是基于Spring开发的,是约定大于配置的核心思想。并且集成了大量的第三方库配置比如redis、mongoDB、jpa等。SpringBoot就相当于maven整合了所有jar包,SpringBoot整合了所有框架。其设计目的是用来简化新Spring应用的初始搭建以及开发过程,并不少什么新的框架。

二、SpringBoot优点

优点其实就是简单、快速

快速创建独立运行的Spring项目以及主流框架集成

使用嵌入式的server容器,应用无需打成WAR包

starters自动依赖与版本控制

有大量的自动配置,简化开发

准生产环境运行应用监控

与云计算的天然集成

SpringBoot主程序分析

//@SpringBootApplication标注这个类是一个Springboot的应用@SpringBootApplicationpublicclassSpringboot02DemoApplication{publicstaticvoidmain(String[]args){//将Springboot应用启动SpringApplication.run(Springboot02DemoApplication.class,args);}}

SpringBootApplication源码剖析,进入源码,结果发现其实它是一个组合注解

第一个SpringBootConfiguration注解:@SpringBootConfiguration--是SpringBoot配置类。下面有一个叫@Configuration:它是配置类,下面又有@Component,其实它就是一个注入组件。

第二个@EnableAutoConfiguration注解:是开启自配配置功能

@AutoConfigurationPackage//自动配置包

@Import(AutoConfigurationImportSelector.class)

public@interfaceEnableAutoConfiguration{}

@AutoConfigurationPackage:自动配置包,使用@Import(AutoConfigurationImportSelector.class)注解来完成的,它是springboot底层注解,作用是给容器中导入组件。

自动配置原理

(1)SpringBoot启动的时候首先加载主配置类,开启啦自动配置的功能(@EnableAutoConfiguration)

(2)自动配置功能@EnableAutoConfiguration的作用:它是利用了

@Import(AutoConfigurationImportSelector.class)给容器中导入一些组件。那么,他会给我们导入哪些组件呢?进入AutoConfigurationImportSelector源码看一下部分源码如下。

//@EnableAutoConfiguration注解

@AutoConfigurationPackage

/@Import(AutoConfigurationImportSelector.class)

public@interfaceEnableAutoConfiguration

@Import(AutoConfigurationImportSelector.class)自动配置导入选择

publicclassAutoConfigurationImportSelectorimplementsDeferredImportSelector,BeanClassLoaderAware,

ResourceLoaderAware,BeanFactoryAware,EnvironmentAware,Ordered{

//----部分源码省略----//

protectedAutoConfigurationEntrygetAutoConfigurationEntry(AnnotationMetadataannotationMetadata){

if(!isEnabled(annotationMetadata)){

returnEMPTY_ENTRY;

}

AnnotationAttributesattributes=getAttributes(annotationMetadata);

ListStringconfigurations=getCandidateConfigurations(annotationMetadata,attributes);

//----部分源码省略----//

}

SpringBoot源码-@EnableConfigurationProperties@ConfigurationProperties注解配置原理

1概述

2实例

3配置注入实现原理

使用过SpringBoot的都会知道,我们可以在application.properties文件中进行一系列的配置,该配置会被自动注入到我们需要使用的bean中,下面我们就介绍配置注入的实现原理。

首先,要知道在application.properties中的配置是通过BeanPostProcessor进行注入的,具体完成该功能的BeanPostProcessor实现类是ConfigurationPropertiesBindingPostProcessor。

本文接下来会介绍ConfigurationPropertiesBindingPostProcessor是在何时被加入到beanfactory中的,以及@EnableConfigurationProperties、@ConfigurationProperties注解的实现原理。

SpringBoot自动配置中充斥着大量使用通过application.properties进行扩展配置的实现,比如我们熟悉的MybatisAutoConfiguration:

下面我们在看下MybatisProperties类的定义:

通过如上的注解,MyBatis就可以获得我们在application.properties中的配置了,比如如下配置:

要了解配置注入的实现原理,首先要找到上文介绍到的ConfigurationPropertiesBindingPostProcessor是何时被注册到beanfactory中的,通过阅读源码发现,在spring.factories文件中有如下一行:

可见,是通过@EnableAutoConfiguration注解引入了相关的配置,@EnableAutoConfiguration通过@Import注解自动配置的原理这里不再介绍。我们看下ConfigurationPropertiesAutoConfiguration类的实现:

首先ConfigurationPropertiesAutoConfiguration被@Configuration注解,因此会在beanfactory加载时被作为配置类处理,具体在ConfigurationClassPostProcessor.postProcessBeanDefinitionRegistry调用ConfigurationClassParser.parse进行处理。

我们再看@EnableConfigurationProperties定义:

@EnableConfigurationProperties通过@Import(EnableConfigurationPropertiesImportSelector.class)向容器中注入了相关的处理类,@Import也是在ConfigurationClassParser.parse进行处理的。

EnableConfigurationPropertiesImportSelector类定义如下:

好了,到这里,我们已经知道注解@EnableConfigurationProperties.value中指定的配置类是如何被注入到beanfactory中的了,那么注解EnableConfigurationProperties.value中指定的配置类中的属性是如何从application.properties被注入的呢?比如上面的

对应配置如下:

这就是我们前面提到的BeanPostProcessor接口实现类ConfigurationPropertiesBindingPostProcessor类处理的,而ConfigurationPropertiesBindingPostProcessor则是通过上面EnableConfigurationPropertiesImportSelector中使用类ConfigurationPropertiesBindingPostProcessorRegistrar进行注册的:

ConfigurationPropertiesBindingPostProcessor是接口BeanPostProcessor的实现,会被ApplicationContext检测出来,在实例化每个bean时会被调用进行扩展处理。

SpringBoot自动装配原理

初看@SpringBootApplication有很多的注解组成,其实归纳就是一个"三体"结构,重要的只有三个Annotation:

(1)@Configuration注解

(2)@ComponentScan

(3)@EnableAutoConfiguration

从源码中可以知道,最关键的要属@Import(EnableAutoConfigurationImportSelector.class),借助EnableAutoConfigurationImportSelector,@EnableAutoConfiguration可以帮助SpringBoot应用将所有符合条件的@Configuration配置都加载到当前SpringBoot创建并使用的IoC容器。同时借助于Spring框架原有的一个工具类:SpringFactoriesLoader,@EnableAutoConfiguration就可以实现智能的自动配置。

总结:@EnableAutoConfiguration作用就是从classpath中搜寻所有的META-INF/spring.factories配置文件,并将其中org.springframework.boot.autoconfigure.EnableutoConfiguration对应的配置项通过反射(JavaRefletion)实例化为对应的标注了@Configuration的JavaConfig形式的IoC容器配置类,然后汇总为一个并加载到IoC容器。这些功能配置类要生效的话,会去classpath中找是否有该类的依赖类(也就是pom.xml必须有对应功能的jar包才行)并且配置类里面注入了默认属性值类,功能类可以引用并赋默认值。生成功能类的原则是自定义优先,没有自定义时才会使用自动装配类。

1、从spring-boot-autoconfigure.jar/META-INF/spring.factories中获取redis的相关配置类全限定名(有120多个的配置类)RedisAutoConfiguration,一般一个功能配置类围绕该功能,负责管理创建多个相关的功能类,比如RedisAutoConfiguration负责:JedisConnectionFactory、RedisTemplate、StringRedisTemplate这3个功能类的创建

2、RedisAutoConfiguration配置类生效的一个条件是在classpath路径下有RedisOperations类存在,因此springboot的自动装配机制会会去classpath下去查找对应的class文件。

3.如果pom.xml有对应的jar包,就能匹配到对应依赖class,

4、匹配成功,这个功能配置类才会生效,同时会注入默认的属性配置类@EnableConfigurationProperties(RedisProperties.class)

5.Redis功能配置里面会根据条件生成最终的JedisConnectionFactory、RedisTemplate,并提供了默认的配置形式@ConditionalOnMissingBean(name="redisTemplate")

6.最终创建好的默认装配类,会通过功能配置类里面的@Bean注解,注入到IOC当中

7.用户使用,当用户在配置文件中自定义时候就会覆盖默认的配置@ConditionalOnMissingBean(name="redisTemplate")

1.通过各种注解实现了类与类之间的依赖关系,容器在启动的时候Application.run,会调用EnableAutoConfigurationImportSelector.class的selectImports方法(其实是其父类的方法)--这里需要注意,调用这个方法之前发生了什么和是在哪里调用这个方法需要进一步的探讨

2.selectImports方法最终会调用SpringFactoriesLoader.loadFactoryNames方法来获取一个全面的常用BeanConfiguration列表

3.loadFactoryNames方法会读取FACTORIES_RESOURCE_LOCATION(也就是spring-boot-autoconfigure.jar下面的spring.factories),获取到所有的Spring相关的Bean的全限定名ClassName,大概120多个

4.selectImports方法继续调用filter(configurations,autoConfigurationMetadata);这个时候会根据这些BeanConfiguration里面的条件,来一一筛选,最关键的是

@ConditionalOnClass,这个条件注解会去classpath下查找,jar包里面是否有这个条件依赖类,所以必须有了相应的jar包,才有这些依赖类,才会生成IOC环境需要的一些默认配置Bean

5.最后把符合条件的BeanConfiguration注入默认的EnableConfigurationPropertie类里面的属性值,并且注入到IOC环境当中

spring表达式注入原理

开门见山。SpringBean的注入原理:

spring是在配置类需要指定扫描包,然后递归得到下面所有的文件;(springboot默认启动类和兄弟目录下面所有的包文件)

包名+文件名=类全限定名;

calss.from加载到内存当中,得到字节码(class);

判断这个类的脑门上是否有注解(就是类的头顶上),有注解的话,就把这个类先put到Map里面(ResourcesMap和autowiredMap各一份);

如果这个类下面有注解的话@Resources就去ResourcesMap里面去遍历,得到对象,然后注入进来,@Autowired就去AutowiredMap里面去遍历,然后得到对象,注入进来;

实体类脑门上没有注解是没有注入到IOC的。

SpringBoot运行原理

SpringBoot是一个基于Spring开发,集成了大量第三方库配置的javaweb开发框架

pom.xml

父依赖

其中它主要是依赖一个父项目,主要是管理项目的资源过滤及插件。以后我们导入依赖默认是不需要写版本的。

启动器spring-boot-starter

springboot-boot-starter-xxx:spring-boot的场景启动器

spring-boot-starter-web:帮我们导入了web模块正常运行所依赖的组件。

springBoot将所有的功能场景都抽取出来,做成一个个的starter(启动器),只需要在项目中引入这些starter即可,所有相关的依赖都会被引进来,我们要用什么功能就导入什么样的场景启动器即可。

@SpringBootApplication

作用:标注在某个类上说明这个类是SpringBoot的主配置类,SpringBoot运行这个类的main方法来启动SpringBoot应用。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
逆水寒手游庄园怎么邀请好友同住 逆水寒手游 逆水寒不同区可以一起组队吗? 逆水寒手游 逆水寒怎么进入好友世界? 逆水寒手游 逆水寒怎么去别人的庄园? 使用puppeteer实现将htmll转成pdf 内卷时代下的前端技术-使用JavaScript在浏览器中生成PDF文档 【译】将HTML转为PDF的几种实现方案 变形金刚08动画怎么样 变形金刚08动画的问题 变形金刚08动画日语版剧情介绍 NBA球星肤色白色其实是黑人[小里弗斯为什么是白人] 容器装着水,进入气体,则 液面会上升还是下降,为什么? 密封的 密封容器中充满液体,热胀冷缩产生的压力怎么计算 三星s7edge支付宝用不了要拍摄头像验证 有哪些带有"水"的意思的男英文名? 燥热季节到了,你真的清楚什么是海蓝宝? 海蓝宝的英文名称是什么? 钩针毛线小物的作品目录 钩针毛线小物图书目录 Proxy SwitchyOmega在chrome安装教程 crx header invalid解决方法 wps2012文字和表格自动换行快捷键 WPS2012上下标的快捷键是什么??? 拜托大家看下WPS2012里的Word里的字数统计在哪里 熟悉的看下吧,不... 请高手解决问题,我把wps2010升级成wps2012版,之前都能打开,升级后都打... ...排挡店名。最好三个字大气点的,能带火字或者偏旁部首 取名字 店名 三个字或者两个字 必须有一个字的偏旁是火 一个字的偏旁... 请问我给一家公司画了插画却一直不给我钱是怎么回事?我难道被骗了? 培训项目预付款多少比例 为什么镭风HD6770用鲁大师检测却是AMD的HD6700呢? Python仿真需要学多少东西(如何用python做物理仿真) 江苏建沭建设有限公司怎么样? 请问谁知道江苏省宿迁市沭阳县有个钱什么镇的没有?知道的请联系我? 沭阳县新冠疫苗接种点及预约咨询电话 胸大下垂能恢复吗 ...她讲自己是处女..那洗澡的时候为什么胸部是下垂的啊 ...检查其中做了抗核抗体全套检查中抗核抗体是1:100阳性其他15项都是... ...开发商说消防图纸还没出来,是不是有什么水分? 医学检验专业英语内容简介 如果接下一个消防工程,没有建筑图纸,怎么设计消防图纸,怎么办?请具 ... ...的是医学检验的,有谁可以告诉我学这个专业要英语好吗?我英语很差... 湖北中医药大学医学检验技术专业 1997湖南省高考录取分数线 水芹菜的功效与作用 水芹菜有哪些好处 水芹菜营养价值有多高? 吃水芹菜有哪些好处 吃水芹菜有什么营养元素 野生水芹菜有毒吗?带你了解野生水芹菜的功效! 当女人说“呵,原来是我把自己太当回事儿了”这是什么意思出于什么样的目... ...玉儿才嫁给他啊 求解啊 那天大汉是不是喝醉酒了 才会这样子..._百... 我的ip是192.168.1.102 网关192.168.1.1 dns是什么 ? 两个都要啊