Bean实例化(Spring源码阅读)

我们到底能走多远系列(33)

扯淡:

  各位:

    命运就算颠沛流离    命运就算曲折离奇    命运就算恐吓着你做人没趣味    别流泪 心酸 更不应舍弃

    …

主题:

  Spring源码阅读还在继续,上篇文章初始化IoC容器:摸我

  事实上前面的IOC容器初始化只是建立了BeanDefinition数据映射,而依赖注入的过程是在向Ioc容器索要bean的时候发生的。

  getBean就是触发依赖注入的地方。

  1,下面是AbstractBeanFactory的getBean实现。根据scop进行分支处理,香港服务器,比较清晰:

  注意:关于spring中的 bean的scop属性,有两个很常用:singleton和prototype

  singleton:这是Spring容器默认的作用域,使用singleton作用域生成的是单实例,在整个Bean容器中仅保留一个实例对象供所有调用者共享引用。单例模式对于那些无会话状态的Bean(如辅助工具类、DAO组件、业务逻辑组件等)是最理想的选择。

  prototype:原型模式,这是多实例作用域,针对每次不同的请求,Bean容器均会生成一个全新的Bean实例以供调用者使用。

public Object getBean(String name) throws BeansException {doGetBean(name, null, null, false);}public <T> T getBean(String name, Class<T> requiredType) throws BeansException {return doGetBean(name, requiredType, null, false);}public Object getBean(String name, Object… args) throws BeansException {return doGetBean(name, null, args, false);}public <T> T getBean(String name, Class<T> requiredType, Object… args) throws BeansException {return doGetBean(name, requiredType, args, false);}

View Code

protected <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.// 从已经建立的实例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 = getObjectForBeanInstance(sharedInstance, name, beanName, null);}else {// Fail if we’re already creating this bean instance: (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) { (T) parentBeanFactory.getBean(nameToLookup, args);}else { 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.// 取得本bean的依赖bean组String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {// 循环调用getBean方法,递归实现本bean的全部依赖for (String dependsOnBean : dependsOn) {getBean(dependsOnBean);registerDependentBean(dependsOnBean, beanName);}}// Create bean instance.// Singleton 情况if (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {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);}// Prototype 情况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);}else {// 其他scop情况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<Object>() {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);}}}

2,上面代码会调用到AbstractAutowireCapableBeanFactory 的 createBean方法,这个方法中调用了内部的doCreateBean方法,createBean方法:

坐在外婆的沙滩,看最白的帆影。

Bean实例化(Spring源码阅读)

相关文章:

你感兴趣的文章:

标签云: