标签: spring源码学习
spring获取单例首先是从缓存去找,如果找不到就要从头开始bean的加载过程,spring中主要通过getSingleton的重载方法实现单例bean的加载过程
要创建一个bean的单例,首先了解下单例是什么样子的,
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
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的回调方法
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
@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方法
public void prepareMethodOverrides() throws BeanDefinitionValidationException {
// Check that lookup methods exists.
MethodOverrides methodOverrides = getMethodOverrides();
if (!methodOverrides.isEmpty()) {
for (MethodOverride mo : methodOverrides.getOverrides()) {
prepareMethodOverride(mo);
}
}
}
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说起。