上一节中将了如何通过xml文件中读取到bean的定义,链接为 Spring 二、主要逻辑代码赏析之获取bean的定义 ,这一节中,我们将会讲述读取出xml文件后,如何根据bean的定义来最终生成bean。
首先还是来看一下
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
初始的时候的refresh() 方法:
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
prepareRefresh();
. . .
// 此为获取一个 DefaultListableBeanFactory 的 beanFactory,并且会生成 XmlBeanDefinitionReader ,从xml文件中读出beanDefinition并放置到 beanFactory中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
. . .
// DefaultListableBeanFactory 会在此方法中根据 BeanDefinition 去加载bean的定义。
finishBeanFactoryInitialization(beanFactory);
finishRefresh();
}
catch (BeansException ex) {
. . .
// Propagate exception to caller.
throw ex;
}
finally {
. . .
}
}
}
可以看到 ,是在 finishBeanFactoryInitialization(beanFactory) 方法中将beanDefinition生成bean的。
下面我们看一下 DefultListableBeanFactory来获取bean的方法:
@Override
public void preInstantiateSingletons() throws BeansException {
// 得到所有的bean定义的name列表
List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);
// 遍历bean定义name的列表,得到对应的bean定义
for (String beanName : beanNames) {
this.logger.debug("beanName 为" + beanName);
// 得到bean的定义
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
// 如果是工厂类的bean
if (isFactoryBean(beanName)) {
final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
@Override
public Boolean run() {
return ((SmartFactoryBean<?>) factory).isEagerInit();
}
}, getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
// 如果不是工厂类的bean,即为普通bean,则直接调用 getBean() 方法
else {
getBean(beanName);
}
}
}
}
可以看到,DefultListableBeanFactory会遍历bean的beanName,然后调用getBean(beanName)方法来获取到bean。getBean(beanName)即调用的 doGetBean() 方法来获取到bean。
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;
// doGetBean() ,这个方法主要做了两件事情:
// 1、判断是否已存在指定beanName的bean,如果有,直接返回
// 2、如果没有,得到其beanDefinition,然后生成bean,放到map中,再返回。
// 从map中得到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);
}
// 发现如果没有bean,那么就得到相应的beanDefinition,然后生成bean
else {
// Fail if we're already creating this bean instance:
// We're assumably within a circular reference.
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
. . .
// 下面为获取单例bean的方法
try {
// 根据beanName来获取到bean的beanDefinition
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
. . .
// 下面为创建bean的方法
if (mbd.isSingleton()) {
// 这里是实现了 ObjectFactory 这个接口,里面得到创建的 bean
// getSingleton方法会做一些处理在同步块中判断是否有无bean,如果没有,再调用回调获取到bean,并将bean放到 singletonObjects 中,也就是最后的 beanName - > bean对象 的Map
sharedInstance = getSingleton(beanName, new ObjectFactory<Object>() {
@Override
public Object getObject() throws BeansException {
try {
logger.debug(" createBean,初始化bean所要调用的方法 ");
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);
}
. . .
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
. . .
return (T) bean;
}
createBean(String beanName, RootBeanDefinition mbd, Object[] args)方法,其调用的是 doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) 方法,我们看一下其实现:
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final Object[] args) {
// 此为真正去获取一个bean的方法,也是可以大致分为两步:
// 1、找到其构造函数与构造函数中要传入的value,比如constructor.newInstance()。这样就然后生成bean的对象。相当于 User user = new User(xx,xx)
// 2、对bean对象中的value进行填充 user.setName(xxx),本质上调用的是method.invoke()方法
// Instantiate the bean.
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
// 此为创建bean,但是仅仅是创建bean,里面的value不填充。因为要创建,所以 如果construction中有依赖,那么肯定要先加载 construction 中的依赖,
// 如果依赖是bean,那么就加载要依赖的bean
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
// 此为得到创建好的bean
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<Object>() {
@Override
public Object getObject() throws BeansException {
return getEarlyBeanReference(beanName, mbd, bean);
}
});
}
try {
// bean创建完成后,调用下面的方法根据beanDefinition中定义的value对bean进行填充
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);
}
}
. . .
// Register bean as disposable.
try {
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
好,我们首先看一下 createBeanInstance() ,即创建bean的方法:
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, Object[] args) {
. . .
// 此为判断bean的构造方法中是否需要value的注入,如果有,那么走 autowireConstructor 方法,先找到value
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
if (ctors != null ||
mbd.getResolvedAutowireMode() == RootBeanDefinition.AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
}
// 如果没有,直接走 instantiateBean ,直接生成一个bean
return instantiateBean(beanName, mbd);
}
那么比如是
<bean id="dependC" class="com.happyheng.bean.DependC">
<constructor-arg ref="dependA"/>
</bean>
那么肯定需要走 autowireConstructor() ,因为构造方法里面有value需要创建。在 autowireConstructor() 中,首先去获取里面的value值
private int resolveConstructorArguments(String beanName, RootBeanDefinition mbd, BeanWrapper bw,
ConstructorArgumentValues cargs, ConstructorArgumentValues resolvedValues) {
. . .
for (ConstructorArgumentValues.ValueHolder valueHolder : cargs.getGenericArgumentValues()) {
// 遍历 Constructor 参数
if (valueHolder.isConverted()) {
resolvedValues.addGenericArgumentValue(valueHolder);
}
else {
// 得到 Constructor 参数里面的value
Object resolvedValue =
valueResolver.resolveValueIfNecessary("constructor argument", valueHolder.getValue());
// 得到value之后,替换ConstructorArgumentValues.ValueHolder中的value
ConstructorArgumentValues.ValueHolder resolvedValueHolder =
new ConstructorArgumentValues.ValueHolder(resolvedValue, valueHolder.getType(), valueHolder.getName());
resolvedValueHolder.setSource(valueHolder);
resolvedValues.addGenericArgumentValue(resolvedValueHolder);
}
}
return minNrOfArgs;
}
在获取value值的时候,有这样的方法:
public Object resolveValueIfNecessary(Object argName, Object value) {
// 如果value是 RuntimeBeanReference ,那么需要先获取到这个bean,即如果有,就直接拿到返回,如果没有,就创建
if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
return resolveReference(argName, ref);
}
. . .
}
所以如果 dependC 的构造函数中有 dependA 的话,那么需要先生成dependA这个bean,最后再生成 dependC 这个bean 。
dependC在获取到了所有构造函数的值后(即dependA已经生成),会在autowireConstructor() 方法的最后 调用 instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner, final Constructor<?> ctor, Object... args) 方法来传入Constructor与对应的args利用反射来生成bean。
至于前面所说的构造函数中没有参数的bean,比如:
<bean id="myBean" class="com.happyheng.bean.MyBean"/>
则直接调用 instantiateBean(beanName, mbd) 方法,其调用了方法:
@Override
public Object instantiate(RootBeanDefinition bd, String beanName, BeanFactory owner) {
/**
* @todo
*/
// 使用了java的反射,先得到bean的Class的 constructor 的方法,然后直接使用 constructor 方法来生成一个bean
if (bd.getMethodOverrides().isEmpty()) {
Constructor<?> constructorToUse;
synchronized (bd.constructorArgumentLock) {
constructorToUse = (Constructor<?>) bd.resolvedConstructorOrFactoryMethod;
if (constructorToUse == null) {
// 得到bean的Class对象
final Class<?> clazz = bd.getBeanClass();
if (clazz.isInterface()) {
throw new BeanInstantiationException(clazz, "Specified class is an interface");
}
try {
if (System.getSecurityManager() != null) {
constructorToUse = AccessController.doPrivileged(new PrivilegedExceptionAction<Constructor<?>>() {
@Override
public Constructor<?> run() throws Exception {
return clazz.getDeclaredConstructor((Class[]) null);
}
});
}
else {
// 得到这个bean的 Constructor 方法
constructorToUse = clazz.getDeclaredConstructor((Class[]) null);
}
bd.resolvedConstructorOrFactoryMethod = constructorToUse;
}
catch (Exception ex) {
throw new BeanInstantiationException(clazz, "No default constructor found", ex);
}
}
}
// 将 Constructor 方法传入到 BeanUtils 来直接生成一个对象即可
return BeanUtils.instantiateClass(constructorToUse);
}
else {
// Must generate CGLIB subclass.
return instantiateWithMethodInjection(bd, beanName, owner);
}
}