spring源码学习(六)Bean的加载(中)
2017-09-21 10:58
399 查看
如果我们获取单例是,内存中还没有缓存,那么则进入下面这个方法
上述函数先判断该单例是否已经加载,若没有则记录beanName正在加载的状态,加载单例前记录加载状态,通过调用参数传入ObjectFactory,实例化bean,然后进行加载单例后处理方法调用,最后把加载好的单例放入缓存并删除加载bean过程中各种辅助状态,最后返回。
下面是createBean的方法体
对class属性或者,className来解析Class,对override属性进行标记和验证,应用初始化前的后处理器,解析指定的bean是否存在初始化前的操作,创建bean。
对override属性的处理,其实就是处理lookup-method和replace-method的配置。
如果当前类中发放只有一个,那么就设置该方法,没有被重载,这样后续调用就可以直接使用找到的方法,不用进行参数匹配了。
实例化前置处理
对所有InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法进行调用
bean实例化前的后处理器应用,将AbstractBeanDefinition转换为BeanWrapper前的处理,给自雷一个修改BeanDefinition的机会,经过这个方法后,bean可能会变成一个经过处理的代理类。
spring中的规则是在bean的初始化后尽可能保证将注册的后处理器的方法应用到bean中,因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程,所以只能在这里应用后处理器方法。
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "Bean name must not be null"); synchronized (this.singletonObjects) { //看是否存在这个单例 Object singletonObject = this.singletonObjects.get(beanName); //若没有则进行初始化 if (singletonObject == null) { if (this.singletonsCurrentlyInDestruction) { throw new BeanCreationNotAllowedException(beanName, "Singleton bean creation not allowed while singletons of this factory are in destruction " + "(Do not request a bean from a BeanFactory in a destroy method implementation!)"); } if (logger.isDebugEnabled()) { logger.debug("Creating shared instance of singleton bean '" + beanName + "'"); } beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<>(); } try { singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { // Has the singleton object implicitly appeared in the meantime -> // if yes, proceed with it since the exception indicates that state. singletonObject = this.singletonObjects.get(beanName); if (singletonObject == null) { throw ex; } } catch (BeanCreationException ex) { if (recordSuppressedExceptions) { for (Exception suppressedException : this.suppressedExceptions) { ex.addRelatedCause(suppressedException); } } throw ex; } finally { if (recordSuppressedExceptions) { this.suppressedExceptions = null; } afterSingletonCreation(beanName); } if (newSingleton) { addSingleton(beanName, singletonObject); } } return singletonObject; } }
上述函数先判断该单例是否已经加载,若没有则记录beanName正在加载的状态,加载单例前记录加载状态,通过调用参数传入ObjectFactory,实例化bean,然后进行加载单例后处理方法调用,最后把加载好的单例放入缓存并删除加载bean过程中各种辅助状态,最后返回。
if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, () -> { try { return createBean(beanName, mbd, args); } catch (BeansException ex) { // Explicitly remove instance from singleton cache: It might have been put there // eagerly by the creation process, to allow for circular reference resolution. // Also remove any beans that received a temporary reference to the bean. destroySingleton(beanName); throw ex; } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); }
下面是createBean的方法体
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; // Make sure bean class is actually resolved at this point, and // clone the bean definition in case of a dynamically resolved Class // which cannot be stored in the shared merged bean definition. // 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.g db2d etResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { // Give BeanPostProcessors a chance to return a proxy instead of the target bean instance. 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); } try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; } catch (BeanCreationException ex) { // A previously detected exception with proper bean creation context already... throw ex; } catch (ImplicitlyAppearedSingletonException ex) { // An IllegalStateException to be communicated up to DefaultSingletonBeanRegistry... throw ex; } catch (Throwable ex) { throw new BeanCreationException( mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex); } }
对class属性或者,className来解析Class,对override属性进行标记和验证,应用初始化前的后处理器,解析指定的bean是否存在初始化前的操作,创建bean。
对override属性的处理,其实就是处理lookup-method和replace-method的配置。
public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exists. MethodOverrides methodOverrides = getMethodOverrides(); if (!methodOverrides.isEmpty()) { Set<MethodOverride> overrides = methodOverrides.getOverrides(); synchronized (overrides) { for (MethodOverride mo : overrides) { prepareMethodOverride(mo); } } } }
protected void prepareMethodOverride(MethodOverride mo) throws BeanDefinitionValidationException { int count = ClassUtils.getMethodCountForName(getBeanClass(), mo.getMethodName()); if (count == 0) { throw new BeanDefinitionValidationException( "Invalid method override: no method with name '" + mo.getMethodName() + "' on class [" + getBeanClassName() + "]"); } else if (count == 1) { // Mark override as not overloaded, to avoid the overhead of arg type checking. mo.setOverloaded(false); } }
如果当前类中发放只有一个,那么就设置该方法,没有被重载,这样后续调用就可以直接使用找到的方法,不用进行参数匹配了。
实例化前置处理
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; //如果尚未被解析 if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { // Make sure bean class is actually resolved at this point. if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
对所有InstantiationAwareBeanPostProcessor类型的后处理器进行postProcessBeforeInstantiation方法和BeanPostProcessor的postProcessAfterInitialization方法进行调用
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }
bean实例化前的后处理器应用,将AbstractBeanDefinition转换为BeanWrapper前的处理,给自雷一个修改BeanDefinition的机会,经过这个方法后,bean可能会变成一个经过处理的代理类。
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { Object current = beanProcessor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }
spring中的规则是在bean的初始化后尽可能保证将注册的后处理器的方法应用到bean中,因为如果返回的bean不为空,那么便不会再次经历普通bean的创建过程,所以只能在这里应用后处理器方法。
相关文章推荐
- spring源码学习(七)Bean的加载(下)
- 通过DefaultListableBeanFactory加载.xml配置文件学习Spring-IoC容器注册/加载bean的机制(源码走读)
- spring容器初始化,bean加载生成过程,源码解析学习
- spring源码初步学习-bean的加载
- spring源码学习(五)Bean的加载(上)
- 【spring源码分析】加载bean过程(2)
- 分析spring源码第五(二)篇:Spring中Bean的加载
- Spring源码阅读——Bean的加载和获取过程
- Spring源码阅读——简单模拟Spring的控制反转IOC和依赖注入(Bean的加载和获取)
- spring boot实战(第十篇)Spring boot Bean加载源码分析
- Spring源码分析:非懒加载的单例Bean初始化前后的一些操作
- Spring源码之bean的加载(二)获取单例bean
- SSH 之 Spring的源码(一)——Bean加载过程
- Spring源码解析:简单容器中Bean的加载过程初探
- 【spring源码学习】spring的IOC容器之自定义xml配置标签扩展namspaceHandler向IOC容器中注册bean
- Spring源码分析之Bean的加载流程
- spring boot实战(第十篇)Spring boot Bean加载源码分析
- [spring源码学习]六、IOC源码-BeanFactory和factory-bean
- spring源码学习(1)-bean包中主要接口部分的简单介绍
- 创建ApplicationContext与BeanFactory时的区别-Spring源码学习之容器的基本实现