本帖最后由 大蓝鲸小蟀锅 于 2020-2-26 09:40 编辑
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);
}
// 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, 帮我们注入了一个后置处理器.
AnnotationAwareAspectJAutoProxyCreator. 此类是 InstantiationAwareBeanPostProcessor的子类, 从写了 postProcessBeforeInstantiation()方法
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
Object cacheKey = getCacheKey(beanClass, beanName);
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;
}
}
// 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;
}
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);
}
3. 第三次调用beanPostProcess, 此方法用来缓存bean中的注解信息. 此时对象已经创建出来, 但是spring还没有创建成功, 因为各种属性还未添加.
MergedBeanDefinitionPostProcessor 的 postProcessMergedBeanDefinition()方法.
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;
}
}
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));
}
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创建对象的流程. 欢迎讨论
|
|