spring-beanFactory二

上一篇只是将xml解析为bean definitions,这一篇来看getBean通过bean definition得到实例。

1 //以XmlBeanFactory为例
2 BeanFactory factory = new XmlBeanFactory(new ClassPathResource("spring/spring-test.xml"));
3 MyBean bean = (MyBean) factory.getBean("myBean");
4 System.out.println(bean.getBeanName());//myBean
1 public class MyBean {
2     private String beanName = "myBean";
3     public String getBeanName() {
4         return beanName;
5     }
6     public void setBeanName(String beanName) {
7         this.beanName = beanName;
8     }
9 }
1 <?xml version="1.0" encoding="UTF-8"?>
2 <beans xmlns="http://www.springframework.org/schema/beans"
3        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4        xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
5     <bean id="myBean" class="com.zyong.spring.beanfactory.MyBean"/>
6 </beans>
1 public Object getBean(String name) throws BeansException {
2     //name, requiredType, args, typeCheckOnly
3     return doGetBean(name, null, null, false);
4 }
 1 //doGetBean会真正的实例化对象,并回调beanFactory(BeanPostProcessor)、
 2 //bean(init,@PostConstruct和@PreDestroy通过CommonAnnotationBeanPostProcessor或开启<context:annotation-config />来支持)的相关方法
 3 protected <T> T doGetBean(
 4         final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)
 5         throws BeansException {
 6
 7     // Eagerly check singleton cache for manually registered singletons.
 8     //尝试从缓存中获取,首先会尝试从singletonObjects获取,再尝试从singletonFactories中获取获取beanFactory(beanName是beanFactory的名字),如果获取到则调用getObject获得bean
 9     Object sharedInstance = getSingleton(beanName);
10     if (sharedInstance != null && args == null) {
11         if (logger.isDebugEnabled()) {
12             if (isSingletonCurrentlyInCreation(beanName)) {
13                 logger.debug("Returning eagerly cached instance of singleton bean ‘" + beanName +
14                         "‘ that is not fully initialized yet - a consequence of a circular reference");
15             }
16             else {
17                 logger.debug("Returning cached instance of singleton bean ‘" + beanName + "‘");
18             }
19         }
20         //从bean实例中获取对象,可能是bean实例自身,如果bean实例是一个beanFactory,则返回beanFactroy创建的对象
21         bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
22     }else{
23         // Check if bean definition exists in this factory.
24         BeanFactory parentBeanFactory = getParentBeanFactory();
25         //如果本beanFactory不包含该beanName的bean definition,则从父级beanFactory获取bean
26         if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
27             // Not found -> check parent.
28             String nameToLookup = originalBeanName(name);
29             return (T) parentBeanFactory.getBean(nameToLookup, args);
30         }
31
32         final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
33         checkMergedBeanDefinition(mbd, beanName, args);
34
35         // Guarantee initialization of beans that the current bean depends on.
36         //这里只是为当前bean注册依赖,并没有注入,注册依赖是为了在销毁当前bean之前,先销毁依赖(为了实现该功能,需要2个注册表,一个是bean->dependences,另一个是dependence->beans)
37         String[] dependsOn = mbd.getDependsOn();
38         if (dependsOn != null) {
39             for (String dep : dependsOn) {
40                 if (isDependent(beanName, dep)) {
41                     throw new BeanCreationException(mbd.getResourceDescription(), beanName,
42                             "Circular depends-on relationship between ‘" + beanName + "‘ and ‘" + dep + "‘");
43                 }
44                 registerDependentBean(dep, beanName);
45                 //递归创建依赖bean
46                 getBean(dep);
47             }
48         }
49
50         //从这里开始真正创建bean
51         // Create bean instance.
52         if (mbd.isSingleton()) {
53             sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {//策略模式,ObjectFactory不同,创建bean的策略也会有差异
54                 @Override
55                 public Object getObject() throws BeansException {
56                     try {
57                         //重要方法
58                         return createBean(beanName, mbd, args);
59                     }
60                     catch (BeansException ex) {
61                         // Explicitly remove instance from singleton cache: It might have been put there
62                         // eagerly by the creation process, to allow for circular reference resolution.
63                         // Also remove any beans that received a temporary reference to the bean.
64                         destroySingleton(beanName);
65                         throw ex;
66                     }
67                 }
68             });
69             //与之前从缓存获取bean实例类似
70             bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
71         }else if(mbd.isPrototype()){
72             ......
73         }else{
74             ......
75         }
76
77     }//else
78
79 }
 1 //createBean的主要逻辑,这里就真正开始创建bean的各种“花招”了
 2 protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
 3     // Make sure bean class is actually resolved at this point, and
 4     // clone the bean definition in case of a dynamically resolved Class
 5     // which cannot be stored in the shared merged bean definition.
 6     //加载bean的class,并存入bean definition
 7     Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
 8     if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
 9         mbdToUse = new RootBeanDefinition(mbd);
