1 定义bean的方式

常见的定义Bean的方式有:

通过xml的方式,例如:

?

通过注解的方式,在Class上使用@Component等注解,例如

?

通过在@Configuration类下的@Bean的方式,例如

?

虽然这三种定义Bean的方式不一样,对应的处理细节也不一样,但是从大的逻辑上来看,都是一样。主要的流程如下图: 最关键的就是问题就是这么去找到定义Bean的方式,然后生成BeanDefinition后注册到Spring上下文中,由Spring自动创建Bean的实例。

2 BeanDefinition

BeanDefinition是一个接口,用来描述一个Bean实例,例如是SINGLETON还是PROTOTYPE,属性的值是什么,构造函数的参数是什么等。简单来说,通过一个BeanDefinition我们就可以完成一个Bean实例化。 BeanDefinition及其主要的子类:

下面简单说一下各个子类:

RootBeanDefinition和ChildBeanDefinition: 这2个BeanDefinition是相对的关系,自Spring 2.5 出来以后,已经被GenericBeanDefinition代替。因为这样强迫我们在编写代码的时候就必须知道他们之间的关系。

GenericBeanDefinition: 相比于RootBeanDefinition和ChildBeanDefinition在定义的时候就必须硬编码,GenericBeanDefinition的优点可以动态的为GenericBeanDefinition设置parent。

AnnotatedBeanDefinition:看名字就是知道是用来读取通过注解定义Bean。

3 通过xml文件定义Bean

通过xml定义Bean是最早的Spring定义Bean的方式。因此,怎么把xml标签解析为BeanDefinition(), 入口是在org.springframework.beans.factory.xml.XmlBeanDefinitionReader这个类,但是实际干活的是在org.springframework.beans.factory.xml.BeanDefinitionParserDelegate。代码很多,但实际逻辑很简单,就是解析Spring定义的 等标签 。

4 通过@Component等Spring支持的注解加载Bean

如果要使用@Component等注解定义Bean,一个前提条件是:有或者@ComponentScan注解。但这2个方式还是有一点点区别:

4.1

由于是一个xml标签,因此是在解析xml,生成的类org.springframework.context.annotation.ComponentScanBeanDefinitionParser,关键代码:

?

4.2 @ComponentScan

注解对应生成的类是org.springframework.context.annotation.ComponentScanAnnotationParser 其实最后实际干活的还是ClassPathBeanDefinitionScanner这个。ComponentScanAnnotationParser类的生成是伴随着@Configuration这个注解处理过程中(意思说@ComponentScan必须和@Configuration一起使用)。而处理@Configuration其实是org.springframework.context.annotation.ConfigurationClassPostProcessor。是不是感觉有点绕。

其实简单来说,在处理@Configuration的时候发现有@ComponentScan注解,就会生成ComponentScanAnnotationParser去扫描@Component注解

4.3 ClassPathBeanDefinitionScanner

上面说到了,无论注解还是标签的方式,最后都会交给ClassPathBeanDefinitionScanner这个类来处理,这个类做的就是1.扫描basePackage下所有class,如果有@Component等注解,读取@Component相关属性,生成ScannedGenericBeanDefinition,注册到Spring中。

5 通过@Bean方式

前面说了@ComponentScan是在@Configuration处理过程中的一环,既然@Bean注解也是必须和@Configuration一起使用,那么说明@Bean的处理也是在@Configuration中,其实最后是交给ConfigurationClassBeanDefinitionReader这个类来处理的,关键代码:

?

6 把BeanDefinition实例化

前面分别说了怎么把不同定义Bean的方式转换为BeanDefinition加入到Spring中去(确切来说是保持在BeanFactory的BeanDefinitionMap中),实例是在ApplicationContext最后阶段,关键代码在DefaultListableBeanFactory中

?

通过getBean最后最后实例的代码,在AbstractAutowireCapableBeanFactory中

?

从上面初始化可以看出,InitializeBean和BeanPostProcessors的调用顺序

7 总结

综上分析,Spring加载Bean其实大的思想都是一样的,先读取相关信息生成BeanDefinition,然后通过BeanDefinition初始化Bean。如果知道了上面了套路以后,就可以清楚怎么自定义Xml标签或者自定义注解向Spring中注入Bean。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://www.cnblogs.com/lizo/p/6759080.html

