- 浏览: 208803 次
- 性别:
- 来自: 上海
文章分类
最新评论
-
flykarry:
说半天让我感觉NIO除了复杂了就没别的优点了
java Bio与Nio通信方式小例子 -
fei33423:
//最初的java socket ...
java Bio与Nio通信方式小例子 -
jason-:
我看AOP的源码也是你这个思路,但是在网上一搜,尼玛大多数的都 ...
spring源码分析之——spring aop原理 -
ooo456mmm:
java Bio与Nio通信方式小例子 -
ooo456mmm:
嗯,这个主要是讲了一下具体用法。
java Bio与Nio通信方式小例子
前面分析了bean解析的过程,知道了bean都是以beandefinition的形式放在bean factory里面的。下面来看一下bean具体的获取过程。
Spring 提供了一个获取bean的工具方法:
WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc).getBean(String beanName);
OK,稍微追踪了一下代码,发现着落在了AbstraceBeanFactory下面:
public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } private <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { final String beanName = transformedBeanName(name); Object bean; // Eagerly check singleton cache for manually registered singletons. 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 = getObjectForBeanInstance(sharedInstance, name, beanName, null); } else { // Fail if we're already creating this bean instance: // We're assumably within a circular reference. if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } // Check if bean definition exists in this factory. 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); } 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 dependsOnBean : dependsOn) { getBean(dependsOnBean); registerDependentBean(dependsOnBean, beanName); } } // Create bean instance. if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { public Object getObject() throws BeansException { 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); } 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 '" + scopeName + "'"); } try { Object scopedInstance = scope.get(beanName, new ObjectFactory() { 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); } } } // Check if required type matches the type of the actual bean instance. if (requiredType != null && bean != null && !requiredType.isAssignableFrom(bean.getClass())) { throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass()); } return (T) bean; }
doGetBean....呃,好长的方法。慢慢研究一下。
Object sharedInstance = getSingleton(beanName);
这个方法首先去已经缓存了的Singleton里面寻找,如果没有,就到手工注入的singleton缓存里面寻找,如果没有,
再到缓存的FactoryBean类型的singleton里面寻找,如果还没有...继续doGetBean里面的下一步。
接下来如果当前beanfactory有parent,就到parentBeanFactory里面寻找,如果找不到,继续...
接下来就是获取spring里面当初解析出来的bean模板:RootBeanDefinition。然后
在当前factory下面注册一下依赖关系,下面就到了关键的步骤了,根据bean是singleton还是Prototype或者其他什么scope类型来分别定义bean的获取过程。下面以singleton为例来进行分析。
注意一下代码:
if (mbd.isSingleton()) { sharedInstance = getSingleton(beanName, new ObjectFactory() { public Object getObject() throws BeansException { 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); }
可见bean的生成委托给了createBean(name,mdb,args)方法。
这个方法的实现是在子类AbstractAutowireCapableBeanFactory里面。
protected Object createBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } // Make sure bean class is actually resolved at this point. resolveBeanClass(mbd, beanName); // Prepare method overrides. try { mbd.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbd.getResourceDescription(), 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, mbd); if (bean != null) { return bean; } } catch (Throwable ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "BeanPostProcessor before instantiation of bean failed", ex); } Object beanInstance = doCreateBean(beanName, mbd, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
从上面的代码可以看出,先调用了resolveBeforeInstantiation方法。如果返回一个非空对象,那么就直接返回这个对象。 于是分析一下这个方法:
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.hasBeanClass() && !mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { bean = applyBeanPostProcessorsBeforeInstantiation(mbd.getBeanClass(), beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
是不是似曾相识哪?那就对了 ! Aop的实现的核心啊,回想一下AbstractAutoProxyCreator,就是实现了InstantiationAwareBeanPostProcessor接口。从AbstractAutoProxyCreator的postProcessBeforeInstantiation代码可以很容易的看出,如果bean需要代理,那么返回一个代理类,否则返回Null.
结合当前代码,那就是如果产生了代理类,那么试着调用beanpostprocessors的postProcessAfterInitialization方法,然后返回这个代理类。从这里也可以看出,如果被代理的类定义了postProcessBeforeInitialization,init等方法,将根本没有调用的机会! 所以被代理类在实现BeanPostProcessor,InitilizingBean等接口时要非常小心。否则可能发现有些方法根本没有回调。
当然了,不一定非要产生代理类,也有可能有其他的实现了InstantiationAwareBeanPostProcessor接口的类也返回非空,这里就不详细分析。我大致看了一下,至少我看的几个实现了InstantiationAwareBeanPostProcessor接口的类是返回null的,除了AbstractAutoProxyCreator.
下面继续。如果调用InstantiationAwareBeanPostProcessor后依然返回Null,那么就继续下面的步骤,也就是激动人心的bean的instantiation过程了!这里是调用了doCreateBean(beanName, mbd, args)方法:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) { // 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); // Allow post-processors to modify the merged bean definition. synchronized (mbd.postProcessingLock) { if (!mbd.postProcessed) { applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName); mbd.postProcessed = true; } } // Eagerly cache singletons to be able to resolve circular references // even when triggered by lifecycle interfaces like BeanFactoryAware. 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() { public Object getObject() throws BeansException { return getEarlyBeanReference(beanName, mbd, bean); } }); } // Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); if (exposedObject != null) { 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); } } if (earlySingletonExposure) { Object earlySingletonReference = getSingleton(beanName, false); if (earlySingletonReference != null) { if (exposedObject == bean) { exposedObject = earlySingletonReference; } else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) { String[] dependentBeans = getDependentBeans(beanName); Set<String> actualDependentBeans = new LinkedHashSet<String>(dependentBeans.length); for (String dependentBean : dependentBeans) { if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) { actualDependentBeans.add(dependentBean); } } if (!actualDependentBeans.isEmpty()) { throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been " + "wrapped. This means that said other beans do not use the final version of the " + "bean. This is often the result of over-eager type matching - consider using " + "'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example."); } } } } // Register bean as disposable. try { registerDisposableBeanIfNecessary(beanName, bean, mbd); } catch (BeanDefinitionValidationException ex) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex); } return exposedObject; }
汗~又是一个长方法。慢慢分析。
这个方法大致分为这么几步:
1. 产生一个beanwrapper.
2. 调用实现了MergedBeanDefinitionPostProcessors接口的类
3. populateBean
4. 初始化bean
5. 注册产生的bean
下面分别就前几个步骤进行分析。
1. 产生beanwrapper
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) { // Make sure bean class is actually resolved at this point. Class beanClass = resolveBeanClass(mbd, beanName); if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) { throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Bean class isn't public, and non-public access not allowed: " + beanClass.getName()); } if (mbd.getFactoryMethodName() != null) { return instantiateUsingFactoryMethod(beanName, mbd, args); } // Shortcut when re-creating the same bean... if (mbd.resolvedConstructorOrFactoryMethod != null && args == null) { if (mbd.constructorArgumentsResolved) { 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); }
在这里可以看出,如果为bean定义了factoryMehtod或者constructor,那么将分别根据factoryMethod或construcgtor完成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>() { public Object run() { return getInstantiationStrategy().instantiate(mbd, beanName, parent); } }, getAccessControlContext()); } else { beanInstance = 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接口,这个接口定了bean初始化的策略。比如在
当前类AbstractAutowireCapableBeanFactory下面一开始就定义了一个变量:
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();
可见,默认的初始化策略是CglibSubclassingInstantiationStrategy。
这个策略的特殊之处就在于如果bean需要有method injection,那么就通过cglib代理的方式产生原本的bean class的一个子类从而实现method override.
OK,至此BeanWrapper的生成基本清晰了。
下面就是实现了MergedBeanDefinitionPostProcessors的类的调用了。这个接口的具体意思我还不是很清楚。稍后研究一下补全。
然后就是populateBean. 这个方法就是把BeanDefinition里面维护的bean的属性populate到beanwrapper里面。
接下来就是bean的初始化:
if (exposedObject != null) {
exposedObject = initializeBean(beanName, exposedObject, mbd);
了解bean的初始化流程还是蛮有意义的:
protected Object initializeBean(final String beanName, final Object bean, RootBeanDefinition mbd) { if (System.getSecurityManager() != null) { AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { invokeAwareMethods(beanName, bean); return null; } }, getAccessControlContext()); } else { invokeAwareMethods(beanName, bean); } Object wrappedBean = bean; if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName); } try { invokeInitMethods(beanName, wrappedBean, mbd); } catch (Throwable ex) { throw new BeanCreationException( (mbd != null ? mbd.getResourceDescription() : null), beanName, "Invocation of init method failed", ex); } if (mbd == null || !mbd.isSynthetic()) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }
可见初始化顺序是: XXAware接口的实现->postProcessBeforeInitialization->InitializingBean的afterPropertiesSet-> custom Init方法->postProcessAfterInitialization
OK.这就是bean初始化的顺序啦!
最后当然就是bean的注册了!
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) { AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null); if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) { if (mbd.isSingleton()) { // Register a DisposableBean implementation that performs all destruction // work for the given bean: DestructionAwareBeanPostProcessors, // DisposableBean interface, custom destroy method. registerDisposableBean(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } else { // A bean with a custom scope... Scope scope = this.scopes.get(mbd.getScope()); if (scope == null) { throw new IllegalStateException("No Scope registered for scope '" + mbd.getScope() + "'"); } scope.registerDestructionCallback(beanName, new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc)); } } }
这里面涉及到了bean以及与scope相关的生命周期的管理,需要单独分析一下。下篇文章再分析。
评论
不过我是想知道rootBeanDefinition是怎么初始化的而搜到您这儿的,没细看,还请见谅~。因为现在我遇到的问题是rootBeanDefinition里的东西为空,,我想您能很快找到源码的地方吗?
相关推荐
《Spring源码分析——BeanFactory》 在Java的IoC(Inversion of Control)和DI(Dependency Injection)领域,Spring框架扮演着至关重要的角色。BeanFactory是Spring的核心组件之一,它是容器的基石,负责管理应用...
《Spring源码分析——ApplicationContext》 在Java世界中,Spring框架是不可或缺的一部分,它以其强大的IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)特性,极大地...
分析Spring源码有助于深入理解其动态代理的工作原理。例如,可以查看`org.springframework.aop.framework.JdkDynamicAopProxy`和`org.springframework.aop.framework.CglibAopProxy`这两个类,它们分别实现了JDK和...
《Spring5 源码分析(第 2 版)》是某Tom老师精心编写的深度解析文档,旨在帮助读者全面理解Spring5的核心机制和设计理念。Spring作为Java领域最为广泛应用的框架之一,其源码的深入理解对于开发者来说至关重要。这篇...
在源码分析的过程中,读者会深入理解Spring的内部工作机制,例如如何解析配置、如何创建bean实例、如何实现AOP代理等。这将有助于开发者编写更高效、更健壮的代码,也能为参与Spring的扩展或定制打下坚实基础。 总...
Spring作为Java领域最广泛应用的框架之一,其核心组件包括依赖注入(Dependency Injection,DI)、AOP(面向切面编程)、资源管理、事件处理以及bean的生命周期管理等。这些组件构成了Spring应用程序的基础,使得...
### Spring源码分析_Spring_IOC:深入理解Spring的IOC容器机制 #### 基本概念与核心作用 在探讨Spring框架的核心组件之一——IOC(Inversion of Control,控制反转)容器之前,首先需要理解它在Spring框架中的角色...
### Spring 源码分析——设计模式篇 #### 一、引言 Spring框架作为Java企业级开发领域中不可或缺的一部分,其内部集成了多种设计模式,不仅有助于提高系统的可维护性和扩展性,还能够帮助开发者更好地理解和应用...
本压缩包“Spring源码解析”提供了对Spring框架核心组件——IOC(Inversion of Control,控制反转)、AOP(Aspect Oriented Programming,面向切面编程)以及Transaction(事务管理)的源码分析,帮助开发者更全面地...
《Spring IOC源码解析(一)——整体介绍》 在深入理解Spring框架的过程中,源码分析是不可或缺的一环。本文将对Spring的IOC(Inversion of Control,控制反转)...希望本文能为你开启Spring源码探索之旅的第一步。
《Spring高级源码分析》是针对Java开发人员深入理解Spring框架的一份宝贵资源。Spring作为Java企业级应用的基石,其强大的功能和灵活性源于其深厚的设计理念和精巧的源码实现。本分析将深入探讨Spring的核心机制,...
《Spring框架源码分析——基于UML图的解读》 在深入探讨Spring框架源码之前,我们首先要理解什么是UML(统一建模语言)。UML是一种标准的图形化建模语言,用于软件设计和系统分析,它通过图表来表示系统的结构、...
### Spring源码分析之IOC容器深入探讨 #### 一、Spring框架及IOC容器概述 Spring框架作为企业级Java开发中最常用的轻量级框架之一,以其强大的功能和灵活的设计深受开发者们的喜爱。Spring的核心特性之一便是...
6. **Spring源码分析**:通过阅读源码,理解Spring框架的工作原理,增强对框架的深入理解。 接下来,我们转向MyBatis,这是一个轻量级的持久层框架,它提供了灵活的SQL映射机制,使得数据库操作变得简单。"MyBatis3...
在本资源中,我们提供了可以直接导入Eclipse的Spring源码的第五部分,版本为4.3.18。这一版本的Spring包含了众多改进和修复,对于理解Spring的工作原理以及进行自定义开发非常有帮助。 首先,让我们深入了解一下...
在源码分析中,我们首先看到`prepareContext`方法被调用,这是`SpringApplication`类中的一个重要方法,它负责初始化`ApplicationContext`(应用上下文)并为后续的bean加载做准备。 `prepareContext`方法做了以下...
通常,Spring源码的构建会依赖于一系列的外部库,包括但不限于这些特定的版本——spring-cglib-repack-3.2.0.jar和spring-objenesis-repack-2.1.jar。 在编译Spring源码时,确保所有依赖项正确地包含在构建路径中是...
Spring框架是Java开发中最常用的...对于初学者,通过阅读和分析这些源码,可以加深对Spring的理解,提升开发技能。同时,文档则可能包含Spring的使用指南、最佳实践以及常见问题解答,是学习和解决问题的重要参考资料。
总之,通过深入学习Spring源码,开发者不仅可以提升编程能力,还能掌握更多软件设计和架构方面的知识,对于职业发展大有裨益。在实际开发中,结合源码理解,能够更好地解决遇到的问题,优化代码,提高工作效率。
### Java毕业设计&课设——Spring源码深度解析+注解开发全套视频教程知识点概览 #### 一、Spring框架简介 Spring框架是由Rod Johnson创建的一款开源轻量级Java EE应用框架,旨在简化企业级应用的开发过程。Spring...