Spring源碼
參考資料
https://www.bilibili.com/video/BV1Tz4y1a7FM
https://www.bilibili.com/video/BV1iz4y1b75q
bean工廠
DefaultListableBeanFactory(最原始)
bean的生命周期
創建(實例化)–>依賴注入–>-初始化–>銷毀
bean–>推斷構造方法(默認是無參構造,或指定的構造方法)–>實例化成普通對象(相當于new bean)
–>進行依賴注入(bean里的屬性)–>執行afterPropertiesSet()(InitializingBean的一個回調方法,同@PostConstruct)
–>初始化后是否需要AOP–>AOP–>代理對象(target=普通對象)–>把對象放入Map<beanname,bean對象>單例池
//真正創建Bean的方法protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)throws BeanCreationException {// Instantiate the bean.//封裝被創建的Bean對象BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);}if (instanceWrapper == null) {instanceWrapper = createBeanInstance(beanName, mbd, args);}final Object bean = instanceWrapper.getWrappedInstance();//獲取實例化對象的類型Class<?> beanType = instanceWrapper.getWrappedClass();if (beanType != NullBean.class) {mbd.resolvedTargetType = beanType;}// Allow post-processors to modify the merged bean definition.//調用PostProcessor后置處理器synchronized (mbd.postProcessingLock) {if (!mbd.postProcessed) {try {applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);}catch (Throwable ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName,"Post-processing of merged bean definition failed", ex);}mbd.postProcessed = true;}}// Eagerly cache singletons to be able to resolve circular references// even when triggered by lifecycle interfaces like BeanFactoryAware.//向容器中緩存單例模式的Bean對象,以防循環引用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, () -> getEarlyBeanReference(beanName, mbd, bean));}// Initialize the bean instance.//Bean對象的初始化,依賴注入在此觸發//這個exposedObject在初始化完成之后返回作為依賴注入完成后的BeanObject exposedObject = bean;try {//將Bean實例對象封裝,并且Bean定義中配置的屬性值賦值給實例對象populateBean(beanName, mbd, instanceWrapper);//初始化Bean對象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);}}if (earlySingletonExposure) {//獲取指定名稱的已注冊的單例模式Bean對象Object earlySingletonReference = getSingleton(beanName, false);if (earlySingletonReference != null) {//根據名稱獲取的已注冊的Bean和正在實例化的Bean是同一個if (exposedObject == bean) {//當前實例化的Bean初始化完成exposedObject = earlySingletonReference;}//當前Bean依賴其他Bean,并且當發生循環引用時不允許新創建實例對象else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {String[] dependentBeans = getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);//獲取當前Bean所依賴的其他Beanfor (String dependentBean : dependentBeans) {//對依賴Bean進行類型檢查if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName,"Bean with name '" + beanName + "' has been injected into other beans [" +StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +"] in its raw version as part of a circular reference, but has eventually been " +"wrapped. This means that said other beans do not use the final version of the " +"bean. This is often the result of over-eager type matching - consider using " +"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");}}}}// Register bean as disposable.//注冊完成依賴注入的Beantry {registerDisposableBeanIfNecessary(beanName, bean, mbd);}catch (BeanDefinitionValidationException ex) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);}return exposedObject;}
//初始容器創建的Bean實例對象,為其添加BeanPostProcessor后置處理器protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {//JDK的安全機制驗證權限if (System.getSecurityManager() != null) {//實現PrivilegedAction接口的匿名內部類AccessController.doPrivileged((PrivilegedAction<Object>) () -> {invokeAwareMethods(beanName, bean);return null;}, getAccessControlContext());}else {//為Bean實例對象包裝相關屬性,如名稱,類加載器,所屬容器等信息invokeAwareMethods(beanName, bean);}Object wrappedBean = bean;//對BeanPostProcessor后置處理器的postProcessBeforeInitialization//回調方法的調用,為Bean實例初始化前做一些處理if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);}//調用Bean實例對象初始化的方法,這個初始化方法是在Spring Bean定義配置//文件中通過init-method屬性指定的try {invokeInitMethods(beanName, wrappedBean, mbd);}catch (Throwable ex) {throw new BeanCreationException((mbd != null ? mbd.getResourceDescription() : null),beanName, "Invocation of init method failed", ex);}//對BeanPostProcessor后置處理器的postProcessAfterInitialization//回調方法的調用,為Bean實例初始化之后做一些處理if (mbd == null || !mbd.isSynthetic()) {wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);}return wrappedBean;}
三級緩存解決循環依賴
循環依賴
在A創建的過程中,A的屬性B需要注入屬性A
- singletonObjects(一級緩存)
- earlysingletonObjects(二級緩存)
- singletonFactories(三級緩存)
- private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap(16);
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap(16);
- 創建的A放入 Set singletonsCurrentlyInCreation(只要創建就放入set,表示bean正在初始化)
- 首先是實例化,new 普通對象,addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));為了防止循環引用,盡早持有對象的引用,第二個參數是一個lamda表達式可用來獲取普通對象
- 在A填充B時,B需要注入A,判斷A正在初始化,此時出現循環依賴
- 先向二級緩存里查找,在多方循環中保證創建的是都是同一個代理對象A
- 再向三級緩存里查找,沒有則執行lamda獲取普通對象,并且進行AOP,生成代理對象
- 放入bean到二級緩存中
- 填充其他的屬性
- 進行Aop的邏輯,若是循環依賴則會提前進行Aop(step5)而不是現在
- 在二級緩存里查找,是不是已經有已經生成好的bean
- 添加到單例池
- Set中removeA,標識初始化完成
beanFactory
四個Applicationcontext
FileSystemXmlApplicationContext
ClassPathXmlApplicationContext
AnnotationConfigApplicationContext
AnnotationConfigWebApplicationContext
GenericApplicationContext(是一個干凈的容器)
后置處理器(PostProcessor)
CommonAnnotationBeanPostProcessor
Ordered.LOWEST_PRECEDENCE - 3
@Resource @PostConstruct @PreDestroy
解析WebService關于JAX-WS的相關注解,EJB相關的注解
AutowiredAnnotationBeanPostProcessor
Ordered.LOWEST_PRECEDENCE - 2
處理@Autowire注解,@Value注解,處理javax.inject.Inject JSR-330注解
//處理類中的屬性@Overridepublic PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {//獲取指定類中autowire相關注解的元信息InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);try {//對Bean的屬性進行自動注入metadata.inject(bean, beanName, pvs);}catch (BeanCreationException ex) {throw ex;}catch (Throwable ex) {throw new BeanCreationException(beanName, "Injection of autowired dependencies failed", ex);}return pvs;}
BeanPostProcessor
處理器定義了Bean 初始化 前后執行的方法。
public interface BeanPostProcessor {//自定義初始化方法之前執行@Nullabledefault Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {return bean;}//自定義初始化方法之后執行@Nullabledefault Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {return bean;}}
InstantiationAwareBeanPostProcessor
該處理器定義了Bean 實例化 前后執行的方法。
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;}//處理bean的Properties值@Nullabledefault PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)throws BeansException {return null;}}
DestructionAwareBeanPostProcessor
該處理器了銷毀Bean之前的操作。
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {//bean銷毀之前void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;//bean是否需要銷毀default boolean requiresDestruction(Object bean) {return true;}}