java spring 加载bean,Spring多种加载Bean方式解析相关推荐

  1. SpringBoot原理篇:bean的多种加载方法之 使用上下文对象regist注入bean

    使用上下文对象regist注入bean package com.qing.app;import com.qing.bean.Cat; import com.qing.bean.Dog; import ...

  2. Spring Boot 学习系列(09)—自定义Bean的顺序加载

    此文已由作者易国强授权网易云社区发布. 欢迎访问网易云社区,了解更多网易技术产品运营经验. Bean 的顺序加载 有些场景中,我们希望编写的Bean能够按照指定的顺序进行加载.比如,有UserServ ...

  3. spring bean的懒加载原理

    spring bean的懒加载原理 1 普通的bean的 初始化是在初始化阶段开始执行的,而被lazy-init修饰的bean则是从容器第一次进行context.getbean("" ...

  4. spring的applicationContext.xml如何自动加载

    一个web工程自动加载的配置文件只有web.xml,想要加载其他.xml必须在web.xml里面进行配置. 用spring的时候需要一个bean容器来管理所有的bean,所有bean默认是写在appl ...

  5. spring boot实战(第六篇)加载application资源文件源码分析

    前言 在上一篇中了解了spring配置资源的加载过程,本篇在此基础上学习spring boot如何默认加载application.xml等文件信息的. ConfigFileApplicationLis ...

  6. webmvcconfigurer配置跨域_为什么加了 Spring Security 会导致 Spring Boot 跨域失效呢?...

    点击上方 IT牧场 ,选择 置顶或者星标 技术干货每日送达 作者:欧阳我去 链接:https://segmentfault.com/a/1190000019485883 作为一个后端开发,我们经常遇到 ...

  7. Spring源码之BeanDifinition(加几行代码,可以产出让队友几天也找不出的Bug)

    前言 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/bin392328206/six-finger 种一棵树最好的时间是十年前,其次是现在 我知道很多人不玩qq ...

  8. SpringXML方式配置bean的懒加载lazy-init

    lazy-init(懒加载),表示该bean在容器初始化的时候不进行初始化. 例如: <bean name="role1" class="com.fz.entity ...

  9. 使用 加载 顺序_SpringBoot系列教程之Bean加载顺序之错误使用姿势辟谣

    在网上查询 Bean 的加载顺序时,看到了大量的文章中使用@Order注解的方式来控制 bean 的加载顺序,不知道写这些的博文的同学自己有没有实际的验证过,本文希望通过指出这些错误的使用姿势,让观文 ...

  10. java中class文件如何加载的_jvm如何加载class文件

    编译期: javac是JDK自带的编译器, 可以将java文件编译为class字节码文件, javap是JDK自带的反编译器,将.class字节码反编译为.java文件,javap -help是jav ...

最新文章

  1. react 开发过程中的总结/归纳
  2. 【长篇连载】桌面管理演义 第八回 电脑中毒很危险 告警隔离防传染
  3. Java一行一行的读文件和简单的写文件
  4. 【运筹学】表上作业法 ( 求初始基可行解 | 最小元素法 )
  5. MySQL not exists 真的不走索引么?
  6. UBoot常用命令手册
  7. mac系统更新后code .命令打不开vs code
  8. 慕课网高并发实战(一)-并发与高并发基本概念
  9. leetcode 1052. 爱生气的书店老板(滑动窗口)
  10. opencv-api FlannBasedMatcher
  11. OC无法进行多人会话
  12. Appcan、apicloud、HBuilder 不同之处解析
  13. CentOS - 安装mysql
  14. dom4j解析xml_JAVADom、Sax解析XML详解
  15. 计算机在线拥有,电路在线计算器
  16. ABB机器人FOR循环指令
  17. npm-Babel转码器
  18. LINUX gdk/X11正确获取DPI/Resolution的函数
  19. 《城市化》(顾朝林)-1
  20. Compose 页面切换动画

热门文章

  1. X64-CL iPro 采集卡OC-64EO-IPRO0简介
  2. js tostring 16 java_js中toString()和String()区别详解
  3. mysql database table_mysqldump database table
  4. Entity Framework 小知识(一)
  5. ORA-00704 ORA-00604 ORA-00942----惜分飞
  6. Python_Day10_进程、线程、协程
  7. ubuntu 下 github 使用方法 以及异常修改
  8. Frequently Asked Questions — Scrapy 0.15.1 documentation
  9. win7系统计算机无最小化,win7纯净版系统任务栏无法显示网页最小化窗口怎么办...
  10. 开了立体声混音仍然不能内录_蓝牙音箱有个功能很鸡肋,用好了秒变HIFI立体声...