Spring bean生命周期(中)

实例化阶段

类加载(Bean的ClassLoading):BeanDefinition中的Class信息从过去的一个文本信息变成一个实在的CLass对象,这个过程称为Bean的class Loading,接下来我们继续讨论这个类信息如何变为我们的一个Bean的实例,也就是我们通常讲的Bean的实例化阶段。实例化阶段分为3个阶段,实例化前阶段,实例化中阶段,实例化后阶段。

Spring Bean实例化前阶段

  • instantiationAwareBeanPostProcessor#postProcessorBeforeInstantiation

Bean实例化前阶段,在实例化之前的操作,这个操作会打破Bean的注册。能够帮助我们提前去生成一些类似与代理对象的东西,来替换掉默认的Spring IOC里面的实现内容。(非主流生命周期,很少有人射猎):

class MyInstantiationAwareBeanPostProocessor implements InstantiationAwareBeanPostProcessor {
    
    @Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throwos BeansException {
        if(ObjectUtils.nullSafeEquals("superUser", beanName) && SuperUser.class.equals(beanClass)) {
            // 覆盖superUser bean的配置
            return new User();
        }
        // 保持 Spring IoC 容器的其他实例化操作
        return null; 
    }
}

Spring Bean实例化阶段

实例化方法:

  • 1.传统实例化方式-实例化策略-InstantiationStrategy
  • 2.构造器依赖注入(按照类型的方式注入)
    /**
	 * Create a new instance for the specified bean, using an appropriate instantiation strategy:
	 * factory method, constructor autowiring, or simple instantiation.
	 */
	protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
		// Make sure bean class is actually resolved at this point.
		Class<?> beanClass = resolveBeanClass(mbd, beanName);

		if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
			throw new BeanCreationException(mbd.getResourceDescription(), beanName,
					"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
		}

		Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
		if (instanceSupplier != null) {
			return obtainFromSupplier(instanceSupplier, beanName);
		}

		if (mbd.getFactoryMethodName() != null) {
			return instantiateUsingFactoryMethod(beanName, mbd, args);
		}

		// Shortcut when re-creating the same bean...
		boolean resolved = false;
		boolean autowireNecessary = false;
		if (args == null) {
			synchronized (mbd.constructorArgumentLock) {
				if (mbd.resolvedConstructorOrFactoryMethod != null) {
					resolved = true;
					autowireNecessary = mbd.constructorArgumentsResolved;
				}
			}
		}
		if (resolved) {
			if (autowireNecessary) {
				return autowireConstructor(beanName, mbd, null, null);
			}
			else {
				return instantiateBean(beanName, mbd);
			}
		}

		// Candidate constructors for autowiring?
		Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
		if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
				mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
			return autowireConstructor(beanName, mbd, ctors, args);
		}

		// Preferred constructors for default construction?
		ctors = mbd.getPreferredConstructors();
		if (ctors != null) {
	        // 构造器注入
			return autowireConstructor(beanName, mbd, ctors, null);
		}

		// No special handling: simply use no-arg constructor.
		// 传统实例化方法
		return instantiateBean(beanName, mbd);
	}

传统实例化方法

// Strategy for creating bean instances.
// 用cglib产生一个动态的子类(字节码自动生成子类)
private InstantiationStrategy instantiationStrategy = new CglibSubclassingInstantiationStrategy();

// Instantiate the given bean using its default constructor.
protected BeanWrapper instantiateBean(final String beanName, final RootBeanDefinition mbd) {
	Object beanInstance;
	final BeanFactory parent = this;
	beanInstance = getInstantiationStrategy().instantiate(mbd, beanName, parent);
	BeanWrapper bw = new BeanWrapperImpl(beanInstance);
	initBeanWrapper(bw);
	return bw;
} 

Spring Bean实例化后阶段

  • Bean属性赋值(Populate)判断:
    • InstantiationAwareBeanPostProcessor#postProcessAfterInstantiation

赋值的前置操作阶段。可以跳过原有bean属性植入,手动的去植入,类似于一种拦截机制。此时Bean的实例化完成了,但是属性的赋值并没有完成。

@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
    // 此时Bean的实例化已经完成了,但是属性的赋值并没有完成
    if(ObjectUtils.nullSafeEquals("user", beanName) && User.class.equals(bean.getClass))) {
        User user = (User) bean;
        user.setId(2L);
        user.setName("mercyblitz");
        // "user"对象不允许属性赋值(配置元信息 -> 属性值)
        return false; // 跳过原有bean属性植入,手动的去植入,类似于一种拦截机制。此时Bean的实例化完成了,但是属性的赋值并没有完成。
    }
    return true; // 按原有逻辑
}

Spring bean属性赋值前阶段

** 赋值前阶段-- 赋值阶段 – invokeAwareMethods – postProcessBeforeInitialization(invokeInitMethods(postConsturct)) – invokeInitMethods(afterPropertiesSet -> invokeCustomInitMethod) **

  • Bean属性值元信息 - PropertyValues
  • Bean属性赋值前回调
    • Spring 1.2-5.0:InstantiationAwareBeanPostProcessor#postProcessPropertyValues
    • Spring 5.1:InstantiationAwareBeanPostProcessor#postProcessProperties

Bean的属性赋值前的一个回调,可以动态调整原来的PropertyValues。

// 可以去拦截,可以把配置里面的值进行修改
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
    return null; // 默认不做任何修改
}
static class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    
    // Returnng false will also prevent any subsequent InstantiationAwareBeanpostProcessor instances being invoked on this bean instance.
    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        if(ObjectUtils.nullSafeEquals("user", beanName) {
            return false;
        }
        return true;
    }
    
    // postProcessAfterInstantiation返回了false的时候,postProcessProperties不会被调用
    @Override
    public PropertyValues postProcessProperties(PropertyValues pvs, Objecjt bean, String beanName) throws BeansException {
        if(ObjectUtils.nullSafeEquals("userHolder", beanName)) {
            final MutablepropertyValues propertyValues = new MutablePropetyValues();
            
            propertyValues.addPropertyValue("number", "1");
            return propertyValues;
        }
        return null;
    }
}

Spring Bean Aware接口回调阶段

回调,在bean的initializing阶段

Spring Aware接口:

  • BeanNameAware
  • BeanClassLoaderAware
  • BeanFactoryAware

普通的BeanFactory只会有这三种回调

ApplicationContext回调方式多一些,有下面这几种

  • EnvironmentAware
  • EmbeddedValueResolverAware
  • ResourceLoaderAware
  • ApplicationEventPublisherAware
  • MessageSourceAware
  • ApplicationContextAware
public Class AbstractApplicationContext {
    ...
    
    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        
        //config the bean factory with context callbacks
        // 通过添加beanPostProcessor来完成Aware的 回调,是第一位的beanPostProcessor  
        // 在BeforeInitialization之前,就会把响应的Aware进行回调操作
        // 只能在 ApplicationContext进行回调
        beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
         
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值