范文健康探索娱乐情感热点
投稿投诉
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文
国学影视

深入理解springboot的自动注入

  一、开篇
    在平时的开发过程中用的最多的莫属springboot了,都知道springboot中有自动注入的功能,在面试过程中也会问到自动注入,你知道自动注入是怎么回事吗,springboot是如何做到自动注入的,自动注入背后的原理是什么,今天来分析下springboot的自动注入,希望这篇文章可以解除大家心中的疑惑。 二、详述2.1、什么是自动注入
    天天将自动注入,你真正明白自动注入是怎么回事吗?举个例子来说,我们要在springboot中使用mybatis,之前的做法是什么?
    1、引入依赖;
    2、在配置文件中配置配置类;
    3、写mybatis的配置文件或注解;
    在springboot中这个步骤就减少了,减少的是第二步,不用再写一堆配置类了,步骤简化为:
    1、引入依赖;
    2、写mybatis的配置文件或注解;
    也就是说无需再搞配置类了,就比如之前的"SqlSessionFactoryBean",现在不用配置了,springboot为我们做了这些工作,现在看springboot引入mybatis需要加入的依赖,                       org.mybatis.spring.boot             mybatis-spring-boot-starter             2.1.3                                          mysql             mysql-connector-java             8.0.26         
    我们加入mybatis和数据库的驱动依赖,因为mybatis要使用数据库连接,所以这里少不了mysql的数据库驱动。重点看mybatis的这个依赖和之前的是不一样的,这个是"mybatis-spring-boot-starter",再看这个依赖中都有哪些jar,
    除了常见的mybatis及mybatis-spring还有一个mybatis-spring-boot-autoconfigure,这个就是今天的主角。 2.2、springboot读取spring.facotries文件(可跳过该节)
    前边说到今天的主角是"mybatis-spring-boot-autoconfigure",其实还有很多这样的依赖,大多数第三方自己实现的都会有这样一个依赖比如,前边自己实现的starter中就有这样一个"customer-spring-boot-autoconfigurer",还有很多都是springboot自己实现的,所以无需这样的依赖。
    要想知道springboot是如何进行自动注入的,唯一的方式是debug,现在开始debug之旅吧。 2.2.1、SpringApplication构造方法
    springboot的启动很简单,就是下面这样一行代码 SpringApplication.run(BootServer.class);
    要跟着这样一行代码走下去,追踪到了这样一句, public static ConfigurableApplicationContext run(Class<?>[] primarySources, String[] args) { 		return new SpringApplication(primarySources).run(args); 	}
    可以看的会new一个SpringApplication的实例,然后再调用其run方法,先看下new方法做了什么,最终调用的是下面的构造方法, public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) { 		this.resourceLoader = resourceLoader; 		Assert.notNull(primarySources, "PrimarySources must not be null"); 		this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources)); 		this.webApplicationType = WebApplicationType.deduceFromClasspath();          //设置初始化器,很重要 		setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));          //设置监听器,很重要 		setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class)); 		this.mainApplicationClass = deduceMainApplicationClass(); 	}
    我在上面 做了注释,重点看注释部分的代码; 2.2.2、setInitializers()方法
    该方法从方法名上看是要设置初始化器,其中 getSpringFactoriesInstances(ApplicationContextInitializer.class) 是重点。其方法定义如下, private  Collection getSpringFactoriesInstances(Class type, Class<?>[] parameterTypes, Object... args) { 		ClassLoader classLoader = getClassLoader(); 		// Use names and ensure unique to protect against duplicates         //SpringFactoriesLoader.loadFactoryNames是重点 		Set names = new LinkedHashSet<>(SpringFactoriesLoader.loadFactoryNames(type, classLoader)); 		List instances = createSpringFactoriesInstances(type, parameterTypes, classLoader, args, names); 		AnnotationAwareOrderComparator.sort(instances); 		return instances; 	}
    看SpringFactoriesLoader.loadFactoryNames方法, public static List loadFactoryNames(Class<?> factoryType, @Nullable ClassLoader classLoader) { 		String factoryTypeName = factoryType.getName();          //loadSpringFactories(classLoader)方法是重点 		return loadSpringFactories(classLoader).getOrDefault(factoryTypeName, Collections.emptyList()); 	}
    把断点放在loadSpringFactroies方法内,
    从上面的debug结果可以看到使用AppClassLoader读取"FACTORIES_RESOURCE_LOCATION"处的资源,AppClassLoader大家都很熟悉,就说应用类加载器,常量"FACTORIES_RESOURCE_LOCATION"指的是, /** 	 * The location to look for factories. 	 * 

Can be present in multiple JAR files. */ public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";     jar下的"META-INF/spring.factories"文件,也就是说要读取项目中jar包中的"META-INF/spring.factories"文件的内容,我在spring-boot-2.3.3.RELEASE.jar中找到这样一个文件,仅截个图,详细内容可以自己查看,     可以看到是一些列的键值对,我们看下loadSpringFactories方法最后的返回值,     这个返回值是,项目中所有jar下META-INF/spring.factories文件中的键值对组成的map。回到loadFactoryNames方法处     该方法需要的是key为"org.springframework.context.ApplicationContextInitializer"的value,该value的值有这样7个   这样我们把setInitializers方法就分析完了,其主要就是从jar包中的META-INF/spring.factories文件中获取org.springframework.context.ApplicationContextInitializer对应的值。下面看setListeners方法 2.2.3、setListeners()方法     该方法和setInitializers方法是类似的,     重点是其参数不一样,该方法的参数是ApplicationListener.class,也就是要找出org.springframework.context.ApplicationListener在spring.factories中的配置,     本人核实过这些的确是从spring.factories文件中读取的,和其内容是一致的。   写到这里其实和自动注入没有关系,如果说有关系的话是,这里 认识了一个关键的类"SpringFactoriesLoader",该类的作用就是读取jar包中META-INF/spring.facotries文件的内容 。在后边的自动注入中还会出现该类的影子。继续向前。 2.3、自动注入的原理2.3.1、@SpringBootApplication注解     在启动springboot程序的时候在程序的入口都会有写上@SpringBootApplication的注解, package com.my.template; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; /** * 启动类 * @date 2022/6/3 21:32 */ @SpringBootApplication public class BootServer { public static void main(String[] args) { try { SpringApplication.run(BootServer.class); }catch (Exception e){ e.printStackTrace(); } } }     看下该注解的定义,     在该注解上还有@SpringBootConfiguration、@EnableAutoConfiguration、@ComponentScan三个注解,今天重点看@EnableAutoConfiguration注解。 2.3.2、@EnableAutoConfiguration注解     该注解便是自动注入的核心注解,     重点是该注解上的下面这句话, @Import(AutoConfigurationImportSelector.class)     看下AutoConfigurationImportSelector类,该类中有这样一个方法,和自动注入是相关的, protected List getCandidateConfigurations(AnnotationMetadata metadata, AnnotationAttributes attributes) { List 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; }   很属性的SpringFactoriesLoader类又出现了,还是很熟悉的loadFactoryNames方法,这次的方法参数是getSpringFactoriesLoaderFactoryClass()方法, /** * Return the class used by {@link SpringFactoriesLoader} to load configuration * candidates. * @return the factory class */ protected Class<?> getSpringFactoriesLoaderFactoryClass() { return EnableAutoConfiguration.class; }     所以SpringFactoriesLoader.loadFactoryNames是要从META-INF/spring.factories中获取key为"org.springframework.boot.autoconfigure.EnableAutoConfiguration"的value,这里可以看到有很多,从中还可以找到我自定义的和myatis的。   也就是说要把这些配置类加到spring的容器中。现在有个问题这些配置都会生效吗? 2.3.3、这些配置类都会生效吗?     上面说到自动配置会加载很多的配置类,但是这些类都会生效吗?答案是不会的,只会在特定情况下生效,以MybatisAutoConfiguration为例,     可以看的该类上有很多注解,      @ConditionalOnClass, 当类路径中存在某个类标识该注解的类才会生效,也就是只有存在SqlSessionFactory、SqlSessionFactoryBean才会解析MybatisAutoConfiguration类。换句话说,要有mybatis、mybatis-spring的jar包。     @ConditionaleOnSigleCanidate, 需要一个单例bean     @EnableConfigurationProperties 读取配置文件,也就是application.properites     @AutoConfigureAfter 自动配置在某个类之后   现在我们知道了一个XXAutoConfiguration类是否会生效还要看其上面的注解是怎么定义的。 三、总结     本文主要分析了springboot的自动注入原理,     1、注解@SpringBootApplication中含有三个注解,其中@EnabelAutoConfiguration和自动配置有关;     2、@EnableAutoConfiguration会读取所有jar下META-INF/spring.factories文件的内容,获取"org.springframework.boot.autoconfigure.EnableAutoConfiguration"的配置,把这些配置注入到容器;     3、@EnableAutoConfiguration注入的类是否生效,需要看其上面的注解,主要配合@ConditionaleXXX注解使用;


春天吃3白,一年病不来,3白指啥,立春后,别忘记吃从今天起记录我的2023导读春天吃3白,一年病不来,3白指啥?立春后,别忘吃,应季而食受益多!今年的立春来得特别晚,以往的立春一般是在腊月,而今年的立春则是在正月十四特别晚的一年。1月每经品牌100涨7。88机构看好A股春季行情每经记者刘明涛每经编辑彭水萍兔年首周,A股主要股指走势略低于预期,沪指与深成指表现平平,涨跌不一,每经品牌100指数同样冲高回落,周跌1。94,以985。09点报收,退守1000点立春之后,应该喝什么汤养生?立春,为二十四节气之首。立,是开始之意春,代表着温暖生长。立春过后,由寒转暖,早晚温差大,容易生病,这个季节容易出现春困,肝火旺盛,湿气重,春季养生要以养肝,祛湿,健脾为主,那么,科普保温杯泡茶,喝了有毒还致癌?到底能不能喝?解答来了俗话说人到中年不由已,保温杯里泡枸杞保温杯成了不少人的标配对养生一族来说,保温杯的最佳拍档除了枸杞,还有各类茶叶图源网络日常工作生活中,很多小伙伴都有用保温杯泡茶的习惯,然而,有些痛风找上门的三大原因,快看你有没有中招近些年来,痛风已经逐渐成为常见的疾病之一,一说起痛风,大多数人脑海里出现的就是疼痛以及关节畸形,而痛风对人体的危害却远远不止这些,严重的痛风还会导致肾功能受损,增加其它疾病的风险等中医治疗生气型冠心病经验方1则活血祛瘀,行气止痛冠心病和生气的关系是非常密切的,人在生气发脾气时,交感神经兴奋,心率加快,血压升高。如果一个人长期发脾气,也就意味着他的交感神经长期处于兴奋状态,血管处于收缩紧张的状态要多一些,这吸收优质蛋白质补充丰富维生素来源湛江日报湛江新闻网感染病毒后,日常居家康复显得非常重要,尤其要提升自身免疫力。如何通过饮食提升免疫力?湛江中心人民医院营养科李新梅副主任医师建议,吃营养丰富的饮食,注意补充适量带你了解中医第二集中医把脉能把出什么?中医望闻问切(中医把脉能把出来什么?)中医四诊法左手心肝肾,右手肺脾命。六个部位必须固定在这地方,这就是中医摸脉的疗效。可以看看你五脏六腑的气血盛衰,用三个指头就能够摸出比ct核磁读书笔记之八1,人与人的根本差异,就在于五藏神明的不同!2,所谓五藏神是什么?心之神,叫神,心神为神,肝神为魂,肺神为魄。所以,魂魄在中医里,是真实的一种存在,是生命能量的一种表现,而不是什么学会晒太阳,胜过饮参汤,怎么晒最有效?晒太阳的好处01hr促进钙吸收万万没想到晒太阳还有好处可以收获,许多人上了年纪钙质流失,在缺钙影响下骨骼密度下降,可能会骨头变得脆弱,长期下去有发展成骨质疏松症的可能。而适当晒太阳想补肾先补脾,简单两味药,补脾益肾效果好大家好,我是刘医生,补肾,可以说是很多人都很执着的一个点,上了年纪之后不少人会自己买一点补肾的中成药来吃,中医上认为肾对人体有非常重要的作用,因为肾主藏精,肾精是人体生长发育防御病
无论假期你的自驾游旅程有多远,若经过这些城市,请留1天给TA!摘自汽车自驾游杂志城市可能是你我平日里就生活与工作的地方所以遇到假期我们总会选择逃离但别人的城市很可能就是我们此行的目的地之一也有可能是途经的落脚地不妨留一天时间给TA即便匆匆而过(社会)江畔露营乐享春光连日来,湖南省长沙市春光明媚微风和煦,不少市民来到湘江畔露营休闲,乐享春光。4月16日,市民在长沙市开福区湘江畔露营休闲(无人机照片)。新华社记者陈振海摄4月16日,市民在长沙市开豆瓣9。2优酷锵锵行天下第三季居国内口碑综艺榜首位近日,由优酷独播的深度文化体验旅行脱口秀锵锵行天下第三季上线播出。节目踏访诗画江南,在领略独特美景的同时,品味历史,对话古今,收获了不少好评。豆瓣显示,该节目评分9。2,位居国内口暑假和朋友去呼伦贝尔玩,路线怎么安排更合适?有哪些注意事项?暑假是一个与朋友们共度美好时光的绝佳时期,呼伦贝尔以其壮美的自然风光和丰富的人文景观成为了越来越多游客的向往之地。为了让你的呼伦贝尔之旅更加完美,我为你量身定制了一份五天的行程攻略大足宝顶镇古佛村打造特色民宿大足区宝顶镇古佛村是重庆市级脱贫村,为了加快乡村振兴步伐,持续壮大村集体经济,近日,古佛村开办了一个名叫古佛学堂的民宿,发展旅游业。环境优美风格复古的乡村民宿一经问世,便受到了游客31天亚非欧豪华邮轮之旅10月启航,现在购票最低仅49990元地中海豪华邮轮之旅,10月25日从武汉长沙出发,一价全含(签证机票酒店船票)49990元起31天旅程,带您穿越2片大洋3个大洲10个国家,探访西方文明建立的中心英国法国意大利,了解云南2022年财政收入15市州负增长,昆明大理德宏减幅超142022年云南省的经济增长总体来说还是比较不错的,GDP增速处于全国中上游,经济总量虽然没有超过辽宁省,但差距已经微乎其微。但是在财政收入层面上,云南省的表现可以说是极度低迷,远没春至金川梨花香来源人民网人民日报海外版柳色黄金嫩,梨花白雪香。春分前夕,我被邀去参加金川县举办的古树梨花节。对于这些年如雨后春笋般兴起的这节那节,我始终提不起兴致。何况我知道,位于成都西北部的金四川纳溪绿色茶园宛如大地指纹来源原创稿茶农忙采摘。廖胜春摄茶农忙采摘。廖胜春摄茶农忙采摘。廖胜春摄茶园风景如画。廖胜春摄绿色茶园宛如大地指纹。廖胜春摄绿色茶园宛如大地指纹。廖胜春摄茶园风景如画。廖胜春摄眼下,春笋是发物,肺癌吃了会复发吗?提醒这5物,少吃或不吃如今像一些肺癌的情况也是比较常见的,严重影响人们的健康,很多人也是比较多的情况,如果没有得到及时治疗的话,很容易发展到晚期,对身体造成严重的影响。而关于肺癌患者在平时的饮食方面也是亲水行丨亲水踏青可以有!16区美丽幸福河湖打卡点,邀你共赴水之旅静安区东茭泾最美人间四月天不负春光与时行随着河湖治理成效日益显现河湖水质持续向好河湖颜值不断提升上海16区美丽河湖成为了靓丽的风景线亲水行的好去处水因城而活城因水而美暖风拂过绿水相伴在这亲水踏