10         mbdToUse.setBeanClass(resolvedClass);
11     }
12     // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
13     //如果bean实现了InstantiationAwareBeanPostProcessor,
14     //这里就会调用InstantiationAwareBeanPostProcessor的Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)接口来创建bean,
15     //如果返回非null,则继续调用boolean postProcessAfterInstantiation(Object bean, String beanName)接口
16     //PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)有机会在注入前执行
17     Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
18     //如果通过InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法得到一个实例,直接返回
19     if (bean != null) {
20         return bean;
21     }
22     //如果通过InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法无法得到一个实例,则进行常规实例化工作(实例化、注入、BeanPostProcessor等)
23     //重要方法
24     Object beanInstance = doCreateBean(beanName, mbdToUse, args);
25     return beanInstance;
26 }
 1 //doCreateBean的主要逻辑
 2 protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
 3     throws BeanCreationException {
 4     //使用工厂方法、构造器注入、简单实例化等策略实例化bean(不是策略模式,只是通过bean definition来决定使用哪种策略,类似switch)
 5     //BeanWrapper是bean的包装类,beanWrapper提供了便捷的方法去更新bean的字段、访问bean的方法,用于注入
 6     BeanWrapper instanceWrapper = createBeanInstance(beanName, mbd, args);//离我们很近
 7     final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
 8     //MergedBeanDefinitionPostProcessor的void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName)
 9     applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
10     // Initialize the bean instance.
11     //exposedObject即暴露的bean、原生的bean
12     Object exposedObject = bean;
13     //先执行InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation,
14     //再执行InstantiationAwareBeanPostProcessor的postProcessPropertyValues,最后再进行xml注入
15     populateBean(beanName, mbd, instanceWrapper);
16     //什么情况下bean==null?
17     if (exposedObject != null) {
18         //初始化bean
19         //invokeAwareMethods(回调BeanNameAware、BeanClassLoaderAware、BeanFactoryAware的相关方法)、
20         //applyBeanPostProcessorsBeforeInitialization(回调BeanPostProcessor的postProcessBeforeInitialization方法)、
21         //invokeInitMethods(回调InitializingBean的afterPropertiesSet,以及init-method)、
22         //applyBeanPostProcessorsAfterInitialization(回调BeanPostProcessor的postProcessAfterInitialization方法)
23         exposedObject = initializeBean(beanName, exposedObject, mbd);//离我们很近
24     }
25     // Register bean as disposable.
26     registerDisposableBeanIfNecessary(beanName, bean, mbd);
27 }
时间: 2024-10-08 04:22:21

spring-beanFactory二的相关文章

攻城狮在路上(贰) Spring(四)--- Spring BeanFactory简介

BeanFactory时Spring框架最核心的接口,它提供了高级IoC的配置机制,使管理不同类型的Java对象成为了可能.我们一般称BeanFactory为IoC容器.BeanFactory是Spring的基础设施,面向Spring本身. 一.BeanFactory的体系结构: 二.类图说明: ListableBeanFactory:定义了访问容器中Bean基本信息的方法,查看Bean的个数.获取某一类型Bean的配置名,看容器中是否包含某一Bean等方法. HierarchicalBeanF

Spring BeanFactory 中的类型推断

Spring BeanFactory 中的类型推断 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) Spring 容器中可以根据 beanName 查找其类型,其推断方式和 bean 的创建方式密切相关,并且 Spring 中有一个原则是尽可能的不要通过创建 bean 来获取其类型,除了 FactoryBean 只有通过创建对象调用其 getObjectType 方法,但也只是部分的创建该 FactoryBean(所谓

Spring BeanFactory 依赖注入

Spring BeanFactory 依赖注入 Spring 系列目录(https://www.cnblogs.com/binarylei/p/10117436.html) 一.autowire 五种注入方式测试 (1) 环境准备 public class Company { private Department department; private List<Employee> employees; public Company() { } public Company(Departmen

攻城狮在路上(贰) Spring(二)--- Spring IoC概念介绍

一.IoC的概念: IoC(控制反转)是Spring容器的核心.另一种解释是DI(依赖注入),即让调用类对某一个接口的依赖关系由第三方注入,以移除调用类对某一个接口实现类的一览. 定义如此,由此可见,在面向接口编程的情况下,IoC可以很好的实现解耦,可以以配置的方式为程序提供所需要的接口实现类. 在实际程序开发中,我们只需要提供对应的接口及实现类,然后通过Spring的配置文件或者注解完成对依赖类的装配.二.IoC的类型: 1.通过构造函数: 此种方式的缺点是,在构造函数中注入之后一般会作为一个

深入浅出Spring(二) IoC详解

上次的博客深入浅出Spring(一)Spring概述中,我给大家简单介绍了一下Spring相关概念.重点是这么一句:Spring是为了解决企业应用开发的复杂性而创建的一个轻量级的控制反转(IoC)和面向切面(AOP)的容器框架.在这句话中重点有两个,一个是IoC,另一个是AOP.今天我们讲第一个IoC. IoC概念 控制反转(Inversion of Control)是一个重要的面向对象编程的法则来削减计算机程序的耦合问题. 它还有一个名字叫做依赖注入(Dependency Injection)

spring batch(二):核心部分(1):配置Spring batch

spring batch(二):核心部分(1):配置Spring batch 博客分类: Spring 经验 java chapter 3.Batch configuration 1.spring batch 的命名空间 spring xml中指定batch的前缀作为命名空间. 示例: Xml代码   <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sprin

Redis实战之征服 Redis + Jedis + Spring (二)

不得不说,用哈希操作来存对象,有点自讨苦吃! 不过,既然吃了苦,也做个记录,也许以后API升级后,能好用些呢?! 或许,是我的理解不对,没有真正的理解哈希表. 相关链接: Redis实战 Redis实战之Redis + Jedis Redis实战之征服 Redis + Jedis + Spring (一) Redis实战之征服 Redis + Jedis + Spring (二) Redis实战之征服 Redis + Jedis + Spring (三) 一.预期 接上一篇,扩充User属性:

bean创建过程、spring BeanFactory的实现、spring aware

Bean的创建过程: Spring beanFactory的工厂模式实现: 解析<bean>标签,存到一个Map<String, Object> beans中 People o = (People)factory.getBean("p"); 因为map存的是object类型,所以取出时需要强制类型转换 Bean的生命周期: spring aware的目的是为了让Bean获得spring容器的服务,bean继承applicationContextAware可以获得

Spring(二)核心容器 - 简介 、BeanFactory、ApplicationContext

目录 前言 1.容器简介 2.容器的结构 2.1 BeanFactory 2.2 ApplicationContext 2.2.1 ConfigurableApplicationContext 2.2.2 WebApplicationContext 2.3 差异对比 3.ApplicationContext 准备启动 4.总结 前言 在上篇文章中,和大家一起讨论了 Spring 的整体架构,其大致分为五个模块:核心容器.AOP.Web.Data 数据访问.Test模块.其中核心容器是 Sprin

Spring讲解二:Spring中的Bean配置1---基于XML文件的方式

一.在Spring的IOC容器中配置Bean 在xml文件中通过bean节点配置bean id:Bean的名称: (1) 在IOC容器中必须是唯一的 (2) 若id没有指定,Spring自动将权限限定性类名作为bean的名字 (3) id可以指定多个名字,名字之间可以用逗号.分号.或空格分隔 二.Spring容器 在Spring IOC容器读取Bean配置创建Bean实例之前,必须对它进行初始化.只有在容器实例化后,才可以从IOC容器中获取Bean实例并使用. Spring提供了两种类型的IOC