前言
接上篇Spring源码学习(五)-- Bean的生命周期(上)
Spring Bean总体的创建过程如下:
在上一篇文章把spring扫描(生成beanDefinition)、合并BeanDefinition,那么接下就是根据BeanDefinition创建spring bean的过程了。
上篇文章分析到refresh()方法中finishBeanFactoryInitialization的方法会实例化非懒加载单例bean,继续走到org.springframework.beans.factory.support.DefaultListableBeanFactory#preInstantiateSingletons()方法
上篇文章分析到是非懒加载单例bean,并且不是FactoryBean的会,会调用getBean(beanName)
去创建Bean对象。
本篇文章就从getBean方法继续分析Bean的生命周期。
Bean的生成过程
这是一个门面方法,直接调用了doGetBean方法:
transformedBeanName(name)方法为beanName转换的执行逻辑:
一是循环去除FactoryBean的修饰符(&)
二是从缓存中取指定alias别名所表示的最终beanName
然后是从单例池中根据beanName获取bean:
Object beanInstance = getSingleton(beanName, false);
上篇文章分析了spring启动之后可以取到bean的情况,而现在是spring容器在启动中,所以是获取不到,那么spring容器就要根据BeanDefinition去创建bean了
//当前bean是不是原型的或者是正在创建中的--循环依赖有关
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
这个判断是和循环依赖有关,之后会单独再循环依赖文章分析
//如果当前beanFacroty没有该beanName的beanDefinition,并且有父beanFacroty,就会去调用父beanFacroty的getBean,并返回
BeanFactory parentBeanFactory = getParentBeanFactory();
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);
}
}
如果当前beanFacroty没有该beanName的beanDefinition,并且有父beanFacroty,就会去调用父beanFacroty的getBean,并返回
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
同样和循环依赖有关,之后会单独再循环依赖文章分析
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查BeanDefinition是不是抽象的
checkMergedBeanDefinition(mbd, beanName, args);
获取合并后的BeanDefinition,并且检查BeanDefinition是不是抽象的
接下来就是@DependsOn注解的处理
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了
for (String dep : dependsOn) {
// beanName是不是被dep依赖了,如果是则出现了循环依赖
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
// dep被beanName依赖了,存入dependentBeanMap中,dep为key,beanName为value
registerDependentBean(dep, beanName);
try {
// 创建所依赖的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
首先从BeanDefinition中拿到当前Bean Dependon的数组
dependsOn表示当前beanName所依赖的,当前Bean创建之前dependsOn所依赖的Bean必须已经创建好了,也就是说我们再创建userServiceImpl时候DepentsOn了orderServiceImpl和car,所以我们要先把orderServiceImpl和car创建出来
如果当前beanName有dependsOn,那么就循环处理
首先dep(被依赖的bean)是不是依赖了beanName(当前要创建的bean),如果dep也依赖了beanName,就会抛错,由于dependsOn注解引起的循环依赖,是没有办法解决的
如果没有,继续走,会将dependsOn的依赖关系缓存:
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
注意这两个map:dependentBeanMap和dependenciesForBeanMap
dependentBeanMap:某个Bean被哪些Bean依赖了
dependenciesForBeanMap:某个Bean依赖了哪些Bean
再之后就会先去创建所依赖的bean
当然getBean(dep)还是会走doGetBean()
dependsOn依赖的Bean创建完成之后,就要继续创建我们的beanName(userServiceImpl)
接下来是对@Scope的处理
if (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);
}
如果是单例bean,先去单例池中取,注意getSingleton方法的第二个参数传的是一个lambda表达式
单例池中没有当前bean,就会回调lambda表达式的方法取创建bean
创建完成之后,把他放到单例池中
getSingleton方法返回单例bean,之后执行getObjectForBeanInstance:
这个方法上篇文章有分析,针对FactoryBean的判断和处理
如果是多例原型bean:
接下来是其他作用域,比如request,session,application等等,下面以session为例:
String scopeName = mbd.getScope();
if (!StringUtils.hasLength(scopeName)) {
throw new IllegalStateException("No scope name defined for bean '" + beanName + "'");
}
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);
}
首先从beanDefinition中拿到scope设置的值
然后根据scopeName得到一个Scope对象:比如RequestScope,SessionScope等实现类
接下来和单例bean类似:
scope.get
objectFactory传入的是lambda表达式,当objectFactory.getObject时就会执行lambda表达式的代码。
sessionScope的get方法:
调用父类(AbstractRequestAttributesScope,同样也是requestScope的父类)的get方法:
public Object get(String name, ObjectFactory<?> objectFactory) {
RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
Object scopedObject = attributes.getAttribute(name, getScope());
if (scopedObject == null) {
scopedObject = objectFactory.getObject();
attributes.setAttribute(name, scopedObject, getScope());
// Retrieve object again, registering it for implicit session attribute updates.
// As a bonus, we also allow for potential decoration at the getAttribute level.
Object retrievedObject = attributes.getAttribute(name, getScope());
if (retrievedObject != null) {
// Only proceed with retrieved object if still present (the expected case).
// If it disappeared concurrently, we return our locally created instance.
scopedObject = retrievedObject;
}
}
return scopedObject;
}
Object scopedObject = attributes.getAttribute(name, getScope());
首先先去request或者session中根据name取bean,如果取到直接返回,如果取不到则创建bean
scopedObject = objectFactory.getObject();
回调lambda表达式的方法,创建bean
attributes.setAttribute(name, scopedObject, getScope());
将创建好的bean存放到requst或session中
无论是哪种scope作用域,都会调用createBean方法创建bean,之后执行getObjectForBeanInstance方法针对FactoryBean处理,拿到创建完成的bean之后,检查通过name所获得到的beanInstance的类型是否是requiredType
// 检查通过name所获得到的beanInstance的类型是否是requiredType
// Check if required type matches the type of the actual bean instance.
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());
}
}
如果requiredType 不等于空,并且拿到的bean不是requiredType 类型,那么就进行类型转换,如果可以转换,返回转换之后的类型,否则报错。
上面无论是哪种scope作用域,都是调用createBean方法去创建Bean,接下来就看一下spring是如何创建bean的
@Override
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.
// 马上就要实例化Bean了,确保beanClass被加载了
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method 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.
// 实例化前
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);
}
try {
// 实例化-属性填充-初始化
Object 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. 加载类
createBean方法就是要根据合并后的BeanDefinition去创建Bean对象,而创建Bean就必须实例化对象,而实例化就必须先加载当前BeanDefinition所对应的class,在AbstractAutowireCapableBeanFactory类的createBean()方法中,一开始就会调用:
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
这行代码就是去加载类,该方法是这么实现的:
// 如果beanClass被加载了
// 注意一开始beanDefinition的beanClass存的是该类的类名,是一个字符串
if (mbd.hasBeanClass()) {
return mbd.getBeanClass();
}
// 如果beanClass没有加载
if (System.getSecurityManager() != null) {
return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
}
else {
// 加载class
return doResolveBeanClass(mbd, typesToMatch);
}
public boolean hasBeanClass() {
return (this.beanClass instanceof Class);
}
如果beanClass属性的类型是Class,那么就直接返回,如果不是,则会根据类名进行加载(doResolveBeanClass方法所做的事情)
会利用BeanFactory所设置的类加载器来加载类,doResolveBeanClass方法首先会获取类加载器
ClassLoader beanClassLoader = getBeanClassLoader();
public ClassLoader getBeanClassLoader() {
return this.beanClassLoader;
}
/** ClassLoader to resolve bean class names with, if necessary. */
@Nullable
private ClassLoader beanClassLoader = ClassUtils.getDefaultClassLoader();
如果我们没有自己通过
context.getBeanFactory().setBeanClassLoader();
设置类加载器,则默认使用**ClassUtils.getDefaultClassLoader()**所返回的类加载器来加载。
public static ClassLoader getDefaultClassLoader() {
ClassLoader cl = null;
// 优先获取线程中的类加载器
try {
cl = Thread.currentThread().getContextClassLoader();
}
catch (Throwable ex) {
// Cannot access thread context ClassLoader - falling back...
}
// 线程中类加载器为null的情况下,获取加载ClassUtils类的类加载器
if (cl == null) {
// No thread context class loader -> use class loader of this class.
cl = ClassUtils.class.getClassLoader();
// 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器
if (cl == null) {
// getClassLoader() returning null indicates the bootstrap ClassLoader
try {
cl = ClassLoader.getSystemClassLoader();
}
catch (Throwable ex) {
// Cannot access system ClassLoader - oh well, maybe the caller can live with null...
}
}
}
return cl;
}
- 优先返回当前线程中的ClassLoader
- 线程中类加载器为null的情况下,返回ClassUtils类的类加载器
- 如果ClassUtils类的类加载器为空,那么则表示是Bootstrap类加载器加载的ClassUtils类,那么则返回系统类加载器
String className = mbd.getBeanClassName();
public String getBeanClassName() {
Object beanClassObject = this.beanClass;
if (beanClassObject instanceof Class) {
return ((Class<?>) beanClassObject).getName();
}
else {
return (String) beanClassObject;
}
}
拿到类的名字
最后通过类加载器加载class
return dynamicLoader.loadClass(className);
将加载的class设置给BeanDefinition的beanclass属性
4. 实例化前
当前BeanDefinition对应的类成功加载后,就可以实例化对象了,但是...
在Spring中,实例化对象之前,Spring提供了一个扩展点,允许用户来控制是否在某个或某些Bean实例化之前做一些启动动作。这个扩展点就是InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()。
比如:
@Component
public class FztxBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("userServiceImpl".equals(beanName)) {
System.out.println("实例化前");
}
return null;
}
}
如上代码会导致,在userServiceImpl这个Bean实例化前,会进行打印。
值得注意的是,postProcessBeforeInstantiation()是有返回值的,如果这么实现:
@Component
public class FztxBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("userServiceImpl".equals(beanName)) {
System.out.println("实例化前");
return new userServiceImpl();
}
return null;
}
}
userServiceImpl这个Bean,在实例化前会直接返回一个由我们所定义的userServiceImpl对象。如果是这样,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步。
我们看一下源码是如何实现的:
// 实例化前
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
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是合成的,那么则不会经过BeanPostProcessors
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
Class<?> targetType = determineTargetType(beanName, mbd);
if (targetType != null) {
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
}
}
mbd.beforeInstantiationResolved = (bean != null);
}
return bean;
}
如果spring容器中有InstantiationAwareBeanPostProcessor的实现类,那么将执行
bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
这个方法就是去执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()的
进去看一下:
protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
if (result != null) {
return result;
}
}
}
return null;
}
这里会循环所有的BeanPostProcessor(InstantiationAwareBeanPostProcessor实现了BeanPostProcessor),如果是InstantiationAwareBeanPostProcessor实现,就会执行postProcessBeforeInstantiation(实例化前),如果返回的结果不为null,就直接返回,后面的
InstantiationAwareBeanPostProcessor实现类将不会继续执行,所有的InstantiationAwareBeanPostProcessor实现类都执行完,返回结果都为null,则返回null。
执行完applyBeanPostProcessorsBeforeInstantiation方法会得到一个返回值bean,
如果bean不为null,将执行applyBeanPostProcessorsAfterInitialization
if (bean != null) {
bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}
循环BeanPostProcessor,执行postProcessAfterInitialization(初始化后)
执行完resolveBeforeInstantiation方法会返回一个Object,
如果返回的Object不为null,将直接返回,这个返回值将代替原本该生成的目标对象的实例(比如代理对象),后续只有postProcessAfterInitialization(初始化后)方法会调用,其它方法(属性赋值,初始化前,初始化)不再调用;
如果返回的Object为null,那么就会按照Spring正常的流程走
try {
// 实例化-属性填充-初始化
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
5. 实例化
doCreateBean方法中中会进行实例化:
// 创建bean实例
instanceWrapper = createBeanInstance(beanName, mbd, args);
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());
}
// BeanDefinition中添加了Supplier,则调用Supplier来得到对象
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
// @Bean对应的BeanDefinition
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
// Shortcut when re-creating the same bean...
// 一个原型BeanDefinition,会多次来创建Bean,那么就可以把该BeanDefinition所要使用的构造方法缓存起来,避免每次都进行构造方法推断
boolean resolved = false;
boolean autowireNecessary = false;
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
if (mbd.resolvedConstructorOrFactoryMethod != null) {
resolved = true;
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
if (resolved) {
// 如果确定了当前BeanDefinition的构造方法,那么看是否需要进行对构造方法进行参数的依赖注入(构造方法注入)
if (autowireNecessary) {
return autowireConstructor(beanName, mbd, null, null);
}
else {
// 如果不需要注入,则表示用的是默认无参构造方法,直接进行实例化
return instantiateBean(beanName, mbd);
}
}
// Candidate constructors for autowiring?
// 提供一个扩展点,可以利用SmartInstantiationAwareBeanPostProcessor来控制用beanClass中的哪个构造方法
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
// 如果ctors有值则需要进行构造方法注入,或者autowiredMode是AUTOWIRE_CONSTRUCTOR
// 或者BeanDefinition中添加了构造方法的参数和值,或者调用getBean()方法时传入了args
// 构造方法注入:首先包括
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.
// 如果没有@Autowired注解的构造方法,当前BeanDefinition的autowiremode也不是AUTOWIRE_CONSTRUCTOR,也没有指明所要用的构造方法参数值
// 则直接使用无参构造方法
return instantiateBean(beanName, mbd);
}
在这个步骤中就会根据BeanDefinition去创建一个对象了。
5.1 Supplier创建对象
首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象。
得直接使用BeanDefinition对象来设置Supplier,比如:
AbstractBeanDefinition beanDefinition = BeanDefinitionBuilder.genericBeanDefinition().getBeanDefinition();
beanDefinition.setInstanceSupplier(new Supplier<Object>() {
@Override
public Object get() {
return new UserService();
}
});
context.registerBeanDefinition("userService", beanDefinition);
5.2 工厂方法创建对象
如果没有设置Supplier,则检查BeanDefinition中是否设置了factoryMethod,也就是工厂方法,有两种方式可以设置factoryMethod,比如:
方式一:
<bean id="userService" class="com.zhouyu.service.UserService" factory-method="createUserService" />
对应的UserService类为:
public class UserService {
public static UserService createUserService() {
System.out.println("执行createUserService()");
UserService userService = new UserService();
return userService;
}
public void test() {
System.out.println("test");
}
}
方式二:
<bean id="commonService" class="com.zhouyu.service.CommonService"/>
<bean id="userService1" factory-bean="commonService" factory-method="createUserService" />
对应的CommonService的类为:
public class CommonService {
public UserService createUserService() {
return new UserService();
}
}
Spring发现当前BeanDefinition方法设置了工厂方法后,就会区分这两种方式,然后调用工厂方法得到对象。
值得注意的是,我们通过@Bean所定义的BeanDefinition,是存在factoryMethod和factoryBean的,也就是和上面的方式二非常类似,@Bean所注解的方法就是factoryMethod,AppConfig对象就是factoryBean。如果@Bean所所注解的方法是static的,那么对应的就是方式一。
5.3 推断构造方法
第一篇文章已经讲过一遍大概原理了,后面有一篇文章单独分析源码实现。推断完构造方法后,就会使用构造方法来进行实例化了。
额外的,在推断构造方法逻辑中除开会去选择构造方法以及查找入参对象意外,会还判断是否在对应的类中是否存在使用**@Lookup注解**了方法。如果存在则把该方法封装为LookupOverride对象并添加到BeanDefinition中。
在实例化时,如果判断出来当前BeanDefinition中没有LookupOverride,那就直接用构造方法反射得到一个实例对象。如果存在LookupOverride对象,也就是类中存在@Lookup注解了的方法,那就会生成一个代理对象。
@Lookup注解就是方法注入,使用demo如下:
@Component
public class UserService {
private OrderService orderService;
public void test() {
OrderService orderService = createOrderService();
System.out.println(orderService);
}
@Lookup("orderService")
public OrderService createOrderService() {
return null;
}
}
6. BeanDefinition的后置处理
Bean对象实例化出来之后,接下来就应该给对象的属性赋值了。在真正给属性赋值之前,Spring又提供了一个扩展点MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition(),可以对此时的BeanDefinition进行加工,比如:
@Component
public class FztxMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
@Override
public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
if ("userServiceImpl".equals(beanName)) {
beanDefinition.setInitMethodName("a");
beanDefinition.getPropertyValues().add("orderService", new OrderServiceImpl());
}
}
}
我们看一下源码是如何实现的:
protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof MergedBeanDefinitionPostProcessor) {
MergedBeanDefinitionPostProcessor bdp = (MergedBeanDefinitionPostProcessor) bp;
bdp.postProcessMergedBeanDefinition(mbd, beanType, beanName);
}
}
}
同样循环所有的BeanPostProcessor,如果是MergedBeanDefinitionPostProcessor的实现类,则执行postProcessMergedBeanDefinition方法。
我们可以通过实现MergedBeanDefinitionPostProcessor并重写postProcessMergedBeanDefinition方法来修改BeanDefinition,当然这里至于修改之后会用到的BeanDefinition的属性才会有用,比如说初始化方法、给某个属性赋值等等。
在Spring源码中,AutowiredAnnotationBeanPostProcessor就是一个MergedBeanDefinitionPostProcessor,它的postProcessMergedBeanDefinition()中会去查找注入点,并缓存在AutowiredAnnotationBeanPostProcessor对象的一个Map中(injectionMetadataCache)。
执行完beandefinition的后置处理之后,将执行populateBean(beanName, mbd, instanceWrapper)
在这个方法中将进行属性赋值,我们继续看:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
if (bw == null) {
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
// Give any InstantiationAwareBeanPostProcessors the opportunity to modify the
// state of the bean before properties are set. This can be used, for example,
// to support styles of field injection.
// 实例化之后,属性设置之前
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
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;
}
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
PropertyDescriptor[] filteredPds = null;
if (hasInstAwareBpps) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
// 这里会调用AutowiredAnnotationBeanPostProcessor的postProcessProperties()方法,会直接给对象中的属性赋值
// AutowiredAnnotationBeanPostProcessor内部并不会处理pvs,直接返回了
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
PropertyValues pvsToUse = ibp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
pvsToUse = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvsToUse == null) {
return;
}
}
pvs = pvsToUse;
}
}
}
if (needsDepCheck) {
if (filteredPds == null) {
filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
}
checkDependencies(beanName, mbd, filteredPds, pvs);
}
// 如果当前Bean中的BeanDefinition中设置了PropertyValues,那么最终将是PropertyValues中的值,覆盖@Autowired
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}
7. 实例化后
在处理完BeanDefinition后,Spring又设计了一个扩展点:InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(),比如:
@Component
public class FztxBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("userServiceImpl".equals(beanName)) {
System.out.println("实例化前");
}
return null;
}
@Override
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("实例化后");
if ("userServiceImpl".equals(beanName)) {
UserServiceImpl userService = (UserServiceImpl) bean;
userService.sayHi();
}
return true;
}
}
上述代码就是对userServiceImpl所实例化出来的对象进行处理。
我们看一下源码:
// 实例化之后,属性设置之前
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return;
}
}
}
}
循环所有的BeanPostProcessor(InstantiationAwareBeanPostProcessor实现了BeanPostProcessor),如果是InstantiationAwareBeanPostProcessor实现,就会执行postProcessAfterInstantiation(实例化后)
这个扩展点,在Spring源码中基本没有怎么使用。
8. 自动注入
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
int resolvedAutowireMode = mbd.getResolvedAutowireMode();
if (resolvedAutowireMode == AUTOWIRE_BY_NAME || resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
// MutablePropertyValues是PropertyValues具体的实现类
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;
}
Spring自带的依赖注入,比如:
public class UserServiceImpl {
private OrderServiceImpl orderService;
public void setOrderService(OrderServiceImpl orderService) {
this.orderService = orderService;
}
public void sayHi() {
System.out.println("Hello");
}
}
//@Bean(autowire = Autowire.BY_NAME)
@Bean(autowire = Autowire.BY_TYPE)
public UserServiceImpl userService(){
return new UserServiceImpl();
}
但是这种方式的依赖注入已经过期了,很少使用,就是只要你类里面有set开头的方法,spring就会去执行。
这里的自动注入指的是Spring自带的依赖注入(除去@Autowired、@Resource、@Value等注解),具体实现原理后续依赖注入文章中单独讲
9. 处理属性
这个步骤中,就会处理@Autowired、@Resource、@Value等注解,也是通过**InstantiationAwareBeanPostProcessor.postProcessProperties()**扩展点来实现的,比如我们甚至可以实现一个自己的自动注入功能,比如:
@Component
public class FztxInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
for (Field field : bean.getClass().getFields()) {
if (field.isAnnotationPresent(FztxInject.class)) {
field.setAccessible(true);
try {
field.set(bean, "123");
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
}
return pvs;
}
}
源码:
关于@Autowired、@Resource、@Value的底层源码,会在后续的依赖注入文章中详解。
执行完populateBean(beanName, mbd, instanceWrapper)进行属性填充之后,接下来就是进行初始化了
exposedObject = initializeBean(beanName, exposedObject, mbd);
10. 执行Aware
完成了属性赋值之后,Spring会执行一些回调:
- BeanNameAware:回传beanName给bean对象。
- BeanClassLoaderAware:回传classLoader给bean对象。
- BeanFactoryAware:回传beanFactory给对象。
aware系列接口的回调位于initializeBean中的invokeAwareMethods方法:
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
11. 初始化前
初始化前位于位于initializeBean的applyBeanPostProcessorsBeforeInitialization方法:
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
throws BeansException {
Object result = existingBean;
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) {
return result;
}
result = current;
}
return result;
}
初始化前,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessBeforeInitialization(),比如
@Component
public class FztxBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("初始化前");
}
return bean;
}
}
利用初始化前,可以对进行了依赖注入的Bean进行处理。
在Spring源码中:
- InitDestroyAnnotationBeanPostProcessor会在初始化前这个步骤中执行@PostConstruct的方法,
- ApplicationContextAwareProcessor会在初始化前这个步骤中进行其他Aware的回调:
- EnvironmentAware:回传环境变量
- EmbeddedValueResolverAware:回传占位符解析器
- ResourceLoaderAware:回传资源加载器
- ApplicationEventPublisherAware:回传事件发布器
- MessageSourceAware:回传国际化资源
- ApplicationStartupAware:回传应用其他监听对象,可忽略
- ApplicationContextAware:回传Spring容器ApplicationContext
12. 初始化
这里面调用了两个方法,一个是afterPropertiesSet方法,一个是init-method方法:
((InitializingBean) bean).afterPropertiesSet();
invokeCustomInitMethod(beanName, bean, mbd);
- 查看当前Bean对象是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法
- 执行BeanDefinition中指定的初始化方法
13. 初始化后
初始化后位于initializeBean的applyBeanPostProcessorsAfterInitialization:
这是Bean创建生命周期中的最后一个步骤,也是Spring提供的一个扩展点:BeanPostProcessor.postProcessAfterInitialization(),比如:
@Component
public class FztxBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if ("userService".equals(beanName)) {
System.out.println("初始化后");
}
return bean;
}
}
可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象。
当进行到这一步,Bean已经被创建完成了,一直停留在应用的上下文中
Bean的销毁过程
Bean销毁是发生在Spring容器关闭过程中的。
在Spring容器关闭时,比如:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
UserService userService = (UserService) context.getBean("userService");
userService.test();
// 容器关闭
context.close();
在Bean创建过程中,在最后(初始化之后),有一个步骤会去判断当前创建的Bean是不是DisposableBean:
protected void registerDisposableBeanIfNecessary(String beanName, Object bean, RootBeanDefinition mbd) {
AccessControlContext acc = (System.getSecurityManager() != null ? getAccessControlContext() : null);
if (!mbd.isPrototype() && requiresDestruction(bean, mbd)) {
if (mbd.isSingleton()) {
// Register a DisposableBean implementation that performs all destruction
// work for the given bean: DestructionAwareBeanPostProcessors,
// DisposableBean interface, custom destroy method.
registerDisposableBean(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
else {
// A bean with a custom scope...
Scope scope = this.scopes.get(mbd.getScope());
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + mbd.getScope() + "'");
}
scope.registerDestructionCallback(beanName,
new DisposableBeanAdapter(bean, beanName, mbd, getBeanPostProcessors(), acc));
}
}
}
- 当前Bean是否实现了DisposableBean接口
- 或者,当前Bean是否实现了AutoCloseable接口
- BeanDefinition中是否指定了destroyMethod
- 调用DestructionAwareBeanPostProcessor.requiresDestruction(bean)进行判断
- ApplicationListenerDetector中直接使得ApplicationListener是DisposableBean
- InitDestroyAnnotationBeanPostProcessor中使得拥有@PreDestroy注解了的方法就是DisposableBean
- 把符合上述任意一个条件的Bean适配成DisposableBeanAdapter对象,并存入disposableBeans中(一个LinkedHashMap)
在Spring容器关闭过程时:
- 首先发布ContextClosedEvent事件
- 调用lifecycleProcessor的onCloese()方法
- 销毁单例Bean
- 遍历disposableBeans
- 把每个disposableBean从单例池中移除
- 调用disposableBean的destroy()
- 如果这个disposableBean还被其他Bean依赖了,那么也得销毁其他Bean
- 如果这个disposableBean还包含了inner beans,将这些Bean从单例池中移除掉 (inner bean参考Core Technologies)
- 清空manualSingletonNames,是一个Set,存的是用户手动注册的单例Bean的beanName
- 清空allBeanNamesByType,是一个Map,key是bean类型,value是该类型所有的beanName数组
- 清空singletonBeanNamesByType,和allBeanNamesByType类似,只不过只存了单例Bean
- 遍历disposableBeans
这里涉及到一个设计模式:适配器模式
在销毁时,Spring会找出实现了DisposableBean接口的Bean。
但是我们在定义一个Bean时,如果这个Bean实现了DisposableBean接口,或者实现了AutoCloseable接口,或者在BeanDefinition中指定了destroyMethodName,那么这个Bean都属于“DisposableBean”,这些Bean在容器关闭时都要调用相应的销毁方法。
所以,这里就需要进行适配,将实现了DisposableBean接口、或者AutoCloseable接口等适配成实现了DisposableBean接口,所以就用到了DisposableBeanAdapter。
会把实现了AutoCloseable接口的类封装成DisposableBeanAdapter,而DisposableBeanAdapter实现了DisposableBean接口。
总结BeanPostProcessor
- InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()----实例化前
- 实例化
- MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()--BeanDefinition后置处理
- InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation()--实例化后
- 属性赋值(spring自带的依赖注入)
- InstantiationAwareBeanPostProcessor.postProcessProperties()--@Autowired、@Resource等
- Aware对象
- BeanPostProcessor.postProcessBeforeInitialization()--初始化前
- 初始化
- BeanPostProcessor.postProcessAfterInitialization()--初始化后
Spring Bean的生命周期
Spring In Action以及市面上流传的大部分博客是这样的:
- 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为连Autowired注解都是没有解析的;
- 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
- 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
- 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
- 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
- 调用BeanPostProcessor的postProcessBeforeInitialization方法;
- 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
- 如果Bean定义了init-method方法,则调用Bean的init-method方法;
- 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁;
- 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用。