Spring源码学习--Bean对象初始化(二)

来源:互联网 发布:linux禁止ftp 编辑:程序博客网 时间:2024/05/29 18:46

即使我们在不了解Spring对bean的初始化机制,我们也可以根据Java语言的特性猜测到其很有可能是通过反射机制来完成Bean的初始化操作,接下来我们一步一步的剖析Spring对Bean的初始化操作。

首先Spring会通过调用 getBean(String name)来获取Bean,在获取bean的过程中完成的Bean的初始化操作。

AbstractBeanFactory类中:

@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}
在doGetBean方法中会判断bean的类型单例、原型,如果是单例则需要判断是否已经初始化bean并添加到缓存中,如果是原型bean则需要重新初始化bean,由于Spring对beanName提供了别名机制,所有需要通过beanName获取最终的bean名称。

@SuppressWarnings("unchecked")protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly)throws BeansException {//查找name是否有别名,获取最终的beanNamefinal String beanName = transformedBeanName(name);Object bean;//如果bean是单例模式,首先尝试从缓存中获取Object sharedInstance = getSingleton(beanName);if (sharedInstance != null && args == null) {if (logger.isDebugEnabled()) {if (isSingletonCurrentlyInCreation(beanName)) {logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}else {logger.debug("Returning cached instance of singleton bean '" + beanName + "'");}}//会判断bean是否是FactoryBean,如果不是直接返回sharedInstance,否则调用sharedInstance.getObject()方法返回beanbean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}//判断容器是否有服容器,如果有则首先尝试从父容器中获取BeanFactory parentBeanFactory = getParentBeanFactory();if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.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 {//根据beanName获取bean的元数据final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.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()) {//获取bean,首先会暴露一个ObjectFactory,通过调用getObject来调用createBean(beanName, mbd, args)获取beansharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {try {//return createBean(beanName, mbd, args);}catch (BeansException ex) {destroySingleton(beanName);throw ex;}}});//会判断bean是否是FactoryBean,如果不是直接返回sharedInstance,否则调用sharedInstance.getObject()方法返回beanbean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);}//bean是原型else if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);//初始化beanprototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}//bean是其他模式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>() {@Overridepublic 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;}}//省略代码..........return (T) bean;}
接下来我们看看在createBean(String beanName, RootBeanDefinition mbd, Object[] args)中进行的处理操作,在createBean中会通过BeanDefinition中获取类名resolvedClass(反射机制重要的一个参数),并且会调用resolveBeforeInstantiation在bean初始的过程中做一些预处理(简单来说就是BeanPostProcessor的实现类所做的处理操作,参考博客Spring源码学习--BeanPostProcessor)。

AbstractAutowireCapableBeanFactory:

@Overrideprotected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {if (logger.isDebugEnabled()) {logger.debug("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;//获取类名,通过反射机制来实例化类Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);//设置类名mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.//如果bean想要在初始化后使用之前做一些预处理操作Object bean = resolveBeforeInstantiation(beanName, mbdToUse);if (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}//初始化beanObject beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isDebugEnabled()) {logger.debug("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}
doCreateBean中完成的处理操作就比较多了,简单来说调用了几个方法完成了bean的初始化操作:

createBeanInstance完成通过构造函数初始化bean的操作;

addSingletonFactory完成将初始化的bean提前暴露出去,这样就解决了单例bean非构造函数的循环引用问题;

populateBean完成bean的属性注入操作,通过set方法或者注解注入属性;

initializeBean完成了bean注入时设置的init-method方法的执行,同时在执行init-method之前会调用applyBeanPostProcessorsBeforeInitialization完成bean使用前的处理操作,调用applyBeanPostProcessorsAfterInitialization完成bean初始化后的操作;

protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args)throws BeanCreationException {BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}//初始化bean实例if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = (instanceWrapper != null ? instanceWrapper.getWrappedInstance() : null);Class<?> beanType = (instanceWrapper != null ? instanceWrapper.getWrappedClass() : null);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;}}//将初始化的bean提前暴露出去,暴露一个ObjectFactory,这也是Spring解决单例bean非构造函数依赖的解决方法boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&isSingletonCurrentlyInCreation(beanName));if (earlySingletonExposure) {if (logger.isDebugEnabled()) {logger.debug("Eagerly caching bean '" + beanName +"' to allow for resolving potential circular references");}addSingletonFactory(beanName, new ObjectFactory<Object>() {@Overridepublic Object getObject() throws BeansException {return getEarlyBeanReference(beanName, mbd, bean);}});}// Initialize the bean instance.Object exposedObject = bean;try {//初始化bean的各种注入或者setXX参数populateBean(beanName, mbd, instanceWrapper);if (exposedObject != null) {//调用注入类的init-method方法exposedObject = initializeBean(beanName, exposedObject, mbd);}}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);}}//// Register bean as disposable.try {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}
createBeanInstance中会通过bean的构造函数或者默认构造函数来完成bean的初始化工作。

protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {//省略代码.............if (resolved) {if (autowireNecessary) {//通过构造函数初始化return autowireConstructor(beanName, mbd, null, null);}else {//使用默认构造函数初始化return instantiateBean(beanName, mbd);}}// Need to determine the constructor...Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);if (ctors != null ||mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args))  {return autowireConstructor(beanName, mbd, ctors, args);}// No special handling: simply use no-arg constructor.return instantiateBean(beanName, mbd);}
instantiateBean中会调用bean初始策略InstantiationStrategy的实现类完成bean的初始化操作。

protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {try {Object beanInstance;final BeanFactory parent = this;if (System.getSecurityManager() != null) {beanInstance = AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {return getInstantiationStrategy().instantiate(mbd, beanName, parent);}}, getAccessControlContext());}else {//调用bean初始化策InstantiationStrategy略初始化beanbeanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);}BeanWrapper bw = new BeanWrapperImpl(beanInstance);initBeanWrapper(bw);return bw;}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Instantiation of bean failed", ex);}}
调用InstantiationStrategy的instantiate方法完成初始化操作。

SimpleInstantiationStrategy(InstantiationStrategy实现类

@Overridepublic Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {// Don't override the class with CGLIB if no overrides.if (bd.getMethodOverrides().isEmpty()) {Constructor<?> constructorToUse;synchronized (bd.constructorArgumentLock) {constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;if (constructorToUse == null) {final Class<?> clazz = bd.getBeanClass();if (clazz.isInterface()) {throw new BeanInstantiationException(clazz, "Specified class is an interface");}try {if (System.getSecurityManager() != null) {constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {@Overridepublic Constructor<?> run() throws Exception {return clazz.getDeclaredConstructor((Class[]) null);}});}else {constructorToUse =clazz.getDeclaredConstructor((Class[]) null);}bd.resolvedConstructorOrFactoryMethod = constructorToUse;}catch (Throwable ex) {throw new BeanInstantiationException(clazz, "No default constructor found", ex);}}}//最终在BeanUtils中完成bean的初始化操作return BeanUtils.instantiateClass(constructorToUse);}else {// Must generate CGLIB subclass.return instantiateWithMethodInjection(bd, beanName, owner);}}
最终我们发现bean的初始化操作是在BeanUtils中完成的,通过反射机制完成Bean的初始化操作。

public static <T> T instantiateClass(Constructor<T> ctor, Object... args) throws BeanInstantiationException {Assert.notNull(ctor, "Constructor must not be null");try {ReflectionUtils.makeAccessible(ctor);//通过反射机制初始化beanreturn ctor.newInstance(args);}catch (InstantiationException ex) {throw new BeanInstantiationException(ctor, "Is it an abstract class?", ex);}catch (IllegalAccessException ex) {throw new BeanInstantiationException(ctor, "Is the constructor accessible?", ex);}catch (IllegalArgumentException ex) {throw new BeanInstantiationException(ctor, "Illegal arguments for constructor", ex);}catch (InvocationTargetException ex) {throw new BeanInstantiationException(ctor, "Constructor threw exception", ex.getTargetException());}}

总结:简单来说Spring对bean的初始化操作就是根据反射机制通过构造函数进行初始化的。

接下来我们再用一篇介绍一下bean的属性注入相关的操作。









阅读全文
0 0