聊聊工厂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<Object> {
@Override
public Class<?> getObjectType() {
return Student.class;
}
@Override
protected Object createInstance() throws Exception {
return new Student("factoryDemo", 18);
}
@Override
public String toString() {
return "StudentFactoryBean";
}
}
public class Bootstrap {
public static void main(String[] args){
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext(
new String[]{"context.xml"}, false);
applicationContext.setAllowBeanDefinitionOverriding(false);
applicationContext.refresh();
Student student = (Student)applicationContext.getBean("studentFactory");
// 生成工厂类生成的具体实体类,值的是studentFactory生成的类
System.out.println(student.toString());
StudentFactoryBean studentFactoryBean = (StudentFactoryBean) applicationContext.getBean("&studentFactory");
// 名字加了一个& 获取的是studentFactory本身
System.out.println(studentFactoryBean.toString());
}
}
<bean name="studentFactory" class="com.demo.StudentFactoryBean" />
如上述代码所述,我们自定义继承了AbstractFactoryBean抽象类,并实现了几个方法,便于生成具体的Student类
image.png执行结果也如设想的一般,分别打印各自对象的toString,不过className并没有被自动注解上
源码分析
以前的学习我们已经知道了在refresh已经完成了对xml配置的bean的实例化操作了。如下图当还未执行getBean("studentFactory")操作时,studentFactory和对应的实体类都已经完成了实例化操作(这点是需要关注的点)
image.png接下来我们就在回过头看看refresh的操作是如何完成实例化的。
DefaultListableBeanFactory 文件
public void preInstantiateSingletons() throws BeansException {
List<String> beanNames = new ArrayList<String>(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<Boolean>() {
@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<Object>() {
@Override
public Object run() {
smartSingleton.afterSingletonsInstantiated();
return null;
}
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
AbstractBeanFactory 文件
protected <T> T doGetBean(
final String name, final Class<T> 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<Object>() {
@Override
public Object getObject() throws BeansException {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
destroySingleton(beanName);
throw ex;
}
}
});
// 得到的sharedInstance 是工厂类 StudentBeanFactory对象
// 获取真正的实例对象,返回
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) {
try {
return getTypeConverter().convertIfNecessary(bean, requiredType);
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
// 强转类型为T
return (T) bean;
}
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<Object>() {
@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<Object>() {
@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操作
image.png执行initializeBean 之后,已经填充了singletonInstance 对象了,其包含的是工厂生成的bean数据
image.png完成整个的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")操作)
image.png
没有,需要getObjectFromFactoryBean这个方法,往factoryBeanObjectCache填充新的实例
这里需要注意的是存储的value是工厂bean关联的真实bean直接返回(也就是首次执行getBean("studentFactory")操作)
不过最后还有个问题,就是最后生成的该对象Student并没有为className注入值,通过上面的实现,压根没有自动注解的那段操作,而是在自定义的工厂bean中通过createInstance方法返回的,所以肯定是没有值的。
网友评论