具体代码通过通读 https://www.cnblogs.com/GooPolaris/p/8169611.html 就可以有一定认识。
这里需要注意的是,该blog里实际上是在讲Spring是如何把定义在资源文件(主要为xml)中的bean定义,加载成实际实例的。
博客中是从XmlBeanDefinitionReader做为起点,然后追溯到AbstractBeanDefinitionReader,然后追溯到资源解析,走到BeanDefinitionReaderUtils.registerBeanDefinition,然后回归到DefaultListableBeanFactory.registerBeanDefinition(默认的Bean工程),在DefaultListableBeanFactory这个工程类中集中存储和管控Bean类名和BeanDefination。从blog看只能看到bean定义管控的部分,bean实例的管控部分在哪呢?
答案是bean实例管控由BeanFactory来负责,而从继承图谱里可以看出,DefaultListableBeanFactory本身也是一个BeanFactory(从名字其实就可知),也就是说它本身就可以作为实例管控的容器。
DefaultListableBeanFactory继承关系图如下,其中,bean管控的方法是通过实现BeanFactory的方法来达成,类似于registerBeanDefinition这种定义管控,是通过实现BeanDefinitionRegistry来达成。
我们通过blog了解的是Spring解析资源文件中bean定义的方式,而在当前Spring-Boot的环境下,更多的不是采用这种方式,而是直接用代码注解的方式来达成。核心机制都是拿到类的定义,xml方式是通过资源文件拿,注解的方式是通过扫描注解拿。系统里除了这两种方式,还有直接用代码,通过读取某些配置来加载Bean的方法,采取的方式类似如下:
GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
beanDefinition.setBeanClass(BasePackages.class);
beanDefinition.getConstructorArgumentValues().addIndexedArgumentValue(0, packageNames);
beanDefinition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
registry.registerBeanDefinition(BEAN, beanDefinition);
@Bean标签注解识别的方式有如下:
比如在入口类中声明一个@Bean,入口类被扫描为@Configuration类时,其中的@Bean会被识别成BeanMethod,在刷新方法的invokeBeanFactoryPostProcessors环节,有一步会把配置类的BeanMethod注册到Bean定义中。