初探Spring源码之Spring Bean的生命周期
写在前面的话:
学无止境,写博客纯粹是一种乐趣而已,把自己理解的东西分享出去,不意味全是对的,欢迎指正!
1 annotationconfigapplicationcontext applicationcontext = new annotationconfigapplicationcontext();
-
实例了一个 annotationconfigapplicationcontext对象,spring中出来注解bean定义的类有两个:
annotationconfigapplicationcontext和annotationconfigwebapplicationcontex annotationconfigwebapplicationcontext是annotationconfigapplicationcontext的web版本,两者的用法以及对注解的处理方式几乎没有什么差别,通过分析这个类我们知道注册一个bean到spring容器有两种办法一、直接将注解bean注册到容器中:(参考)public void register(class<?>... annotatedclasses)但是直接把一个注解的bean注册到容器当中也分为两种方法:
1、在初始化容器时注册并且解析
2、也可以在容器创建之后手动调用注册方法向容器注册,然后通过手动刷新容器,使得容器对注册的注解bean进行处理。
思考:为什么@profile要使用这类的第2种方法?
因为需要通过applicationcontext.getenvironment()这样的方式设置环境或者获取环境变量
二、通过扫描指定的包及其子包下的所有类扫描其实同上,也是两种方法,初始化的时候扫描,和初始化之后再扫描
1 public annotationconfigapplicationcontext() {//0 2 /** 3 * 父类的构造方法 4 * 创建一个读取注解的bean定义读取器 5 * 什么是bean定义?beandefinition 6 */ 7 this.reader = new annotatedbeandefinitionreader(this); //1 8 9 //可以用来扫描包或者类,继而转换成bd 10 //但是实际上我们扫描包工作不是scanner这个对象来完成的 11 //是spring自己new的一个classpathbeandefinitionscanner 12 //这里的scanner仅仅是为了程序员能够在外部调用annotationconfigapplicationcontext对象的scan方法 13 this.scanner = new classpathbeandefinitionscanner(this); //2 14 }
注意: * 初始化一个bean的读取和扫描器 * 何谓读取器和扫描器参考上面的属性注释
* 默认构造函数,如果直接调用这个默认构造方法,需要在稍后通过调用其register()
* 去注册配置类(javaconfig),并调用refresh()方法刷新容器,
* 触发容器对注解bean的载入、解析和注册过程
-
实例化annotationconfigapplicationcontext会先实例化父类genericapplicationcontext,然后初始化一个bean工厂,defaultlistablebeanfactory
1 public genericapplicationcontext() { 2 this.beanfactory = new defaultlistablebeanfactory(); 3 }
-
1处,实例化一个beandefinition读取器 annotatedbeandefinitionreader
1 /** 2 * 这里的beandefinitionregistry registry是通过在annotationconfigapplicationcontext 3 * 的构造方法中传进来的this 4 * 由此说明annotationconfigapplicationcontext是一个beandefinitionregistry类型的类 5 * 何以证明我们可以看到annotationconfigapplicationcontext的类关系: 6 * genericapplicationcontext extends abstractapplicationcontext implements beandefinitionregistry 7 * 看到他实现了beandefinitionregistry证明上面的说法,那么beandefinitionregistry的作用是什么呢? 8 * beandefinitionregistry 顾名思义就是beandefinition的注册器 9 * 那么何为beandefinition呢?参考beandefinition的源码的注释 10 * @param registry 11 */ 12 public annotatedbeandefinitionreader(beandefinitionregistry registry) { 13 this(registry, getorcreateenvironment(registry)); 14 } 15 public annotatedbeandefinitionreader(beandefinitionregistry registry, environment environment) { 16 assert.notnull(registry, "beandefinitionregistry must not be null"); 17 assert.notnull(environment, "environment must not be null"); 18 this.registry = registry; 19 this.conditionevaluator = new conditionevaluator(registry, environment, null); 20 annotationconfigutils.registerannotationconfigprocessors(this.registry); 21 }
annotationconfigutils.registerannotationconfigprocessors(this.registry);
1 public static void registerannotationconfigprocessors(beandefinitionregistry registry) { 2 registerannotationconfigprocessors(registry, null);
以上空壳方法,调用以下方法
1 1 public static set<beandefinitionholder> registerannotationconfigprocessors( 2 2 beandefinitionregistry registry, @nullable object source) { 3 3 //主要是为了获得工厂对象,实例化annotationconfigapplicationcontext的时候会调用父类 4 4 //genericapplicationcontext的构造器去实例化defaultlistablebeanfactory 5 5 //这里的registry其实际是genericapplicationcontext的子类实例,向上转型取得工厂的属性 6 6 //从而得到 beanfactory对象 7 7 defaultlistablebeanfactory beanfactory = unwrapdefaultlistablebeanfactory(registry);
获得工厂的具体逻辑
private static defaultlistablebeanfactory unwrapdefaultlistablebeanfactory(beandefinitionregistry registry) { if (registry instanceof defaultlistablebeanfactory) { return (defaultlistablebeanfactory) registry; } else if (registry instanceof genericapplicationcontext) { //这里在annotationconfigapplicationcontext初始化的时候this() //方法中调用了父类genericapplicationcontext的时候new了一个defaultlistablebeanfactory对象 //下面代码返回这个对象 return ((genericapplicationcontext) registry).getdefaultlistablebeanfactory(); } else { return null; } }
这段代码主要是为解析是否含有需要排序的注解
1 if (beanfactory != null) { 2 if (!(beanfactory.getdependencycomparator() instanceof annotationawareordercomparator)) { 3 //annotationawareordercomparator主要能解析@order注解和@priority 4 beanfactory.setdependencycomparator(annotationawareordercomparator.instance); 5 } 6 if (!(beanfactory.getautowirecandidateresolver() instanceof contextannotationautowirecandidateresolver)) { 7 //contextannotationautowirecandidateresolver提供处理延迟加载的功能 8 beanfactory.setautowirecandidateresolver(new contextannotationautowirecandidateresolver()); 9 } 10 }
org.springframework.context.annotation.internalconfigurationannotationprocessor这个是beandefinition
的一个beanname, 具体的类是configurationclasspostprocessor,它在beandefinition中表现的是一个后置处理器(重要),是spring的核心类之一。
1 set<beandefinitionholder> beandefs = new linkedhashset<>(8); 2 //beandefinitio的注册,这里很重要,需要理解注册每个bean的类型 3 //org.springframework.context.annotation.internalconfigurationannotationprocessor 4 //这个是spring生命周期非常重要的一个类 5 if (!registry.containsbeandefinition(configuration_annotation_processor_bean_name)) { 6 //需要注意的是configurationclasspostprocessor的类型是beandefinitionregistrypostprocessor 7 //而 beandefinitionregistrypostprocessor 最终实现beanfactorypostprocessor这个接口 8 //因此需要对这两种类型的进行区分处理 9 10 //将一个类变成beandefinition 11 rootbeandefinition def = new rootbeandefinition(configurationclasspostprocessor.class); 12 def.setsource(source); 13 //这里是将bd注册到beanfactory的beandefinitionmap容器中,并返回一个 14 //beandefinitionholder对象 15 beandefs.add(registerpostprocessor(registry, def, configuration_annotation_processor_bean_name)); 16 }
实际上上面的代码和以下的代码主要往defaultlistablebeanfactory中的beandefinitionmap 中放入以下所列举的6个后置处理器。其中configurationclasspostprocessor是核心
0.org.springframework.context.annotation.configurationclasspostprocessor(重要)
1.org.springframework.beans.factory.annotation.autowiredannotationbeanpostprocessor
2.org.springframework.beans.factory.annotation.requiredannotationbeanpostprocessor
3.org.springframework.context.annotation.commonannotationbeanpostprocessor
4.org.springframework.context.event.eventlistenermethodprocessor
5.org.springframework.context.event.defaulteventlistenerfactory
1 if (!registry.containsbeandefinition(autowired_annotation_processor_bean_name)) { 2 //autowiredannotationbeanpostprocessor 实现了 mergedbeandefinitionpostprocessor 3 //mergedbeandefinitionpostprocessor 最终实现了 beanpostprocessor 4 rootbeandefinition def = new rootbeandefinition(autowiredannotationbeanpostprocessor.class); 5 def.setsource(source); 6 beandefs.add(registerpostprocessor(registry, def, autowired_annotation_processor_bean_name)); 7 } 8 9 if (!registry.containsbeandefinition(required_annotation_processor_bean_name)) { 10 rootbeandefinition def = new rootbeandefinition(requiredannotationbeanpostprocessor.class); 11 def.setsource(source); 12 beandefs.add(registerpostprocessor(registry, def, required_annotation_processor_bean_name)); 13 } 14 15 // check for jsr-250 support, and if present add the commonannotationbeanpostprocessor. 16 if (jsr250present && !registry.containsbeandefinition(common_annotation_processor_bean_name)) { 17 rootbeandefinition def = new rootbeandefinition(commonannotationbeanpostprocessor.class); 18 def.setsource(source); 19 beandefs.add(registerpostprocessor(registry, def, common_annotation_processor_bean_name)); 20 } 21 22 // check for jpa support, and if present add the persistenceannotationbeanpostprocessor. 23 if (jpapresent && !registry.containsbeandefinition(persistence_annotation_processor_bean_name)) { 24 rootbeandefinition def = new rootbeandefinition(); 25 try { 26 def.setbeanclass(classutils.forname(persistence_annotation_processor_class_name, 27 annotationconfigutils.class.getclassloader())); 28 } 29 catch (classnotfoundexception ex) { 30 throw new illegalstateexception( 31 "cannot load optional framework class: " + persistence_annotation_processor_class_name, ex); 32 } 33 def.setsource(source); 34 beandefs.add(registerpostprocessor(registry, def, persistence_annotation_processor_bean_name)); 35 } 36 37 if (!registry.containsbeandefinition(event_listener_processor_bean_name)) { 38 rootbeandefinition def = new rootbeandefinition(eventlistenermethodprocessor.class); 39 def.setsource(source); 40 beandefs.add(registerpostprocessor(registry, def, event_listener_processor_bean_name)); 41 } 42 43 if (!registry.containsbeandefinition(event_listener_factory_bean_name)) { 44 rootbeandefinition def = new rootbeandefinition(defaulteventlistenerfactory.class); 45 def.setsource(source); 46 beandefs.add(registerpostprocessor(registry, def, event_listener_factory_bean_name)); 47 }
疑问1:普通的对象是怎么变成beandefinition的呢?
//将一个类变成beandefinition rootbeandefinition def = new rootbeandefinition(configurationclasspostprocessor.class);
疑问2:对象变成beandefinition之后又是怎么注册到bean工厂的呢?
1 private static beandefinitionholder registerpostprocessor( 2 beandefinitionregistry registry, rootbeandefinition definition, string beanname) { 3 4 definition.setrole(beandefinition.role_infrastructure); 5 //将bd注册到工厂的beandefinitionmap中 6 registry.registerbeandefinition(beanname, definition); 7 //beandefinitionholder 只是封装参数使用 8 return new beandefinitionholder(definition, beanname); 9 }
registry.registerbeandefinition(beanname, definition);这句代码将beandefinition注册到beanfactory中
注意这里的registry注册器一直都是annotationconfigapplicationcontext对象,该类中没有registerbeandefinition() ,因此会调用父类genericapplicationcontext的registerbeandefinition()方法注册beandefinition。
1 public void registerbeandefinition(string beanname, beandefinition beandefinition) 2 throws beandefinitionstoreexception { 3 4 this.beanfactory.registerbeandefinition(beanname, beandefinition); 5 }
调用org.springframework.beans.factory.support.defaultlistablebeanfactory#registerbeandefinition()的方法执行以下逻辑
1 public void registerbeandefinition(string beanname, beandefinition beandefinition) 2 throws beandefinitionstoreexception {
不管genericbeandefinition,还是rootbeandefinition都继承了abstractbeandefinition,因此会执行以下逻辑
1 assert.notnull(beandefinition, "beandefinition must not be null"); 2 //beandefinition的所有实现类都继承了abstractbeandefinition,因此会执行以下的检验逻辑 3 if (beandefinition instanceof abstractbeandefinition) { 4 try { 5 ((abstractbeandefinition) beandefinition).validate(); 6 } 7 catch (beandefinitionvalidationexception ex) { 8 throw new beandefinitionstoreexception(beandefinition.getresourcedescription(), beanname, 9 "validation of bean definition failed", ex); 10 } 11 }
执行一些逻辑判断,打印一些log,这些不重要
1 //根据beanname从容器中取出bd,判断是否已经注册了的各种校验 2 beandefinition existingdefinition = this.beandefinitionmap.get(beanname); 3 if (existingdefinition != null) { 4 //是否允许覆盖原有的bean 默认是不覆盖 5 if (!isallowbeandefinitionoverriding()) { 6 throw new beandefinitionstoreexception(beandefinition.getresourcedescription(), beanname, 7 "cannot register bean definition [" + beandefinition + "] for bean '" + beanname + 8 "': there is already [" + existingdefinition + "] bound."); 9 } 10 else if (existingdefinition.getrole() < beandefinition.getrole()) { 11 // e.g. was role_application, now overriding with role_support or role_infrastructure 12 if (logger.iswarnenabled()) { 13 logger.warn("overriding user-defined bean definition for bean '" + beanname + 14 "' with a framework-generated bean definition: replacing [" + 15 existingdefinition + "] with [" + beandefinition + "]"); 16 } 17 } 18 else if (!beandefinition.equals(existingdefinition)) { 19 if (logger.isinfoenabled()) { 20 logger.info("overriding bean definition for bean '" + beanname + 21 "' with a different definition: replacing [" + existingdefinition + 22 "] with [" + beandefinition + "]"); 23 } 24 } 25 else { 26 if (logger.isdebugenabled()) { 27 logger.debug("overriding bean definition for bean '" + beanname + 28 "' with an equivalent definition: replacing [" + existingdefinition + 29 "] with [" + beandefinition + "]"); 30 } 31 } 32 //加入到beandefinitionmap当中,正常第一次不会走到这里 33 this.beandefinitionmap.put(beanname, beandefinition); 34 } 35 else { 36 if (hasbeancreationstarted()) { 37 // cannot modify startup-time collection elements anymore (for stable iteration) 38 synchronized (this.beandefinitionmap) { 39 //这里加锁的意义是防止正在创建的bean被修改。 40 this.beandefinitionmap.put(beanname, beandefinition); 41 list<string> updateddefinitions = new arraylist<>(this.beandefinitionnames.size() + 1); 42 updateddefinitions.addall(this.beandefinitionnames); 43 updateddefinitions.add(beanname); 44 this.beandefinitionnames = updateddefinitions; 45 if (this.manualsingletonnames.contains(beanname)) { 46 set<string> updatedsingletons = new linkedhashset<>(this.manualsingletonnames); 47 updatedsingletons.remove(beanname); 48 this.manualsingletonnames = updatedsingletons; 49 } 50 } 51 }
初次注册beandefinition的会执行
1 else { 2 // still in startup registration phase 3 //初次注册会执行这段逻辑,90%的注册会走到这里 4 this.beandefinitionmap.put(beanname, beandefinition); 5 this.beandefinitionnames.add(beanname); 6 this.manualsingletonnames.remove(beanname); 7 } 8 this.frozenbeandefinitionnames = null;
至此,实例化一个annotationbeandefinitionreader会注册6个后置处理器,为什么注册这些后置处理器,有什么作用,会在后续的spring源码解析中进行讲解。另外核心的类configurationclasspostprocessor的作用是什么?
-
2处,实例化一个beandefinition 扫描器classpathbeandefinitionscanner
beandefinition扫描器这里不做多介绍,因为这里的扫描器主要是为了给程序员自己定义一个类的扫描器,用来扫描我们自定义的加了注解类。
-
上一篇: php函数指定默认值方法的小例子
推荐阅读
-
初探Spring源码之Spring Bean的生命周期
-
Spring基本用法5——容器中Bean的生命周期 博客分类: Spring Spring容器Bean生命周期Spring基本用法
-
spring-boot-2.0.3不一样系列之源码篇 - run方法(四)之prepareContext,绝对有值得你看的地方
-
spring5源码解析—Bean的获取流程
-
Spring之Bean生命周期精简版
-
spring源码深度解析— IOC 之 容器的基本实现
-
深入了解Spring的Bean生命周期
-
荐 Spring源码之容器的基本实现:通过Xml配置装载Bean
-
java JSP开发之Spring中Bean的使用
-
Spring源码解密之默认标签的解析