https://zhuanlan.zhihu.com/p/66719191
1 AbstractBeanFactory.getBean 主流程
@Overridepublic Object getBean(String name) throws BeansException {return doGetBean(name, null, null, false);}
第二个参数表示bean的Class类型,第三个表示创建bean需要的参数,最后一个表示不需要进行类型检查。
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {//1 提取beanName//去除&符号,因为当配置文件中<bean>的class属性配置的实现类是FactoryBean时//通过getBean()方法返回的不是FactoryBean本身,//而是FactoryBean#getObject()方法所返回的对象//相当于FactoryBean#getObject()代理了getBean()方法//如果希望获取FactoryBean的实例,需要在beanName前加上“&”符号,即getBean("&beanName")//在这里要获取的是bean的实例,所以要去掉&符号final String beanName = transformedBeanName(name);Object bean;// Eagerly check singleton cache for manually registered singletons.//2 率先直接从单例缓存或objectFactory中提取bean,容器内部初始化和非初始化(手动调用)过程也都被调用//如果是原型bean,直接获得不到,进入创建bean的else流程Object sharedInstance = getSingleton(beanName);// 3 getbean 主流程// 3.1 如果存在该单例bean且属性为空,直接返回if (sharedInstance != null && args == null) {if (logger.isTraceEnabled()) {// 3.1.1循环依赖if (isSingletonCurrentlyInCreation(beanName)) {logger.trace("Returning eagerly cached instance of singleton bean '" + beanName +"' that is not fully initialized yet - a consequence of a circular reference");}// 3.1.2不存在循环依赖else {logger.trace("Returning cached instance of singleton bean '" + beanName + "'");}}// 3.1.3 getObjectForBeanInstance//如果从缓存中得到了bean的原始状态,则需要对bean进行实例化。//缓存中记录的只是最原始的bean状态,并不一定是我们最终想要的bean。//假如我们需要对工厂bean进行处理,那么这里得到的其实是工厂bean的初始状态//但是我们正真需要的是工程bean中定义的factory-method方法中返回的bean//而getObjectForBeanInstance就是完成这个工作的bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);}// 3.2 非单例,或者单例第一次创建,或单例已存在参数不为空else {// Fail if we're already creating this bean instance:// We're assumably within a circular reference.// 3.2.1 检查循环依赖是否合法//只有单例才会解决bean的循环依赖问题//原型bean 依赖的存在bean正在创建 非法if (isPrototypeCurrentlyInCreation(beanName)) {throw new BeanCurrentlyInCreationException(beanName);}// Check if bean definition exists in this factory.// 3.2.2 beanName不在本容器内,检查父容器,委托给父工厂中寻找,甚至创建BeanFactory parentBeanFactory = getParentBeanFactory();//如果当前bean不在当前beanfactory的beanDefinitionMap,委托给父工厂中寻找,甚至创建if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {// Not found -> check parent.String nameToLookup = originalBeanName(name);if (parentBeanFactory instanceof AbstractBeanFactory) {return ((AbstractBeanFactory) parentBeanFactory).doGetBean(nameToLookup, requiredType, args, typeCheckOnly);}else if (args != null) {// Delegation to parent with explicit args.return (T) parentBeanFactory.getBean(nameToLookup, args);}else if (requiredType != null) {// No args -> delegate to standard getBean method.return parentBeanFactory.getBean(nameToLookup, requiredType);}else {return (T) parentBeanFactory.getBean(nameToLookup);}}//3.2.3标记已经该bean创建了// 清除合并父beanDefiniton的标志,把创建的beanName加入if (!typeCheckOnly) {markBeanAsCreated(beanName);}// 3.2.4 合并父beanDefiniton和递归get依赖的beantry {//读取bean的标签对应的BeanDefinition,子bean的话合并父属性final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);checkMergedBeanDefinition(mbd, beanName, args);// Guarantee initialization of beans that the current bean depends on.String[] dependsOn = mbd.getDependsOn();if (dependsOn != null) {for (String dep : dependsOn) {if (isDependent(beanName, dep)) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");}//注册依赖和递归获得bean的顺序与3.0版本相反//注册依赖关系registerDependentBean(dep, beanName);try {//递归调用 get依赖的beangetBean(dep);}catch (NoSuchBeanDefinitionException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"'" + beanName + "' depends on missing bean '" + dep + "'", ex);}}}// Create bean instance.// 3.2.5 创建bean//3.2.5 .1 单例beanif (mbd.isSingleton()) {sharedInstance = getSingleton(beanName, () -> {try {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);}//3.2.5 .2 原型beanelse if (mbd.isPrototype()) {// It's a prototype -> create a new instance.Object prototypeInstance = null;try {beforePrototypeCreation(beanName);prototypeInstance = createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);}//3.2.5 .3 其他scope的beanelse {String scopeName = mbd.getScope();final Scope scope = this.scopes.get(scopeName);if (scope == null) {throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");}try {Object scopedInstance = scope.get(beanName, () -> {beforePrototypeCreation(beanName);try {return createBean(beanName, mbd, args);}finally {afterPrototypeCreation(beanName);}});bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);}catch (IllegalStateException ex) {throw new BeanCreationException(beanName,"Scope '" + scopeName + "' is not active for the current thread; consider " +"defining a scoped proxy for this bean if you intend to refer to it from a singleton",ex);}}}catch (BeansException ex) {cleanupAfterBeanCreationFailure(beanName);throw ex;}}// Check if required type matches the type of the actual bean instance.//4 转换bean为需要的类型,不满足抛出异常if (requiredType != null && !requiredType.isInstance(bean)) {try {T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);if (convertedBean == null) {throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}return convertedBean;}catch (TypeMismatchException ex) {if (logger.isTraceEnabled()) {logger.trace("Failed to convert bean '" + name + "' to required type '" +ClassUtils.getQualifiedName(requiredType) + "'", ex);}throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());}}return (T) bean;}
2 两个 getSingleton方法
2.1 从一级缓存获得bean(解决循环依赖第一步)
//先从singletonObjects寻找,如果找不到,再从earlySingletonObjects寻找,//仍然找不到,那就从singletonFactories寻找对应的制造singleton的工厂,//然后调用工厂的getObject方法,造出对应的SingletonBean,并放入earlySingletonObjects中
//单例Bean的缓存,一级缓存 bean name 对应 bean 实例private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);/** Cache of singleton factories: bean name to ObjectFactory. *///ObjectFactory的缓存,bean name 对应 特定ObjectFactory;//ObjectFactory的getObject方法返回bean的实例 ObjectFactory通过getObject方法获取到了earlySingletonBean//然后在由earlySingletonBean成为bean的实例// 有人叫二级缓存private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);/** Cache of early singleton objects: bean name to bean instance. *///早期bean实例的缓存,beanName对应 early bean instance//是singletonFactory 制造出来的 singleton的缓存 有人叫三级缓存private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);@Nullableprotected Object getSingleton(String beanName, boolean allowEarlyReference) {Object singletonObject = this.singletonObjects.get(beanName);if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {synchronized (this.singletonObjects) {singletonObject = this.earlySingletonObjects.get(beanName);if (singletonObject == null && allowEarlyReference) {ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);if (singletonFactory != null) {singletonObject = singletonFactory.getObject();this.earlySingletonObjects.put(beanName, singletonObject);this.singletonFactories.remove(beanName);}}}}return singletonObject;}
2.2 create新的bean与几个缓存交互
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {Assert.notNull(beanName, "Bean name must not be null");synchronized (this.singletonObjects) {Object singletonObject = this.singletonObjects.get(beanName);//1 从缓存拿,拿不到创建if (singletonObject == null) {if (this.singletonsCurrentlyInDestruction) {throw new BeanCreationNotAllowedException(beanName,"Singleton bean creation not allowed while 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 + "'");}//2 创建bean前置检查,如已经存在正在创建的bean且inCreationCheckExclusions(web容器中)中不存在该bean,则抛出异常beforeSingletonCreation(beanName);boolean newSingleton = false;boolean recordSuppressedExceptions = (this.suppressedExceptions == null);if (recordSuppressedExceptions) {this.suppressedExceptions = new LinkedHashSet<>();}//3 利用ObjectFactory创建新的单例beantry {singletonObject = singletonFactory.getObject();newSingleton = true;}catch (IllegalStateException ex) {// Has the singleton object implicitly appeared in the meantime ->// if yes, proceed with it since the exception indicates that state.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;}//4 创建bean前置检查,如移除正在创建的bean失败且inCreationCheckExclusions(web容器中)中不存在该bean,则抛出异常afterSingletonCreation(beanName);}//5 成功的创建了新的bean则加入缓存if (newSingleton) {addSingleton(beanName, singletonObject);}}return singletonObject;}}
3 createBean
源码位于AbstractAutowireCapableBeanFactory.createBean
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)throws BeanCreationException {if (logger.isTraceEnabled()) {logger.trace("Creating instance of bean '" + beanName + "'");}RootBeanDefinition mbdToUse = mbd;// Make sure bean class is actually resolved at this point, and// clone the bean definition in case of a dynamically resolved Class// which cannot be stored in the shared merged bean definition.//1 获得bean的class对象,根据beanName或beandefiniton属性解析class// 克隆那些因动态解析类的情况下,不能存储在共享合并bean定义的beandefinition,动态支持Class<?> resolvedClass = resolveBeanClass(mbd, beanName);if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {mbdToUse = new RootBeanDefinition(mbd);mbdToUse.setBeanClass(resolvedClass);}// Prepare method overrides.//2 lookup-overrides 和 replace-overrides处理 检查方法覆盖是否合法try {mbdToUse.prepareMethodOverrides();}catch (BeanDefinitionValidationException ex) {throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),beanName, "Validation of method overrides failed", ex);}try {// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.//3 给 InstantiationAwareBeanPostProcessor一个机会 返回代理单例对象代替当前对象Object bean = resolveBeforeInstantiation(beanName, mbdToUse);//为特殊的bean提够短路功能,如aopif (bean != null) {return bean;}}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,"BeanPostProcessor before instantiation of bean failed", ex);}try {// 4 具体创建beanObject beanInstance = doCreateBean(beanName, mbdToUse, args);if (logger.isTraceEnabled()) {logger.trace("Finished creating instance of bean '" + beanName + "'");}return beanInstance;}catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {// A previously detected exception with proper bean creation context already,// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.throw ex;}catch (Throwable ex) {throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);}}
3.1 InstantiationAwareBeanPostProcessor
给 InstantiationAwareBeanPostProcessor一个机会 返回代理单例对象代替当前对象
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
//为特殊的bean提够短路功能,如aop
if (bean != null) {
return bean;
}
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {Object bean = null;//未被初始化if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {// Make sure bean class is actually resolved at this point.// Synthetic特殊的bean,临时的bean。spring自己的beanif (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {// 核心逻辑// 1 创建实例的前置处理bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);// 2 创建实例的后置处理if (bean != null) {bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}
3.2 doCreateBean
4 bean对象后置处理器:BeanPostProcessor
Bean后置处理器:负责对已创建好的bean对象进行加工处理。
主要是可以对新创建的bean实例进行修改,提供了一个类似于hook机制,对创建好的bean对象实例进行修改。 另外,不要将BeanPostProcessor标记为延迟初始化。因为如果这样做,Spring容器将不会注册它们,自定义逻辑也就无法得到应用。假如你在元素的定义中使用了’default-lazy-init’属性,请确信你的各个BeanPostProcessor标记为’lazy-init=”false”‘。
public interface BeanPostProcessor {//bean初始化方法调用前被调用 在创建好bean实例,但是在任何初始化回调执行之前,如InitializingBean的afterPropertiesSet,先执行该方法。Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;//bean初始化方法调用后被调用 在创建好bean实例,并且所有的初始化回调都执行完了,如InitializingBean的afterPropertiesSet,再执行该方法Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;}public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {@Nullabledefault Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {return null;}default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {return true;}@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)throws BeansException {return null;}@Deprecated@Nullabledefault PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {return pvs;}}
ApplicationContext会自动检测当前存在的beanPostProcessors,并应用在创建的bean实例上。
注解处理相关的BeanPostProcessor
通常用于在创建好bean对象实例后,处理这个bean上面的注解。同时也可以对bean对象进行其他功能拓展。
BeanPostProcessor的注册
定义:在注解配置工具类AnnotationConfigUtils的静态方法registerAnnotationConfigProcessors方法中,定义注解的处理器的注册逻辑。
调用:在BeanFactoryPostProcessor中调用这个静态方法来完成将特定的BeanPostProcessor实现类,注册到ApplicationContext的BeanPostProcessor列表:
1 AutowiredAnnotationBeanPostProcessor:处理bean对象的依赖注入关系,即从BeanFactory获取该bean所依赖的bean,然后注入到该bean对应的成员变量中。
2 CommonAnnotationBeanPostProcessor:该bean中所使用了的JDK定义的注解的处理,如方法中的@PostConstruct,@PreDestroy,成员变量上的@Resource等。
3 PersistenceAnnotationBeanPostProcessor(JPA时添加):JPA相关bean的持久化处理。
