相关文章java
FactoryBean 接口spring
BeanFactory 接口 sql
BeanFactory 接口 和 FactoryBean 接口的区别数组
getBean 方法的源码解析缓存
Spring 循环依赖的解决方式mybatis
在文章 Spring 中 bean 注册的源码解析 和 Spring bean 建立过程源码解析 了解了 bean 的注册和建立过程,当经过 getBean 方法来获取对应 bean 的时候,会是如何的呢?下面就来看看 getBean 方法的内部实现。在进入 getBean 方法内部以前,先来看看 FactoryBean 这个接口,由于在 getBean 方法内部会对该接口的实现类进行另外的处理。ide
这个接口和 BeanFactory 接口很是的像,可是做用却大相径庭,先来看看 javadoc 文档的定义,大体意思就是:若是某个 bean 实现了这个接口,经过 getBean 方法来获取 bean 的时候,并非返回本身的实例,而是返回其 getObject() 方法的返回值;此外 FactoryBeans 能够支持 singletons 和 prototypes 模式。它的源码以下,只有 三个 方法:工具
public interface FactoryBean<T> { // 返回 bean 的实例,即调用 getBean 方法获取到的实例就是该方法的返回值 T getObject() throws Exception; // 返回 bean 的类型 Class<?> getObjectType(); // 该 bean 是不是单例模式 boolean isSingleton(); }
那么这个 FactoryBean 接口有什么用呢?经过 Spring bean 建立过程源码解析 知道,bean 的实例化就是使用反射和CGLIB来实现的,可是在某些状况下,实例化 Bean 过程比较复杂,若是按照传统的方式,则须要在配置文件 <bean> 中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会获得一个简单的方案。因此,用户能够经过实现该接口定制实例化 Bean 的逻辑。
先来看一个栗子,如今有个 User 对象,传统的方式,在配置文件中配置以下:
public class User { private String name; private int age; private int sex; private double money; private String job; // setter / getter / toString }
<bean id="user" class="main.tsmyk.pojo.User"> <property name="name" value="zhangsan"/> <property name="age" value="20"/> <property name="job" value="java"/> <property name="money" value="10000"/> <property name="sex" value="1"/> </bean>
测试:
ApplicationContext context = new ClassPathXmlApplicationContext("myspring.xml"); User user = (User) context.getBean("user"); System.out.println(user); 结果:User{name='zhangsan', age=20, sex=1, money=10000.0, job='java'}
从打印的结果能够看到 User 对象的属性都被附上了值。
可是,若是 User 对象的属性不少,不想写不少的 <property> 标签,则能够经过 FactoryBean 接口来实现,在该接口内部,按照必定的规则来解析 User 对象的属性并赋值。以下所示:
public class UserFactoryBean implements FactoryBean<User> { private String user; @Override public User getObject() throws Exception { User user = new User(); String[] userInfos = this.user.split(";"); user.setName(userInfos[0]); user.setAge(Integer.parseInt(userInfos[1])); user.setJob(userInfos[2]); user.setMoney(Double.parseDouble(userInfos[3])); user.setSex(Integer.parseInt(userInfos[4])); return user; } @Override public Class<User> getObjectType() { return User.class; } @Override public boolean isSingleton() { return false; } public String getUser() { return user; } public void setUser(String user) { this.user = user; } }
在该类的 getObject 方法内部对 User 对象的属性进行解析并赋值,经过 getBean 方法获取 bean 的时候,获得的就是 getObject 方法返回的 User 对象,配置以下:
<bean id="userFactory" class="main.tsmyk.beans.UserFactoryBean"> <property name="user" value="zhangsan;20;java;10000;1"/> </bean>
测试:
ApplicationContext context = new ClassPathXmlApplicationContext("myspring.xml"); User user1 = (User) context.getBean("userFactory"); System.out.println(user1); 结果:User{name='zhangsan', age=20, sex=1, money=10000.0, job='java'}
能够看到和上面传统的方式是同样的。也验证了 getBean 方法获取到的是 getObject 方法的返回值,而不是 FactoryBean 实例自己;可是,若是就想获取到 FactoryBean 的实例自己,也是能够的,在 bean 的名字前加 & 符号就能够了,即 getBean("&userFactory");
测试:
ApplicationContext context = new ClassPathXmlApplicationContext("myspring.xml"); UserFactoryBean userBean = (UserFactoryBean) context.getBean("&userFactory"); System.out.println(userBean.getUser()); 结果:zhangsan;20;java;10000;1
敲黑板:因此说,经过 getBean(String beanName) 方法来获取实例的时候,beanName 有多是以 & 开头的,若是 beanName 以 & 开头,就表示处理的是 FactoryBean 接口
Spring 自身也提供了 FactoryBean 接口的不少实现,如 JndiObjectFactoryBean 类:
public class JndiObjectFactoryBean extends JndiObjectLocator implements FactoryBean<Object>, BeanFactoryAware, BeanClassLoaderAware { private Object jndiObject; // 其余复杂的计算,为 jndiObject 赋值 @Override public Object getObject() { return this.jndiObject; } }
咱们熟知的第三方 ORM 框架 Mybatis 也提供了该接口的实现 SqlSessionFactoryBean :
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> // 其余配置 </bean>
public class SqlSessionFactoryBean implements FactoryBean<SqlSessionFactory>, InitializingBean, ApplicationListener<ApplicationEvent> { private SqlSessionFactory sqlSessionFactory; @Override public SqlSessionFactory getObject() throws Exception { if (this.sqlSessionFactory == null) { afterPropertiesSet(); } return this.sqlSessionFactory; } // 其余方法 }
因此经过 getBean 方法获取的时候,获得的是 SqlSessionFactory 而不是 SqlSessionFactoryBean
如今来看看和 FactoryBean 很类似的一个接口 BeanFactory ,BeanFactory 它是 Spring IOC 容器的核心接口,它定义了 容器的主要功能,如建立 bean,获取 bean 等,它是用来管理 bean 的,即它是用来 实例化、定位、配置应用程序中的对象及创建这些对象间的依赖关系的。它的源码以下:
public interface BeanFactory { String FACTORY_BEAN_PREFIX = "&"; Object getBean(String name) throws BeansException; <T> T getBean(String name, Class<T> requiredType) throws BeansException; Object getBean(String name, Object... args) throws BeansException; <T> T getBean(Class<T> requiredType) throws BeansException; <T> T getBean(Class<T> requiredType, Object... args) throws BeansException; boolean containsBean(String name); boolean isSingleton(String name) throws NoSuchBeanDefinitionException; boolean isPrototype(String name) throws NoSuchBeanDefinitionException; boolean isTypeMatch(String name, ResolvableType typeToMatch); boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException; Class<?> getType(String name) throws NoSuchBeanDefinitionException; String[] getAliases(String name); }
能够看到定义了容器的基本功能,注意它有一个属性 FACTORY_BEAN_PREFIX = "&" 就是用来表示 FactoryBean 接口的 beanName 的前缀。
到这里,经过源码就能够看到,虽然 FactoryBean 和 BeanFactory 很像,但它们的做用彻底不一样,
FactoryBean 能够看作一个工厂,用它来建立一些负责的 bean
BeanFactory 定义了 Spring 容器基本的功能,交由子类去实现,用于管理 bean
User user = (User) beanFactory.getBean("user");
@Override public Object getBean(String name) throws BeansException { return doGetBean(name, null, null, false); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { return doGetBean(name, requiredType, null, false); } @Override public Object getBean(String name, Object... args) throws BeansException { return doGetBean(name, null, args, false); }
接下来看下 doGetBean 方法:
protected <T> T doGetBean(final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException { // 提取对应的 beanName,处理别名和FactoryBean接口的实现类,即 beanName 以 & 开头 final String beanName = transformedBeanName(name); Object bean; // 尝试从缓存中或者ObjectFactory中获取 Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { if (isSingletonCurrentlyInCreation(beanName)) { logger.debug("......"); } // 这里主要处理 FactoryBean,有时候并非返回实例自己,而是返回指定方法返回的实例 bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } // 缓存中不存在该bean的实例 else { // 这里bean的做用域是原型模式,且存在循环依赖,出现循环依赖,则抛出异常 if (isPrototypeCurrentlyInCreation(beanName)) { throw new BeanCurrentlyInCreationException(beanName); } BeanFactory parentBeanFactory = getParentBeanFactory(); // 若是当前的的beanDefinitionMap即配置文件不包含该bean,则从parentBeanFactory 中查找 if (parentBeanFactory != null && !containsBeanDefinition(beanName)) { String nameToLookup = originalBeanName(name); if (args != null) { // 这个 args 是 getBean(beanName, args...) 方法传入的 return (T) parentBeanFactory.getBean(nameToLookup, args); } else { return parentBeanFactory.getBean(nameToLookup, requiredType); } } // 若是不只仅是作类型检查,则是建立bean,则进行标记,标记该bean以建立 if (!typeCheckOnly) { markBeanAsCreated(beanName); } // 将配置文件中GenericBeanDefinition转换为RootBeanDefinition,若是beanName是子bean的话,会合并父类的属性 final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); checkMergedBeanDefinition(mbd, beanName, args); // 处理依赖,若是存在依赖,则递归实例化依赖的bean String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException("........"); } registerDependentBean(dep, beanName); getBean(dep); } } //实例化 bean if (mbd.isSingleton()) { // 实例化单例的bean sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return createBean(beanName, mbd, args); }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // 实例化原型的bean Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { // 指定的 score 上实例化bean String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); Object scopedInstance = scope.get(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { beforePrototypeCreation(beanName); try { return createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } }); bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd); } } } } // 处理参数类型的转换 if (requiredType != null && bean != null && !requiredType.isInstance(bean)) { return getTypeConverter().convertIfNecessary(bean, requiredType); } return (T) bean; }
从 上述的代码能够看到,doGetBean 方法流程是很清晰的,每一步都使用对应的方法进行处理,它的流程主要以下:
1. 处理 beanName,为何要处理 beanName呢,由于 bean 是能够有别名的,且,在上面介绍 FactoryBean 接口的时候,获取该 bean 的时,须要加上 & 前缀,因此这里要去掉&
2. 尝试从缓存中加载该 bean,由于单例的 bean 只会加载一次,若是缓存中不存在该 bean,则会尝试从 singletonFactories 中加载,这个 singletonFactories 是什么呢? 在 Spring bean 建立过程源码解析 知道, bean 在建立的时候可能会存在依赖注入的状况,而在建立依赖 bean 的时候,为了 避免循环依赖,那么在建立该 bean 的时候,不等到 bean 建立完成就会把建立该 bean 的 ObjectFactory 放到 singletonFactories 缓存中,一旦下一个 bean 建立的时候,须要依赖上一个 bean 则直接从 singletonFactories 缓存中获取该 ObjectFactory 来进行建立,好比 A 依赖 B,A --> B,如今建立 A 的实例 beanA,建立过程当中,就把建立 A 的 ObjectFactory 放到 singletonFactories 缓存中,如今发现 A 依赖于 B,则如今要去建立 B 的实例 beanB,当建立完 beanB 后才会继续建立 beanA;若是如今发现 B 也依赖于 A,B --> A,那么在建立 beanB 的时候,也会先去建立 beanA,由于以前建立 A 的实例 beanA 的时候,已经把 A 的 ObjectFactory 放入到 缓存中了,如今直接去缓存中取出该 ObjectFactory 便可,试想一下,若是没有事先把 A 的 ObjectFactory 放到缓存中,那么在建立 B 的时候,先去建立 A ,建立 A 的时候发现依赖 B ,则又会去 建立 B,这样就会形成循环依赖,就会实例化失败。
因此 Spring 是经过这种方法是解决 bean 之间循环依赖的,可是仅仅是处理单例的循环依赖,原型或其余的则会抛出异常。关于 bean 的建立能够参考 Spring bean 建立过程源码解析
3. 建立 bean
3.1 从父类查找 bean
3.2 将 GenericBeanDefinition 转换为 RootBeanDefinition,由于从配置文件加载 bean 的时候,是以 GenericBeanDefinition 方式保存的
3.3 处理依赖
3.4 建立 单例的 bean
3.5 建立 原型的 bean
3.6 建立其余 score 做用于的 bean
3.7 参数类型的转换
4. 处理 FactoryBean 接口的 bean
流程是否是很清晰,再经过流程图来看更清晰:
下面看看每一个部分。
当经过 getBean 方法获取 bean 的时候,bean 的 name 是能够以 & 开头的,即获取 FactoryBean 实例自己,此外,bean 还有别名,一个 bean 能够有多个别名等,全部在这里首先要提取 bean 的名称,即 方法 transformedBeanName:
final String beanName = transformedBeanName(name); protected String transformedBeanName(String name) { String beanName = BeanFactoryUtils.transformedBeanName(name); return canonicalName(beanName); } // 使用工具类 BeanFactoryUtils 来转名字 public static String transformedBeanName(String name) { String beanName = name; // 若是 beanName 以 & 开头,则去掉 & while (beanName.startsWith(BeanFactory.FACTORY_BEAN_PREFIX)) { beanName = beanName.substring(BeanFactory.FACTORY_BEAN_PREFIX.length()); } // 返回去掉 & 后的 beanName return beanName; } // 返回原始的bean的名字,解决别名 public String canonicalName(String name) { String canonicalName = name; String resolvedName; // while 循环,由于 bean 的别名能够有多个 do { resolvedName = this.aliasMap.get(canonicalName); if (resolvedName != null) { canonicalName = resolvedName; } } while (resolvedName != null); return canonicalName; }
Object sharedInstance = getSingleton(beanName); if (sharedInstance != null && args == null) { // 处理 FactoryBean bean = getObjectForBeanInstance(sharedInstance, name, beanName, null); } // 获取 bean public Object getSingleton(String beanName) { return getSingleton(beanName, true); } protected Object getSingleton(String beanName, boolean allowEarlyReference) { // 从缓存中获取bean,该缓存singletonObjects用来存放已经建立完毕的bean的实例 Object singletonObject = this.singletonObjects.get(beanName); // 若是缓存中没有,且该 bean 正在建立 if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) { synchronized (this.singletonObjects) { // 从正在建立bean的缓存中获取,该 earlySingletonObjects 缓存是用来存放正在建立且尚未建立完毕的bean singletonObject = this.earlySingletonObjects.get(beanName); // 若是此时仍是获取不到实例,且容许从ObjectFactory中获取,解决循环引用 if (singletonObject == null && allowEarlyReference) { // 从 ObjectFactory 中获取对应的工厂,使用工厂建立建立对象,由于以前在建立该bean的时候且尚未建立完毕的时候,已经把该bean的 ObjectFactory 放入到缓存中 ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); // 获取到工厂以后,进行建立bean的实例,并放入到对应的缓存中 if (singletonFactory != null) { singletonObject = singletonFactory.getObject(); this.earlySingletonObjects.put(beanName, singletonObject); this.singletonFactories.remove(beanName); } } } } // 若是缓存中没有,且该bean没有正在建立,则直接返回 nul return (singletonObject != NULL_OBJECT ? singletonObject : null); }
在该方法里面会尝试解决循环依赖,该方法会涉及到 3 个 map 类型的缓存:
因此上述方法的主要逻辑就是先从 singletonObjects 获取实例,若是获取不到,即该 bean 尚未建立;再从 earlySingletonObjects 获取,若是获取不到,即该bean没有正在建立,再从 ObjectFactory 获取对应的工厂来建立,若是到最后仍是获取不到,则返回 null、
获取到 bean的实例后,须要处理 诸如 FactoryBean 和 factory-method 之类的方法,在后面从不一样的 score 获取到 bean 的实例后,都会执行该方法:
protected Object getObjectForBeanInstance( Object beanInstance, String name, String beanName, RootBeanDefinition mbd) { // 若是 bean 的实例不是 FactoryBean 类型,便是通常的 bean ,能够直接返回 // 若是 beanName 是以 & 开头,则也直接返回,由于 beanName 以 & 开头,表示返回工厂实例自己 // BeanFactoryUtils.isFactoryDereference : name != null && name.startsWith("&") if (!(beanInstance instanceof FactoryBean) || BeanFactoryUtils.isFactoryDereference(name)) { return beanInstance; } Object object = null; if (mbd == null) { // 尝试从 FactoryBean 缓存中获取bean object = getCachedObjectForFactoryBean(beanName); } if (object == null) { // 到这里,已经明确了 bean的实例必定是 FactoryBean 类型 FactoryBean<?> factory = (FactoryBean<?>) beanInstance; if (mbd == null && containsBeanDefinition(beanName)) { mbd = getMergedLocalBeanDefinition(beanName); } boolean synthetic = (mbd != null && mbd.isSynthetic()); object = getObjectFromFactoryBean(factory, beanName, !synthetic); } return object; } // 经过 FactoryBean 来获取 bean 实例 protected Object getObjectFromFactoryBean(FactoryBean<?> factory, String beanName, boolean shouldPostProcess) { // 忽略了其余代码 // doGetObjectFromFactoryBean -> factory.getObject(),返回的是 FactoryBean 的 getObject 方法的返回值 object = doGetObjectFromFactoryBean(factory, beanName); return object; }
通过了上述几步,发现从获取中还获取不到实例的话,就会进行 bean 的实例化。当时在建立以前,若是该 bean 有依赖的 bean,则先会处理依赖的bean:
String[] dependsOn = mbd.getDependsOn(); if (dependsOn != null) { for (String dep : dependsOn) { if (isDependent(beanName, dep)) { throw new BeanCreationException("循环依赖异常"); } // 注册循环依赖 registerDependentBean(dep, beanName); // 建立依赖的 bean getBean(dep); // return doGetBean(name); } }
if (mbd.isSingleton()) { // 建立单例的bean sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() { @Override public Object getObject() throws BeansException { return createBean(beanName, mbd, args); } }); bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd); } else if (mbd.isPrototype()) { // 建立原型的bean Object prototypeInstance = null; try { beforePrototypeCreation(beanName); prototypeInstance = createBean(beanName, mbd, args); } finally { afterPrototypeCreation(beanName); } bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd); } else { // 建立其余score的bean String scopeName = mbd.getScope(); final Scope scope = this.scopes.get(scopeName); 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); }
单例的 bean和其余score的bean的建立能够参考 Spring bean 建立过程源码解析 的 createBean 方法。
下面来看看建立原型的bean的过程:
protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException { RootBeanDefinition mbdToUse = mbd; // 解析 class Class<?> resolvedClass = resolveBeanClass(mbd, beanName); if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) { mbdToUse = new RootBeanDefinition(mbd); mbdToUse.setBeanClass(resolvedClass); } // 处理 lookup-method 和 replace-method 属性,在 “Spring 中 bean 注册的源码解析“ 从已经解析过 mbdToUse.prepareMethodOverrides(); // 在该方法里面会执行前置处理器和后置处理器 Object bean = resolveBeforeInstantiation(beanName, mbdToUse); // 若是应用前置处理和后置处理器改变了bean,就直接返回,AOP功能就在此实现 if (bean != null) { return bean; } // 正真建立bean Object beanInstance = doCreateBean(beanName, mbdToUse, args); return beanInstance; } // 应用前置处理器和后置处理器 protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { // 前置处理器 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { // 后置处理器 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } // 省略其余代码 return bean; } // 前置处理器 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; } // 后置处理器 public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) { result = beanProcessor.postProcessAfterInitialization(result, beanName); if (result == null) { return result; } } return result; }
通过了上述的步骤以后,就会获得一个 bean 的实例,不管这个bean是单例的仍是原型的,仍是其余的score的,总之到这里就已经获得了 bean 的实例,获得实例以后,咱们须要进行类型的转换,即 若是 bean 是一个 String,可是 requiredType 为 Integer ,则就须要进行类型的转换。
if (requiredType != null && bean != null && !requiredType.isInstance(bean)) { return getTypeConverter().convertIfNecessary(bean, requiredType); } // 获取类型转换器 public TypeConverter getTypeConverter() { TypeConverter customConverter = getCustomTypeConverter(); if (customConverter != null) { return customConverter; } else { SimpleTypeConverter typeConverter = new SimpleTypeConverter(); typeConverter.setConversionService(getConversionService()); registerCustomEditors(typeConverter); return typeConverter; } } // 类型的转换 public <T> T convertIfNecessary(Object value, Class<T> requiredType, Field field){ return doConvert(value, requiredType, null, field); } private <T> T doConvert(Object value, Class<T> requiredType, MethodParameter methodParam, Field field){ if (field != null) { return this.typeConverterDelegate.convertIfNecessary(value, requiredType, field); } else { return this.typeConverterDelegate.convertIfNecessary(value, requiredType, methodParam); } } // 正真类型的转换 public <T> T convertIfNecessary(String propertyName, Object oldValue, Object newValue, Class<T> requiredType, TypeDescriptor typeDescriptor) throws IllegalArgumentException { // 自定义转换器 PropertyEditor editor = this.propertyEditorRegistry.findCustomEditor(requiredType, propertyName); ConversionFailedException conversionAttemptEx = null; ConversionService conversionService = this.propertyEditorRegistry.getConversionService(); if (editor == null && conversionService != null && newValue != null && typeDescriptor != null) { TypeDescriptor sourceTypeDesc = TypeDescriptor.forObject(newValue); if (conversionService.canConvert(sourceTypeDesc, typeDescriptor)) { return (T) conversionService.convert(newValue, sourceTypeDesc, typeDescriptor); } } } // 省略其余代码 if (requiredType != null) { if (convertedValue != null) { // 类型为 class if (Object.class == requiredType) { return (T) convertedValue; } // 类型为数组 else if (requiredType.isArray()) { 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) { convertedValue = convertToTypedCollection((Collection<?>) convertedValue, propertyName, requiredType, typeDescriptor); standardConversion = true; } // 类型为 map else if (convertedValue instanceof Map) { convertedValue = convertToTypedMap( (Map<?, ?>) convertedValue, propertyName, requiredType, typeDescriptor); standardConversion = true; } if (convertedValue.getClass().isArray() && Array.getLength(convertedValue) == 1) { convertedValue = Array.get(convertedValue, 0); standardConversion = true; } // String if (String.class == requiredType && ClassUtils.isPrimitiveOrWrapper(convertedValue.getClass())) { return (T) convertedValue.toString(); } // String else if (convertedValue instanceof String && !requiredType.isInstance(convertedValue)) { if (conversionAttemptEx == null && !requiredType.isInterface() && !requiredType.isEnum()) { Constructor<T> strCtor = requiredType.getConstructor(String.class); return BeanUtils.instantiateClass(strCtor, convertedValue); } String trimmedValue = ((String) convertedValue).trim(); if (requiredType.isEnum() && "".equals(trimmedValue)) { return null; } convertedValue = attemptToConvertStringToEnum(requiredType, trimmedValue, convertedValue); standardConversion = true; } // number else if (convertedValue instanceof Number && Number.class.isAssignableFrom(requiredType)) { convertedValue = NumberUtils.convertNumberToTargetClass( (Number) convertedValue, (Class<Number>) requiredType); standardConversion = true; } } else { if (javaUtilOptionalEmpty != null && requiredType == javaUtilOptionalEmpty.getClass()) { convertedValue = javaUtilOptionalEmpty; } } // 省略其余代码 return (T) convertedValue; }
到这里 经过 getBean 就能获取到一个正确的 bean 了,
以上就是 getBean 方法的逻辑了,主要是须要知道 还能够经过 FactoryBean 来建立 bean,beanName 还能够是以 & 开头。