spring-bean建立的生命週期與後置處理器的調用點
1.第一次調用BeanPostProcess , InstantiationAwareBeanPostProcessor中的postProcessBeforeInstantiation()方法.
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
// 第一次調用BeanPostProcess InstantiationAwareBeanPostProcessor這個處理器的postProcessBeforeInstantiation()方法.
// 若是一個對象,不想經過spring進行維護, 只是想放入spring容器當中, 就實現此接口, 反回一個你須要的對象出來
// 這邊返回的對象不爲null時, 這個beanName的的建立也聚完成了, spring的後置處理器不會對此對象進行操做.
// spring不推薦使用, 是spring提供內部添加對象時調用的.
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);
} spring
// Make sure bean class is actually resolved at this point.
// 判斷是否有InstantiationAwareBeanPostProcessors的後置處理器.
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
// 若是調用postProcessBeforeInstantiation返回了一個對象, 那麼就直接執行後置處理器,此對象的實例化就完成.
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
} 緩存
通常來講 , 實現此接口返回的對象, 都是不須要通過spring幫咱們建立對象了 , 不須要spring進行管理了. spring不推薦咱們使用, 而是交由spring內部本身調用的.
在spring-AOP有應用場景.
在咱們開啓AOP時. 添加 @EnableAspectJAutoProxy 註解. 基於spring的Import擴展 經過 ImportBeanDefinitionRegister, 幫咱們注入了一個後置處理器. mybatis
AnnotationAwareAspectJAutoProxyCreator. 此類是 InstantiationAwareBeanPostProcessor的子類, 從寫了 postProcessBeforeInstantiation()方法
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName); app
if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
if (this.advisedBeans.containsKey(cacheKey)) {
return null;
}
// 再次判斷beanClass中是否包含切面的註解 , 若是包含,保存到advisedBeans集合中,表明其實一個切面, 這樣在bean實例化以後,
// 執行beanPostProcess的postProcessAfterInitialization方法時, 不會對切面進行加強.
if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return null;
}
} ide
// Create proxy here if we have a custom TargetSource.
// Suppresses unnecessary default instantiation of the target bean:
// The TargetSource will handle target instances in a custom fashion.
TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
if (targetSource != null) {
if (StringUtils.hasLength(beanName)) {
this.targetSourcedBeans.add(beanName);
}
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
} post
return null;
}
** 2. 第二次調用beanPostProcess, 來決定使用什麼構造方法來建立對象. SmartInstantiationAwareBeanPostProcessor的determineCandidateConstructors()方法.
**// 第二次調用beanPostProcess , 用來決定是什麼哪一個構造方法建立對象. SmartInstantiationAwareBeanPostProcessor 的determineCandidateConstructors()方法.
// 由後置處理器來肯定返回那些夠着方法, 若是拿到就使用這個構造方法實例化. spring爲何要這樣作呢?
// 咱們能夠經過反射直接拿到構造方法呀.
// beanPostProcess認爲若是你沒有沒有構造方法,或者你構造方法是默認的空參構造, 那麼此時返回的constructor= null.
// spring就認爲你不存在特殊的構造方法, 因此直接跳過調用空參構造建立對象, 若是有特殊的構造方法,那麼constructor != null,
// 就會使用你這個有參構造方法來建立對象.
// 可是若是有兩個構造方法時 , 而且你沒有指定primary的構造方法時, 也會返回null , 由於spring不知道你要使用哪一個構造方法,因此仍是讓你走空參構造建立對象.
// 簡單來講 , 若是有有且只有一個有參構造方法, 那麼就返回這個有參構造方法, 若是有多個構造方法 , 就使用空參構造建立.
// 可是若是在解析beanDefinotion給他添加了構造方法, 那麼就會使用到咱們添加的構造方法.
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 如何使用有參構造方法來建立對象呢?
// 有四個判斷條件.
// 1. 經過上方,後置處理器,找到了惟一的有參構造
// 2. BeanDefinition設置爲自動建立的模式 AUTOWIRE_CONSTRUCTOR
// 3. BeanDefinition咱們設置了ConstructorArgumentValues, 還記得mybatis嗎? 咱們掃描完BeanDefinition後,給BeanDefinition設置使用什麼構造參數和使用哪一個beanClass.
// 4. 調用singletonObject是,傳入的args就不爲空, 是有值的, 明確告訴你, 我須要構造方法建立.
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
return autowireConstructor(beanName, mbd, ctors, args);
} ui
** 3. 第三次調用beanPostProcess, 此方法用來緩存bean中的註解信息. 此時對象已經建立出來, 可是spring尚未建立成功, 由於各類屬性還未添加.
** MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition()方法. this
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//第三次調用 beanPostProcess , MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition()方法
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
} lua
4. 第四次調用beanPostProcess, 用來提早暴露對象.spring認爲此時, 對象僅僅是new了出來, 可是沒有建立完成 , 對象走完spring的生命週期, 放入singletonObjects中, spring纔算對象建立完成. 此時會把bean保存到singleonFactories中. 至關於一箇中間集合, 若是對象在建立中, 由於引用其餘對象時 , getSingleton()方法 會先到singletonFactories中獲取, 若是獲取不到 , 再經過 creatBean()建立對象 , 用來解決spring的循環引用問題 .
SmartInstantiationAwareBeanPostProcessor 的 getEarlyBeanReference() 方法.
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
// 會把正在建立的bean保存到singletonFactories中
// 第四次調用beanPostProcess , SmartInstantiationAwareBeanPostProcessor的getEarlyBeanReference()方法, 用來解決循環依賴的
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
} debug
**5.第五次調用beanPostProcess, 用來判斷你的bean需不須要完成屬性填充 , 若是實現此接口 , 返回false , 那麼spring不會幫咱們填充屬性.
** InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法.
// 第五次執行beanPostProcess , InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation()方法
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
** 6. 第六次調用beanPostProcess,
** AutowireAnnotationBeanPostProcessor 中的 postProcessProperrtyValues()方法. 主要使用來幫咱們完成屬性注入的 .
CommonAnnotationBeanPostProcessor 中的 postProcessProperrtyValues()方法. 主要是用來處理@Resource的.**
// 判斷autowireMode是什麼類型, 默認實際上是 AUTOWIRE_BY_NO.
// 經過byName 或者 byType 拿到對應的屬性, 其中spring會進行過濾 , 賦值給pvs ,讓後置處理器去處理.
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
// Add property values based on autowire by name if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
// Add property values based on autowire by type if applicable.
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
protected String[] unsatisfiedNonSimpleProperties(AbstractBeanDefinition mbd, BeanWrapper bw) {
Set<String> result = new TreeSet<>();
// 拿到咱們手動設置的屬性. 咱們拿到beanDefinition後能夠手動設置屬性.
PropertyValues pvs = mbd.getPropertyValues();
// 拿到class 的全部屬性.
PropertyDescriptor[] pds = bw.getPropertyDescriptors();
for (PropertyDescriptor pd : pds) {
// 對全部的屬性進行過濾. 那些屬性是咱們想要的.
// 1. 須要set方法.
// 2. spring過濾接口, 不存在.
// 3. pvs中不包含的pd , 咱們手動添加給beanDefinition也須要過濾掉, 由於set方法確定是class本身的,而不是咱們手動添加的.
// 4. 簡單類型的也忽略掉.
if (pd.getWriteMethod() != null && !isExcludedFromDependencyCheck(pd) && !pvs.contains(pd.getName()) &&
!BeanUtils.isSimpleProperty(pd.getPropertyType())) {
result.add(pd.getName());
}
}
return StringUtils.toStringArray(result);
}
if (hasInstAwareBpps) {
//在這一步處理使用後置處理器來處理對象, 例如require , autowire 註解
// 第六次調用beanPostProcess , InstantiationAwareBeanPostProcessor的postProcessPropertyValues()方法.
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
@Override
public PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeanCreationException {
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 經過inject注入屬性.
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;
}
@Override
protected void inject(Object bean, @Nullable String beanName, @Nullable PropertyValues pvs) throws Throwable {
Field field = (Field) this.member;
Object value;
if (this.cached) {
value = resolvedCachedArgument(beanName, this.cachedFieldValue);
}
else {
DependencyDescriptor desc = new DependencyDescriptor(field, this.required);
desc.setContainingClass(bean.getClass());
Set<String> autowiredBeanNames = new LinkedHashSet<>(1);
Assert.state(beanFactory != null, "No BeanFactory available");
TypeConverter typeConverter = beanFactory.getTypeConverter();
try {
// 關鍵代碼 , 從spring的beanFactory中獲取對象
value = beanFactory.resolveDependency(desc, beanName, autowiredBeanNames, typeConverter);
}
catch (BeansException ex) {
throw new UnsatisfiedDependencyException(null, beanName, new InjectionPoint(field), ex);
}
synchronized (this) {
if (!this.cached) {
if (value != null || this.required) {
this.cachedFieldValue = desc;
registerDependentBeans(beanName, autowiredBeanNames);
if (autowiredBeanNames.size() == 1) {
String autowiredBeanName = autowiredBeanNames.iterator().next();
if (beanFactory.containsBean(autowiredBeanName) &&
beanFactory.isTypeMatch(autowiredBeanName, field.getType())) {
this.cachedFieldValue = new ShortcutDependencyDescriptor(
desc, autowiredBeanName, field.getType());
}
}
}
else {
this.cachedFieldValue = null;
}
this.cached = true;
}
}
}
if (value != null) {
ReflectionUtils.makeAccessible(field);
field.set(bean, value);
}
}
}
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
// 調用到geiBean() , 而後經過getSingleton()獲取.
return beanFactory.getBean(beanName);
}
** 7. 第七次調用beanPostProcess, 此時對象已經建立成功, 而且屬性填充完畢. 基本上一個bean對象已經建立完成.
**
if (mbd == null || !mbd.isSynthetic()) {
// BeanPostProcess有兩個方法 ,這裏先執行 postProcessBeforeInitialization 方法.
// 第七次執行BeanPostProcess , 真正執行的BeanPostProcess的postProcessBeforeInitialization()方法.
// 以前執行的都是實現類中本身定義的擴展功能的方法.
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) {
//若是你的bean是ImportAware
if (bean instanceof ImportAware) {
ImportRegistry ir = this.beanFactory.getBean(IMPORT_REGISTRY_BEAN_NAME, ImportRegistry.class);
AnnotationMetadata importingClass = ir.getImportingClassFor(bean.getClass().getSuperclass().getName());
if (importingClass != null) {
((ImportAware) bean).setImportMetadata(importingClass);
}
}
return bean;
}
** 8. 第八次調用beanPostProcess, 建立對象的最後一步, aop的代理就是在此處建立.
**if (mbd == null || !mbd.isSynthetic()) {
// 處理BeanPostProcess的另外一個方法 . postProcessAfterInitialization , aop就在此時作的.
// 第八次執行beanPostProcess, 真正執行的beanPostProcess的postProcessAfterInitialization()方法.
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
@Nullable Object[] specificInterceptors, TargetSource targetSource) {
if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
}
// spring寫的代理工廠 , 工廠模式的使用
ProxyFactory proxyFactory = new ProxyFactory();
// 這隻proxyFactory工廠的屬性, 從這個類中, 由於此類繼承 ProxyConfig
proxyFactory.copyFrom(this);
// 判斷使用那種方式進行代理 , cglib 仍是 jdk
// 由於在new ProxyFactory工廠時, 父類會建立 AopProxyFactory工廠,
// 此類的createAopProxy(),中調用proxyTargetClass屬性, 若是是true,就使用cglib , spring默認是false.
if (!proxyFactory.isProxyTargetClass()) {
if (shouldProxyTargetClass(beanClass, beanName)) {
proxyFactory.setProxyTargetClass(true);
}
else {
evaluateProxyInterfaces(beanClass, proxyFactory);
}
}
// 拿到咱們切面中的全部方法.
Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
proxyFactory.addAdvisors(advisors);
proxyFactory.setTargetSource(targetSource);
customizeProxyFactory(proxyFactory);
proxyFactory.setFrozen(this.freezeProxy);
if (advisorsPreFiltered()) {
proxyFactory.setPreFiltered(true);
}
return proxyFactory.getProxy(getProxyClassLoader());
}
以上就是spring掃描的咱們對應的類以後 , 經過beanDefinition建立對象的流程. 歡迎討論