springIOC源码解析(四)
来源:互联网 发布:刘飞儿faye知乎 编辑:程序博客网 时间:2024/05/16 09:21
这两天工作比较闲,上午的时候我又仔细看了一遍spring初始化bean加载流程,下面我挑重点写一下我的收获
spring如何保持bean的单例
对于singleton的bean而言,spring在初始化bean之后,会把beanName及bean实例保存到一个map中(DefaultSingletonBeanRegistry中的singletonObjects);当再次要获取bean实例时直接从map中拿;而prototype的bean每次都从新创建一个
这里衍生出一个问题,这里的单例和单例模式中的单例是什么关系?我的理解是:单例模式中的单例,是通过设计方式让其自身成为单例,与容器无关.用单例模式创建的单例类,一般是工具类,不会让容器来管理;spring中的单例则是对于容器来说,也就是说,在spring的管理下,bean在容器中是保持单例,而其自身不是单例spring如何管理有依赖关系的bean
spring在创建bean实例之后,会用BeanWrapper对bean进行包装,BeanWrapper的主要功能之一就是为bean提供属性编辑器PropertyEditor,通过属性编辑器对属性进行赋值,主要代码如下
public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue, Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException { ...... Object convertedValue = newValue; ...... if (requiredType != null) { // Try to apply some standard type conversion rules if appropriate. if (convertedValue != null) { if (Object.class == requiredType) { return (T) convertedValue; } else if (requiredType.isArray()) { // Array required -> apply appropriate conversion of elements. if (convertedValue instanceof String && Enum.class.isAssignableFrom(requiredType.getComponentType())) { convertedValue = StringUtils.commaDelimitedListToStringArray((String) convertedValue); } return (T) convertToTypedArray(convertedValue, propertyName, requiredType.getComponentType()); } else if (convertedValue instanceof Collection) { // Convert elements to target type, if determined. convertedValue = convertToTypedCollection( (Collection<?>) convertedValue, propertyName, requiredType, typeDescriptor); standardConversion = true; } else if (convertedValue instanceof Map) { // Convert keys and values to respective target type, if determined. convertedValue = convertToTypedMap( (Map<?, ?>) convertedValue, propertyName, requiredType, typeDescriptor); standardConversion = true; } if (convertedValue.getClass().isArray() && Array.getLength(convertedValue) == 1) { convertedValue = Array.get(convertedValue, 0); standardConversion = true; } if (String.class == requiredType && ClassUtils.isPrimitiveOrWrapper(convertedValue.getClass())) { // We can stringify any primitive value... return (T) convertedValue.toString(); } else if (convertedValue instanceof String && !requiredType.isInstance(convertedValue)) { if (conversionAttemptEx == null && !requiredType.isInterface() && !requiredType.isEnum()) { try { Constructor<T> strCtor = requiredType.getConstructor(String.class); return BeanUtils.instantiateClass(strCtor, convertedValue); } catch (NoSuchMethodException ex) { // proceed with field lookup if (logger.isTraceEnabled()) { logger.trace("No String constructor found on type [" + requiredType.getName() + "]", ex); } } catch (Exception ex) { if (logger.isDebugEnabled()) { logger.debug("Construction via String failed for type [" + requiredType.getName() + "]", ex); } } } String trimmedValue = ((String) convertedValue).trim(); if (requiredType.isEnum() && "".equals(trimmedValue)) { // It's an empty enum identifier: reset the enum value to null. return null; } convertedValue = attemptToConvertStringToEnum(requiredType, trimmedValue, convertedValue); standardConversion = true; } else if (convertedValue instanceof Number && Number.class.isAssignableFrom(requiredType)) { convertedValue = NumberUtils.convertNumberToTargetClass( (Number) convertedValue, (Class<Number>) requiredType); standardConversion = true; } } else { // convertedValue == null if (javaUtilOptionalEmpty != null && requiredType == javaUtilOptionalEmpty.getClass()) { convertedValue = javaUtilOptionalEmpty; } } ...... return (T) convertedValue; }
- bean延迟加载问题
大家都知道设置lazy-init=”true”可以设置bean在需要的时候实例化(lazy-init默认false).但这里可能存在一个很容易忽略的细节,只有使用ApplicationContext的时候设置lazy-init才有能控制bean实例化的时机(是容器启动时还是需要使用时);如果使用BeanFactory bean只会在调getBean方法时(也就是需要使用时)进行实例化
OK,下一张我们分析通过ApplicationContext启动容器的过程
1 0
- springIOC源码解析(四)
- SpringIOC--初始化源码解析
- SpringIOC--初始化源码解析
- SpringIOC--初始化源码解析
- springIOC源码解析(一)
- springIOC源码解析(二)
- springIOC源码解析(三)
- springIOC源码解析(五)
- springIOC源码解析(六)
- SpringIOC源码解析
- SpringIOC源码解析
- SpringIOC源码序列图
- SpringIOC个人解析
- TFS源码解析四
- AFNetworking源码解析<四>
- AFNetworking源码解析<四>
- AFNetworking源码解析<四>
- AFNetworking源码解析<四>
- orcle同义词的创建
- Now直播应用的后台服务器性能测试实践
- 温习小知识---typedef
- 【模拟】Luogu P1518 两只塔姆沃思牛(The Tamworth Two)
- hbase行键过滤器RowFilter
- springIOC源码解析(四)
- Win8/8.1/10 ISE _pn.exe crash-崩溃问题解决
- java基础8_对象转型_接口
- ios之静态库的CPU架构
- [LeetCode]Subsets II
- 正则表达式判断字符串时间格式
- 整流二极管
- Android Handler详细使用方法实例
- Number.MAX_SAFE_INTEGER与Number.MAX_VALUE