Spring获取单例getSingleton(1)
2016-01-22 14:13
417 查看
标签: spring源码学习
spring获取单例首先是从缓存去找,如果找不到就要从头开始bean的加载过程,spring中主要通过getSingleton的重载方法实现单例bean的加载过程
要创建一个bean的单例,首先了解下单例是什么样子的,
spring创建单例bean主要查看 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry类的getSingleton(String beanName, ObjectFactory
现在继续去找创建bean的回调方法
createBean方法里面还是在做一些准备工作,真正的创建bean交给了doCreateBean
在这里首先关注下AbstractBeanDefinition类的prepareMethodOverrides方法
spring配置中存在lookup-method和replace-method两个配置功能,这两个配置的加载就是将配置存储在BeanDefinition中的methodOverrides属性里面。功能的实现原理是在bean的实例化的时候如果检测到存在methodOverrides属性,会动态的为当前bean生成代理并使用对应的拦截器为bean做增强处理。
下一篇继续从doCreateBean说起。
spring获取单例首先是从缓存去找,如果找不到就要从头开始bean的加载过程,spring中主要通过getSingleton的重载方法实现单例bean的加载过程
要创建一个bean的单例,首先了解下单例是什么样子的,
[code] public static synchronized Singleton getInstance() { if (single == null) { single = new Singleton(); } return single; }
spring创建单例bean主要查看 org.springframework.beans.factory.support.DefaultSingletonBeanRegistry类的getSingleton(String beanName, ObjectFactory
[code]public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) { Assert.notNull(beanName, "'beanName' 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 the 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 + "'"); } //把当前正在创建的bean记录在缓存中,对循环依赖进行检测 beforeSingletonCreation(beanName); boolean newSingleton = false; boolean recordSuppressedExceptions = (this.suppressedExceptions == null); if (recordSuppressedExceptions) { this.suppressedExceptions = new LinkedHashSet<Exception>(); } try { //使用回调方法 创建单例bean singletonObject = singletonFactory.getObject(); newSingleton = true; } catch (IllegalStateException ex) { 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; } //移除缓存中对该bean正在加载的状态 afterSingletonCreation(beanName); } if (newSingleton) { //将新创建的bean加入缓存,并且删除加载bean过程中所记录的各种辅助状态 //这些辅助状态主要是在回调方法创建bean时候引入的 addSingleton(beanName, singletonObject); } } return (singletonObject != NULL_OBJECT ? singletonObject : null); } }
现在继续去找创建bean的回调方法
[code]sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { try { //创建bean的核心实现又调用了createBean方法 return createBean(beanName, mbd, args); } catch (BeansException ex) { destroySingleton(beanName); throw ex; } } }); //创建完的beanInstance还不一定不是我们最终需要的bean 还需要加工验证正确性 bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
createBean方法里面还是在做一些准备工作,真正的创建bean交给了doCreateBean
[code]@Override protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { if (logger.isDebugEnabled()) { logger.debug("Creating instance of bean '" + beanName + "'"); } RootBeanDefinition mbdToUse = mbd; //根据指定的BeanDefinition信息 解析bean class 并且存储在BeanDefinition中 Class<?> resolvedClass = resolveBeanClass(mbd, beanName); //对已有的bean definition进行克隆 以防一动态解析的class不能存储在合并的bean definition中 //这里说的动态解析的class是指在bean class的定义中使用EL表达式或者自己定义的beanExpressionResolver if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null){ mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } try { //验证及准备覆盖的方法 mbdToUse.prepareMethodOverrides(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(), beanName, "Validation of method overrides failed", ex); } try { //给beanPostProcessors一个机会返回代理来替代真正的实例 //这里的beanPostProcessors是指InstantiationAwareBeanPostProcessor类型 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); } //创建bean的过程又交给了doCreateBean,spring中以doxxx开头的方法就是真正干活的方法 Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isDebugEnabled()) { logger.debug("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }
在这里首先关注下AbstractBeanDefinition类的prepareMethodOverrides方法
[code] public void prepareMethodOverrides() throws BeanDefinitionValidationException { // Check that lookup methods exists. MethodOverrides methodOverrides = getMethodOverrides(); if (!methodOverrides.isEmpty()) { for (MethodOverride mo : methodOverrides.getOverrides()) { prepareMethodOverride(mo); } } }
[code]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); } }
spring配置中存在lookup-method和replace-method两个配置功能,这两个配置的加载就是将配置存储在BeanDefinition中的methodOverrides属性里面。功能的实现原理是在bean的实例化的时候如果检测到存在methodOverrides属性,会动态的为当前bean生成代理并使用对应的拦截器为bean做增强处理。
下一篇继续从doCreateBean说起。
相关文章推荐
- Java基础-了解Hashtable
- 【spring源代码分析】--Bean的解析与注冊
- Hive学习1_hive配置遇到的问题:Relative path in absolute URI: ${system:java.io.tmpdir%7D/$%7Bsystem:user.name%
- JAVA设计模式:组合模式
- eclipse快捷键汇总
- java基础篇--01<基础>
- java.lang.IllegalStateException: ScrollView can host only one direct child
- JavaEE 之 JPA 常见异常处理办法汇总
- 关于struts2的那点事
- static关键字--java
- Vector and ArrayList in Java
- Java 方法
- 手动编译JAVA类
- JavaSE001_String类总结之构造器和常用方法
- android studio 导入eclipse遇到的相关问题
- java ftp相关的异常汇总
- Spring+MVC项目发布停止
- java前台传参json,后台用map或者实体对象接收
- java.lang.RuntimeException: JPedal Trial has now expired
- java 实现多线程的三种基本方式