基于Spring5.0.6版本。
一 BeanFactory
类路径:org.springframework.beans.factory.BeanFactory
BeanFactory是Spring IOC实现的基础,提供了getBean方法(),isSingleton(),isPrototype(name),isTypeMatch(),getType和String[] getAliases(String name)等核心方法。
String FACTORY_BEAN_PREFIX = "&";
接口中包含了一个成员变量,内容从变量命名上看,是factorybean的前缀。注释的英文描述:
/** * Used to dereference a {@link FactoryBean} instance and distinguish it from * beans <i>created</i> by the FactoryBean. For example, if the bean named * {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject} * will return the factory, not the instance returned by the factory. */
翻译过来,这个前缀用于间接引用一个FactoryBean实例,并把它与用FactoryBean”创建“的beans区分开来。例如:如果bean名为myJndiObject是一个FactoryBean,get &myJndiObject将会return工厂,而不是由工厂创建的实例。
查看被调用关系,可以查到在DefaultListableBeanFactory,BeanFactoryUtils,AbstractAutoProxyCreator这三个类中都有使用(不止这三个类)。
先看BeanFactoryUtils中的使用位置:
public static boolean isFactoryDereference(@Nullable String name) { return (name != null && name.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)); }
是判断一个输入字符串,是否是否是间接引用。
可见,方法是用语判断输入的bean(名称)是否是间接引用。
二 Spring bean 生命周期
1、实例化 Instantiation
2、属性赋值 Populate
3、初始化 Initialization
4、销毁 Destruction
1、InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置。
2、postProcessBeforeInstantiation方法是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走。
3、postProcessAfterInstantiation方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行。
4、postProcessPropertyValues方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改。
5、父接口BeanPostProcessor的2个方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目标对象被实例化之后,并且属性也被设置之后调用的。