聊聊工厂bean和bean工厂有什么同异,先说结论
- bean工厂:不是bean,在spring中一般指的是DefaultListableBeanFactory对象,管理和维护spring中所有的bean
- 工厂bean:一种特殊的bean,在xml文件中配置的,用来生成新的bean的加工厂,通过getObject()方法可以获取其生产的新bean,如果想获取该工厂bean本身,需要使用类似于
getBean("&" + beanName)
的样式。
demo
先来个小demo,具体学习和了解下如何使用工厂bean
public class StudentFactoryBean extends AbstractFactoryBean
如上述代码所述,我们自定义继承了AbstractFactoryBean抽象类,并实现了几个方法,便于生成具体的Student类
执行结果也如设想的一般,分别打印各自对象的toString,不过className并没有被自动注解上
源码分析
以前的学习我们已经知道了在refresh已经完成了对xml配置的bean的实例化操作了。如下图当还未执行getBean("studentFactory")操作时,studentFactory和对应的实体类都已经完成了实例化操作(这点是需要关注的点)
接下来我们就在回过头看看refresh的操作是如何完成实例化的。
DefaultListableBeanFactory 文件
public void preInstantiateSingletons() throws BeansException {
List beanNames = new ArrayList(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 得到合并parentBean的beandefinition bd
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 不是抽象类 是单例类型同时不是懒加载的beandefinition
if (isFactoryBean(beanName)) {
// 如果是工厂bean(针对beanName对应的class类型匹配判断)
final FactoryBean> factory = (FactoryBean>) getBean(FACTORY_BEAN_PREFIX + beanName);
// 调用getBean("&" + beanName)操作,返回的factory是工厂bean实例
// 这样在这个bean实例中,存储着映射的具体bean
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction() {
@Override
public Boolean run() {
return ((SmartFactoryBean>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
else {
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged(new PrivilegedAction
AbstractBeanFactory 文件
protected T doGetBean(
final String name, final Class requiredType, final Object[] args, boolean typeCheckOnly)
throws BeansException {
final String beanName = transformedBeanName(name);
// 如果是"&" + beanName,那么beanName就是去掉&的值
Object bean;
Object sharedInstance = getSingleton(beanName);
// 从singletonObjects 中获取已经处理好的single 实例化对象
if (sharedInstance != null && args == null) {
// single已经有数据了,而且参数也没有,生成真正的对象bean
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
if (isPrototypeCurrentlyInCreation(beanName)) {
// 如果当前的beanName在prototype的创建中,则抛出异常
throw new BeanCurrentlyInCreationException(beanName);
}
// 获取当前bean工厂的父亲工厂
BeanFactory parentBeanFactory = getParentBeanFactory();
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
// 如果有父亲工厂,而且还未处理
String nameToLookup = originalBeanName(name);
if (args != null) {
// Delegation to parent with explicit args.
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// No args -> delegate to standard getBean method.
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// 得到当前beandefinition的依赖元素
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
getBean(dep);
// 把每一个必须依赖的bean注册好,并进行实例化操作
}
}
// 到这里就完成了一个对象实例化之前的操作了,现在需要创建具体的对象
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, new ObjectFactory
AbstractAutowireCapableBeanFactory 文件 真正创建对象的方法
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)
throws BeanCreationException {
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);
Class> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);
mbd.resolvedTargetType = beanType;
// 获取到所有的MergedBeanDefinitionPostProcessor 对象,依次去修改对应的bean信息
// 这样就可以再对BeanDefinition 进行修改处理了
// 而且!!!自动注入值就是在这里通过AutowiredAnnotationBeanPostProcessor类完成的
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
// 判断是否是正在处理当前这个single对象,而且允许循环引用
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
addSingletonFactory(beanName, new ObjectFactory() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper);
// 完成值的真正填充,注意在上面说过使用AutowiredAnnotationBeanPostProcessor注入值,其实并没有注入绝对的值,而是注入的相关数据,在populated的时候才是完成真正的值注入
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
// 这一步很关键,重点关注下面贴出来的invokeInitMethods 方法
}
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
....
return exposedObject;
}
// ====== 分割线 ======
protected void invokeInitMethods(String beanName, final Object bean, RootBeanDefinition mbd)
throws Throwable {
boolean isInitializingBean = (bean instanceof InitializingBean);
if (isInitializingBean && (mbd == null || !mbd.isExternallyManagedInitMethod("afterPropertiesSet"))) {
if (logger.isDebugEnabled()) {
logger.debug("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
}
if (System.getSecurityManager() != null) {
try {
AccessController.doPrivileged(new PrivilegedExceptionAction() {
@Override
public Object run() throws Exception {
((InitializingBean) bean).afterPropertiesSet();
return null;
}
}, getAccessControlContext());
}
catch (PrivilegedActionException pae) {
throw pae.getException();
}
}
else {
// 调用afterPropertiesSet 方法,完成对bean的singletonInstance实例化
((InitializingBean) bean).afterPropertiesSet();
}
}
...
}
AbstractFactoryBean 文件
public void afterPropertiesSet() throws Exception {
if (isSingleton()) {
this.initialized = true;
this.singletonInstance = createInstance();
// 相当关键的一步!!!!!调用createInstance
this.earlySingletonInstance = null;
}
}
如图所示,在执行initializeBean之前时,完成了对象的实例化,还会继续进行初始化bean操作
执行initializeBean 之后,已经填充了singletonInstance 对象了,其包含的是工厂生成的bean数据
完成整个的refresh操作之后,其实所有的未懒加载的bean都已经完成的实例化,工厂bean对应的具体bean也被保存在工厂bean中。
接下来讲讲在完成实例化之后,调用getBean获取工厂bean实例以及工厂bean本身的细节
- getBean("studentFactory")
- getBean("&studentFactory")
1、老套路来到了doGetBean方法,得出name的原始beanName值
2、从singletonObjects找确认存在该值
3、进入到getObjectForBeanInstance方法
4、如果想要返回的是工厂bean本身,而且还不为null,直接返回(也就是getBean("&studentFactory")操作)
5、从factoryBeanObjectCache确认是否存在对应的值
如果有,意味着存在这个对应的值,直接返回(也就是多次getBean("studentFactory")操作)
没有,需要getObjectFromFactoryBean这个方法,往factoryBeanObjectCache填充新的实例
这里需要注意的是存储的value是工厂bean关联的真实bean直接返回(也就是首次执行getBean("studentFactory")操作)
不过最后还有个问题,就是最后生成的该对象Student并没有为className注入值,通过上面的实现,压根没有自动注解的那段操作,而是在自定义的工厂bean中通过createInstance方法返回的,所以肯定是没有值的。