《Spring 高手系列》(Bean生命周期)笔记

参考链接1

Spring bean生命周期

  1. 阶段1:Bean元信息配置阶段
  2. 阶段2:Bean元信息解析阶段
  3. 阶段3:将Bean注册到容器中
  4. 阶段4:BeanDefinition合并阶段
  5. 阶段5:Bean Class加载阶段
  6. 阶段6:Bean实例化阶段
  7. 阶段7:合并后的BeanDefinition处理
  8. 阶段8:属性赋值阶段
  9. 阶段9:Bean初始化阶段
  10. 阶段10:所有单例bean初始化完成后阶段
  11. 阶段11:Bean的使用阶段
  12. 阶段12:Bean销毁前阶段
  13. 阶段13:Bean销毁阶段

阶段6分为

  1. Bean实例化前阶段
  2. Bean实例化阶段

阶段8分为

  1. Bean实例化后阶段
  2. Bean属性赋值前阶段.
  3. Bean属性赋值阶段

阶段9分为

  1. Bean Aware接口回调阶段
  2. Bean初始化前阶段
  3. Bean初始化阶段
  4. Bean初始化后阶段

阶段1:Bean元信息配置阶段

Bean信息定义4种方式

主要包括xml,@Bean,properties文件,接口

接口

案例1:组装一个简单的bean

public class Car {
    private String name;
	//省略get、set、toStirng
}
public class Client {
    public static void main(String[] args) {
        BeanDefinitionBuilder beanDefinitionBuilder = 
        BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
        BeanDefinition beanDefinition = beanDefinitionBuilder.getBeanDefinition();
        System.out.println(beanDefinition);
    }
}

输出

Root bean: class [com.example.lurenjia.spring.c22.d1.Car];
scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0;
autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null;
initMethodName=null; destroyMethodName=null

案例2:组装一个有属性的bean

public class Client2 {
    public static void main(String[] args) {
        BeanDefinitionBuilder beanDefinitionBuilder = 
        BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName());
        beanDefinitionBuilder.addPropertyValue("name", "奥迪");
        BeanDefinition carBeanDefinition = beanDefinitionBuilder.getBeanDefinition();
        System.out.println(carBeanDefinition);
        System.out.println("----");
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("car", carBeanDefinition);
        Car bean = factory.getBean("car", Car.class);
        System.out.println(bean);
    }
}

输出

Root bean: class [com.example.lurenjia.spring.c22.jd1.d1.Car]; scope=; abstract=false; lazyInit=null;
 autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; 
 factoryMethodName=null; initMethodName=null; destroyMethodName=null
----
Creating shared instance of singleton bean 'car'
Car{name='奥迪'}

案例3:组装一个有依赖关系的bean

public class User {

    private String name;

    private Car car;
	//省略get、set、toStirng
}
public class Client3 {
    public static void main(String[] args) {
        BeanDefinition carBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(Car.class.getName()).addPropertyValue("name", "奥迪").getBeanDefinition();
        BeanDefinition userBeanDefinition = BeanDefinitionBuilder.rootBeanDefinition(User.class.getName()).
                addPropertyValue("name", "路人甲Java").
                addPropertyReference("car", "car").
                getBeanDefinition();
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("car", carBeanDefinition);
        factory.registerBeanDefinition("user", userBeanDefinition);
        System.out.println(factory.getBean("car"));
        System.out.println(factory.getBean("user"));
    }
}
Car{name='奥迪'}
User{name='路人甲Java', car=Car{name='奥迪'}}

案例4:来2个有父子关系的bean

public class Client4 {
    public static void main(String[] args) {
        BeanDefinition carBeanDefinition1 = BeanDefinitionBuilder.
                genericBeanDefinition(Car.class).
                addPropertyValue("name", "保时捷").
                getBeanDefinition();

        BeanDefinition carBeanDefinition2 = BeanDefinitionBuilder.
                genericBeanDefinition().
                setParentName("car1").
                getBeanDefinition();
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("car1", carBeanDefinition1);
        factory.registerBeanDefinition("car2", carBeanDefinition2);
        System.out.println(String.format("car1->%s", factory.getBean("car1")));
        System.out.println(String.format("car2->%s", factory.getBean("car2")));
    }
}
car1->Car{name='保时捷'}
car2->Car{name='保时捷'}

案例5:通过api设置(Map、Set、List)属性

public class CompositeObj {

    private String name;
    private Integer salary;

    private Car car1;
    private List<String> stringList;
    private List<Car> carList;

    private Set<String> stringSet;
    private Set<Car> carSet;

    private java.util.Map<String, String> stringMap;
    private java.util.Map<String, Car> stringCarMap;

    //省略get set tostring
}
public class Client {
    public static void main(String[] args) {
        //定义car1
        BeanDefinition car1 = BeanDefinitionBuilder.
                genericBeanDefinition(Car.class).
                addPropertyValue("name", "奥迪").
                getBeanDefinition();
        //定义car2
        BeanDefinition car2 = BeanDefinitionBuilder.
                genericBeanDefinition(Car.class).
                addPropertyValue("name", "保时捷").
                getBeanDefinition();

        //定义CompositeObj这个bean
        //创建stringList这个属性对应的值
        ManagedList<String> stringList = new ManagedList<>();
        stringList.addAll(Arrays.asList("java高并发系列", "mysql系列", "maven高手系列"));

        //创建carList这个属性对应的值,内部引用其他两个bean的名称[car1,car2]
        ManagedList<RuntimeBeanReference> carList = new ManagedList<>();
        carList.add(new RuntimeBeanReference("car1"));
        carList.add(new RuntimeBeanReference("car2"));

        //创建stringList这个属性对应的值
        ManagedSet<String> stringSet = new ManagedSet<>();
        stringSet.addAll(Arrays.asList("java高并发系列", "mysql系列", "maven高手系列"));

        //创建carSet这个属性对应的值,内部引用其他两个bean的名称[car1,car2]
        ManagedList<RuntimeBeanReference> carSet = new ManagedList<>();
        carSet.add(new RuntimeBeanReference("car1"));
        carSet.add(new RuntimeBeanReference("car2"));

        //创建stringMap这个属性对应的值
        ManagedMap<String, String> stringMap = new ManagedMap<>();
        stringMap.put("系列1", "java高并发系列");
        stringMap.put("系列2", "Maven高手系列");
        stringMap.put("系列3", "mysql系列");

        ManagedMap<String, RuntimeBeanReference> stringCarMap = new ManagedMap<>();
        stringCarMap.put("car1", new RuntimeBeanReference("car1"));
        stringCarMap.put("car2", new RuntimeBeanReference("car2"));


        //下面我们使用原生的api来创建BeanDefinition
        GenericBeanDefinition compositeObj = new GenericBeanDefinition();
        compositeObj.setBeanClassName(CompositeObj.class.getName());
        compositeObj.getPropertyValues().add("name", "路人甲Java").
                add("salary", 50000).
                add("car1", new RuntimeBeanReference("car1")).
                add("stringList", stringList).
                add("carList", carList).
                add("stringSet", stringSet).
                add("carSet", carSet).
                add("stringMap", stringMap).
                add("stringCarMap", stringCarMap);

        //将上面bean 注册到容器
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("car1", car1);
        factory.registerBeanDefinition("car2", car2);
        factory.registerBeanDefinition("compositeObj", compositeObj);

        //下面我们将容器中所有的bean输出
        for (String beanName : factory.getBeanDefinitionNames()) {
            System.out.println(String.format("%s->%s", beanName, factory.getBean(beanName)));
        }
    }
}

xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="helloWorld" class="com.example.lurenjia.spring.c3.HelloWorld"/>

</beans>

xml中的bean配置信息会被解析器解析为BeanDefinition对象,一会在第二阶段详解。

properties文件的方式

参照阶段2解析里面properties文件定义内容

注解的方式

类上标注@Compontent注解来定义一个bean

示例省略

配置类中使用@Bean注解来定义bean

示例省略

阶段2:Bean元信息解析阶段

目的:将阶段1各种方式的定义解析为 BeanDefinition 对象

XML方式解析:XmlBeanDefinitionReader

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
       
    <bean id="helloWorld" class="com.example.lurenjia.spring.c3.HelloWorld"/>

</beans>
public class Client {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader xmlBeanDefinitionReader = new XmlBeanDefinitionReader(factory);
        String location = "classpath:beans3.xml";
        int countBean = xmlBeanDefinitionReader.loadBeanDefinitions(location);
        System.out.println(String.format("共注册了 %s 个bean", countBean));
        for (String beanName : factory.getBeanDefinitionNames()) {
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
            String beanDefinitionClassName = beanDefinition.getClass().getName();
            Object bean = factory.getBean(beanName);
            System.out.println(beanName + ":");
            System.out.println("    beanDefinitionClassName:" + beanDefinitionClassName);
            System.out.println("    beanDefinition:" + beanDefinition);
            System.out.println("    bean:" + bean);
        }
    }
}
共注册了 1 个bean
helloWorld:
    beanDefinitionClassName:org.springframework.beans.factory.support.GenericBeanDefinition
    beanDefinition:Generic bean: class [com.example.lurenjia.spring.c3.HelloWorld]; scope=; abstract=false; 
    lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; 
    factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; 
    defined in class path resource [beans3.xml]
    bean:com.example.lurenjia.spring.c3.HelloWorld@51565ec2

properties文件定义bean的解析:PropertiesBeanDefinitionReader

官方示例

   employee.(class)=MyClass       // bean is of class MyClass
   employee.(abstract)=true       // this bean can't be instantiated directly
   employee.group=Insurance       // real property
   employee.usesDialUp=false      // real property (potentially overridden)
  
   salesrep.(parent)=employee     // derives from "employee" bean definition
   salesrep.(lazy-init)=true      // lazily initialize this singleton bean
   salesrep.manager(ref)=tony     // reference to another bean
   salesrep.department=Sales      // real property
  
   techie.(parent)=employee       // derives from "employee" bean definition
   techie.(scope)=prototype       // bean is a prototype (not a shared instance)
   techie.manager(ref)=jeff       // reference to another bean
   techie.department=Engineering  // real property
   techie.usesDialUp=true         // real property (overriding parent value)
  
   ceo.$0(ref)=secretary          // inject 'secretary' bean as 0th constructor arg
   ceo.$1=1000000                 // inject value '1000000' at 1st constructor arg

我们在resource目录下创建一个beans.properties

car.(class)=com.example.lurenjia.spring.c22.jd1.d1.Car
car.name=name1

car1.(class)=com.example.lurenjia.spring.c22.jd1.d1.Car
car1.name=name2
public class Client {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        PropertiesBeanDefinitionReader propertiesBeanDefinitionReader = new PropertiesBeanDefinitionReader(factory);
        String location = "classpath:beans.properties";
        int countBean = propertiesBeanDefinitionReader.loadBeanDefinitions(location);
        System.out.println(String.format("共注册了 %s 个bean", countBean));
        for (String beanName : factory.getBeanDefinitionNames()) {
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
            String beanDefinitionClassName = beanDefinition.getClass().getName();
            Object bean = factory.getBean(beanName);
            System.out.println(beanName + ":");
            System.out.println("    beanDefinitionClassName:" + beanDefinitionClassName);
            System.out.println("    beanDefinition:" + beanDefinition);
            System.out.println("    bean:" + bean);
        }
    }
}

在这里插入图片描述

注解方式:PropertiesBeanDefinitionReader

@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Primary
@Lazy
public class Service1 {
}
public class Service2 {

    @Autowired
    private Service1 service1;

    @Override
    public String toString() {
        return "Service2{" +
                "service1=" + service1 +
                '}';
    }
}
public class Client {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        AnnotatedBeanDefinitionReader annotatedBeanDefinitionReader = new AnnotatedBeanDefinitionReader(factory);
        annotatedBeanDefinitionReader.register(Service1.class, Service2.class);
        for (String beanName : new String[]{"service1", "service2"}) {
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
            String beanDefinitionClassName = beanDefinition.getClass().getName();
            Object bean = factory.getBean(beanName);
            System.out.println(beanName + ":");
            System.out.println("    beanDefinitionClassName:" + beanDefinitionClassName);
            System.out.println("    beanDefinition:" + beanDefinition);
            System.out.println("    bean:" + bean);
        }
    }
}

在这里插入图片描述
这里为什么会输出一个null呢

在 for 循环上面添加一行代码

        factory.getBeansOfType(BeanPostProcessor.class).values().forEach(factory::addBeanPostProcessor);

在这里插入图片描述

阶段3:Spring Bean注册阶段

一个重要的接口 BeanDefinitionRegistry

BeanDefinitionRegistry源码

public interface BeanDefinitionRegistry extends AliasRegistry {
	//注册bean定义
	void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException;
	//移除bean定义
	void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	//获取bean定义
	BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;
	//是否包含bean定义
	boolean containsBeanDefinition(String beanName);
	//获取bean定义名称
	String[] getBeanDefinitionNames();
	//获取bean定义数量
	int getBeanDefinitionCount();
	//beanName是否已经注册
	boolean isBeanNameInUse(String beanName);
}

AliasRegistry

AliasRegistry 是 BeanDefinitionRegistry 的父接口

public interface AliasRegistry {
	//注册别名
	void registerAlias(String name, String alias);
	//移除别名
	void removeAlias(String alias);
	//判断是不是别名
	boolean isAlias(String name);
	//获取别名数组
	String[] getAliases(String name);
}

BeanDefinitionRegistry实现类

DefaultListableBeanFactory

public class Client {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        GenericBeanDefinition nameBdf = new GenericBeanDefinition();
        nameBdf.setBeanClass(String.class);
        nameBdf.getConstructorArgumentValues().addIndexedArgumentValue(0, "abcdefg");
        factory.registerBeanDefinition("name", nameBdf);
        System.out.println(factory.getBeanDefinition("name"));
        System.out.println(factory.containsBeanDefinition("name"));
        System.out.println(Arrays.asList(factory.getBeanDefinitionNames()));
        System.out.println(factory.getBeanDefinitionCount());
        System.out.println(factory.isBeanNameInUse("name"));
        factory.registerAlias("name", "alias-name-1");
        factory.registerAlias("name", "alias-name-2");
        System.out.println(factory.isAlias("alias-name-1"));
        System.out.println(Arrays.asList(factory.getAliases("name")));
        System.out.println(factory.getBean("name"));
    }
}
Generic bean: class [java.lang.String]; scope=; abstract=false; lazyInit=null; autowireMode=0; dependencyCheck=0; autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null
true
[name]
1
true
true
[alias-name-2, alias-name-1]
10:25:45.492 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'name'
abcdefg

阶段4:BeanDefinition合并阶段

目的:

案例

public class LessonModel {

    private String name;

    private int lessonCount;

    private String description;
    //省略get set tostring

}

定义xml文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="lesson1" class="com.example.lurenjia.spring.c22.jd4.LessonModel"/>

    <bean id="lesson2" parent="lesson1">
        <property name="name" value="spring高手系列"/>
        <property name="lessonCount" value="100"/>
    </bean>

    <bean id="lesson3" parent="lesson2">
        <property name="description" value="路人甲Java带你学spring,超越90%开发者!"/>
    </bean>
</beans>
public class Client {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(factory);
        beanDefinitionReader.loadBeanDefinitions("classpath:c22jd4d1.xml");
        for (String beanName : factory.getBeanDefinitionNames()) {
            BeanDefinition beanDefinition = factory.getBeanDefinition(beanName);
            BeanDefinition mergedBeanDefinition = factory.getMergedBeanDefinition(beanName);
            System.out.println(beanName);
            System.out.println("解析xml过程中注册的beanDefinition:" + beanDefinition);
            System.out.println("beanDefinition中的属性信息" + beanDefinition.getPropertyValues());
            System.out.println("合并之后得到的mergedBeanDefinition:" + mergedBeanDefinition);
            System.out.println("mergedBeanDefinition中的属性信息" + mergedBeanDefinition.getPropertyValues());
            System.out.println("---------------------------");
        }
    }
}
lesson3
解析xml过程中注册的beanDefinition:Generic bean with parent 'lesson2': 
class [null]; scope=; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; 
autowireCandidate=true; primary=false; factoryBeanName=null; factoryMethodName=null;
 initMethodName=null; destroyMethodName=null; defined in class path resource [c22jd4d1.xml]
beanDefinition中的属性信息PropertyValues: length=1; bean property 'description'
合并之后得到的mergedBeanDefinition:Root bean: class [com.example.lurenjia.spring.c22.jd4.LessonModel]; 
scope=singleton; abstract=false; lazyInit=false; autowireMode=0; dependencyCheck=0; autowireCandidate=true; 
primary=false; factoryBeanName=null; factoryMethodName=null; initMethodName=null; destroyMethodName=null; 
defined in class path resource [c22jd4d1.xml]
mergedBeanDefinition中的属性信息PropertyValues: length=3; bean property 'name'; bean property 'lessonCount';
bean property 'description'

阶段5:Bean Class加载阶段 (resolveBeanClass)

Resolve the bean class for the specified bean definition, resolving a bean class name into a Class reference (if necessary) and storing the resolved Class in the bean definition for further use.

将 bean definition 解析为 bean class.

	@Nullable
	protected Class<?> resolveBeanClass(RootBeanDefinition mbd, String beanName, Class<?>... typesToMatch)
			throws CannotLoadBeanClassException {

		try {
			if (mbd.hasBeanClass()) {
				return mbd.getBeanClass();
			}
			if (System.getSecurityManager() != null) {
				return AccessController.doPrivileged((PrivilegedExceptionAction<Class<?>>)
						() -> doResolveBeanClass(mbd, typesToMatch), getAccessControlContext());
			}
			else {
				return doResolveBeanClass(mbd, typesToMatch);
			}
		}
		catch (PrivilegedActionException pae) {
			ClassNotFoundException ex = (ClassNotFoundException) pae.getException();
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
		}
		catch (ClassNotFoundException ex) {
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), ex);
		}
		catch (LinkageError err) {
			throw new CannotLoadBeanClassException(mbd.getResourceDescription(), beanName, mbd.getBeanClassName(), err);
		}
	}

阶段6:Bean实例化阶段

createBean方法

		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;
			}
		}

resolveBeforeInstantiation

	@Nullable
	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.
			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;
	}
	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
		return null;
	}

阶段7:合并后的BeanDefinition处理

doCreateBean类583行applyMergedBeanDefinitionPostProcessors

		// Allow post-processors to modify the merged bean definition. 
		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;
			}
		}

applyMergedBeanDefinitionPostProcessors

	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
			processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}

postProcessMergedBeanDefinition是MergedBeanDefinitionPostProcessor接口的方法

	void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

主要实现类 todo

阶段8:Bean属性设置阶段

		// Initialize the bean instance. 初始化bean实例
		Object exposedObject = bean;
		try {
			//填充bean,涉及阶段8
			populateBean(beanName, mbd, instanceWrapper);
			//初始化bean,涉及阶段9
			exposedObject = initializeBean(beanName, exposedObject, mbd);
		}

populateBean方法源码

	protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
		//如果BeanWrapper为空
		if (bw == null) {
			if (mbd.hasPropertyValues()) {
				throw new BeanCreationException(
						mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
			}
			//当mbd.hasPropertyValues()返回false
			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 (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				//如果postProcessAfterInstantiation返回false则跳过该阶段
				if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
					return;
				}
			}
		}
		//PropertyValues 
		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();
			}
			//阶段2
			for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
				PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance(), beanName);
				if (pvsToUse == null) {
					if (filteredPds == null) {
						filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
					}
					pvsToUse = bp.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);
		}

		if (pvs != null) {
			applyPropertyValues(beanName, mbd, bw, pvs);
		}
	}

阶段9:Bean初始化阶段(初始化)

包含阶段

这个阶段含有几个小阶段

  • Bean Aware接口回调

  • Bean初始化前

  • Bean初始化

  • Bean初始化后

主要原理 initializeBean 方法执行过程

AbstractAutowireCapableBeanFactory类609行

		exposedObject = initializeBean(beanName, exposedObject, mbd);

AbstractAutowireCapableBeanFactory类initializeBean方法源码如下

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		//阶段1 处理aware方法
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}
		//阶段2 applyBeanPostProcessorsBeforeInitialization
		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}
		//invokeInitMethods
		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		//applyBeanPostProcessorsAfterInitialization
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}

Bean Aware接口回调

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-aware

Aware原理

initializeBean中关于invokeAwareMethods的调用

		//阶段1 处理aware方法
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			invokeAwareMethods(beanName, bean);
		}

aware翻译为:知道的;察觉的;了解的;关注的

public interface Aware {}

虽然Aware接口什么方法都没有,但是它有非常多的实现类,org.springframework.beans.factory这个包下以Aware结尾的接口。核心代码 AbstractAutowireCapableBeanFactory 类

	private void invokeAwareMethods(String beanName, Object bean) {
		//Aware
		if (bean instanceof Aware) {
		    //BeanNameAware
			if (bean instanceof BeanNameAware) {
				((BeanNameAware) bean).setBeanName(beanName);
			}
			//BeanClassLoaderAware
			if (bean instanceof BeanClassLoaderAware) {
				ClassLoader bcl = getBeanClassLoader();
				if (bcl != null) {
					((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
				}
			}
			//BeanFactoryAware
			if (bean instanceof BeanFactoryAware) {
				((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
			}
		}
	}

Aware案例

public class AwareBean implements BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {

    @Override
    public void setBeanName(String name) {
        System.out.println("setBeanName:" + name);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println("setBeanFactory:" + beanFactory);
    }

    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println("setBeanClassLoader:" + classLoader);
    }

}

client

public class Client {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        factory.registerBeanDefinition("awareBean",
                BeanDefinitionBuilder.genericBeanDefinition(AwareBean.class).getBeanDefinition());
        factory.getBean("awareBean");
    }
}

输出

setBeanName:awareBean
setBeanClassLoader:sun.misc.Launcher$AppClassLoader@18b4aac2
setBeanFactory:org.springframework.beans.factory.support.DefaultListableBeanFactory@30c7da1e: defining beans [awareBean]; root of factory hierarchy

Bean初始化 (postProcessBeforeInitialization)

原理

initializeBean中关于applyBeanPostProcessorsBeforeInitialization的调用

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

applyBeanPostProcessorsBeforeInitialization源码

	@Override
	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;
	}

根据源码processor.postProcessBeforeInitialization这一行就是这个方法的核心。

BeanPostProcessor接口中的postProcessBeforeInitialization默认实现

	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) 
	throws BeansException {
		return bean;
	}

post 和 Process 通常翻译为:后处理,后续处理
Before 在。。之前
Initialization 初始化
所以这个方法的意思为在初始化之前进行的处理过程。

这个接口有2个实现类,比较重要:
ApplicationContextAwareProcessor 和 CommonAnnotationBeanPostProcessor

	@Override
	@Nullable
	public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
				bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
				bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware ||
				bean instanceof ApplicationStartupAware)) {
			return bean;
		}

		AccessControlContext acc = null;

		if (System.getSecurityManager() != null) {
			acc = this.applicationContext.getBeanFactory().getAccessControlContext();
		}

		if (acc != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareInterfaces(bean);
				return null;
			}, acc);
		}
		else {
			invokeAwareInterfaces(bean);
		}

		return bean;
	}

案例

Bean初始化(invokeInitMethods)

源码来自initializeBean第三部分,翻译为调用初始化方法

		//invokeInitMethods
		try {
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}

Give a bean a chance to react now all its properties are set, and a chance to know about its owning bean factory (this object). This means checking whether the bean implements InitializingBean or defines a custom init method, and invoking the necessary callback(s) if it does.

invokeInitMethods源码,翻译为调用初始化方法。

	protected void invokeInitMethods(String beanName, Object bean, @Nullable RootBeanDefinition mbd)
			throws Throwable {
		//bean是否实现InitializingBean接口
		boolean isInitializingBean = (bean instanceof InitializingBean);
		
		if (isInitializingBean && (mbd == null || !mbd.hasAnyExternallyManagedInitMethod("afterPropertiesSet"))) {
			//如果是trace级别
			if (logger.isTraceEnabled()) {
				logger.trace("Invoking afterPropertiesSet() on bean with name '" + beanName + "'");
			}
			//
			if (System.getSecurityManager() != null) {
				try {
					AccessController.doPrivileged((PrivilegedExceptionAction<Object>) () -> {
						((InitializingBean) bean).afterPropertiesSet();
						return null;
					}, getAccessControlContext());
				}
				catch (PrivilegedActionException pae) {
					throw pae.getException();
				}
			}
			else {
				//调用afterPropertiesSet
				((InitializingBean) bean).afterPropertiesSet();
			}
		}

		if (mbd != null && bean.getClass() != NullBean.class) {
			String initMethodName = mbd.getInitMethodName();
			if (StringUtils.hasLength(initMethodName) &&
					!(isInitializingBean && "afterPropertiesSet".equals(initMethodName)) &&
					!mbd.hasAnyExternallyManagedInitMethod(initMethodName)) {
				//调用	invokeCustomInitMethod
				invokeCustomInitMethod(beanName, bean, mbd);
			}
		}
	}

主要作用就是调用 afterPropertiesSet和invokeCustomInitMethod

afterPropertiesSet

public interface InitializingBean {
	//在配置文件设置之后
	void afterPropertiesSet() throws Exception;
}

invokeCustomInitMethod

	protected void invokeCustomInitMethod(String beanName, Object bean, RootBeanDefinition mbd)
			throws Throwable {

		String initMethodName = mbd.getInitMethodName();
		Assert.state(initMethodName != null, "No init method set");
		Method initMethod = (mbd.isNonPublicAccessAllowed() ?
				BeanUtils.findMethod(bean.getClass(), initMethodName) :
				ClassUtils.getMethodIfAvailable(bean.getClass(), initMethodName));

		if (initMethod == null) {
			if (mbd.isEnforceInitMethod()) {
				throw new BeanDefinitionValidationException("Could not find an init method named '" +
						initMethodName + "' on bean with name '" + beanName + "'");
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("No default init method named '" + initMethodName +
							"' found on bean with name '" + beanName + "'");
				}
				// Ignore non-existent default lifecycle methods.
				return;
			}
		}

		if (logger.isTraceEnabled()) {
			logger.trace("Invoking init method  '" + initMethodName + "' on bean with name '" + beanName + "'");
		}
		Method methodToInvoke = ClassUtils.getInterfaceMethodIfPossible(initMethod, bean.getClass());

		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				ReflectionUtils.makeAccessible(methodToInvoke);
				return null;
			});
			try {
				AccessController.doPrivileged((PrivilegedExceptionAction<Object>)
						() -> methodToInvoke.invoke(bean), getAccessControlContext());
			}
			catch (PrivilegedActionException pae) {
				InvocationTargetException ex = (InvocationTargetException) pae.getException();
				throw ex.getTargetException();
			}
		}
		else {
			try {
				ReflectionUtils.makeAccessible(methodToInvoke);
				methodToInvoke.invoke(bean);
			}
			catch (InvocationTargetException ex) {
				throw ex.getTargetException();
			}
		}
	}

Bean初始化后(postProcessAfterInitialization)

源码来自initializeBean第四部分

		if (mbd == null || !mbd.isSynthetic()) {
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

applyBeanPostProcessorsAfterInitialization方法分析

	@Override
	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
		//当前bean	
		Object result = existingBean;
		//循环使用BeanPostProcessor 来处理
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
			//使用每个处理器的postProcessAfterInitialization方法处理
			Object current = processor.postProcessAfterInitialization(result, beanName);	
			//如果处理后为null直接返回
			if (current == null) {
				return result;
			}
			result = current;
		}
		//所有的处理器处理完之后返回对象
		return result;
	}

BeanPostProcessor接口postProcessAfterInitialization方法的默认实现

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

阶段9总结

Bean初始化分为四个阶段,其中在初始化的前后分别有前后处理器处理。最前面是Aware接口的一些处理。

We recommend that you do not use the InitializingBean interface, because it unnecessarily couples the code to Spring. Alternatively, we suggest using the @PostConstruct annotation or specifying a POJO initialization method.

我们不推荐使用InitializingBean,这样会导致Spring耦合。推荐@PostConstruct。

阶段10:所有单例bean初始化完成后阶段 (初始化后)

SmartInitializingSingleton

smart 轻量
initializing 初始化
singleton 单例

Callback interface triggered at the end of the singleton pre-instantiation phase during BeanFactory bootstrap.

at the end of the singleton pre-instantiation phase 在单例预实例化阶段之后,下面我们来一个案例

public class Entity implements SmartInitializingSingleton {

    private static final Logger logger = LoggerFactory.getLogger(Entity.class);

    public Entity() {
        logger.info("entity is init ... ");
    }

    @Override
    public void afterSingletonsInstantiated() {
        logger.info("afterSingletonsInstantiated is callback");
    }
}

输出

INFO com.example.lurenjia.spring.c22.jd11.Entity - entity is init ... 
INFO com.example.lurenjia.spring.c22.jd11.Entity - afterSingletonsInstantiated is callback

通过实现SmartInitializingSingleton 在初始化后执行

DubboLoadBalancedRestTemplateAutoConfiguration 中的实践

	@Override
	public void afterSingletonsInstantiated() {
		loadBalancerInterceptorBean = retryLoadBalancerInterceptor != null
				? retryLoadBalancerInterceptor : loadBalancerInterceptor;
	}

阶段11:Bean使用阶段

使用阶段相信大家都会不再赘述。

阶段12:Bean销毁阶段

案例1 DisposableBean

public class Entity13 implements DisposableBean {

    private static final Logger logger = LoggerFactory.getLogger(Entity13.class);

    public Entity13() {
        logger.info("Entity13 is init ... ");
    }

    @Override
    public void destroy() throws Exception {
        logger.info("Entity13 is destroy ... ");
    }
}
@Configuration
public class Config13 {
    @Bean
    Entity13 entity13() {
        return new Entity13();
    }
}
public class Client1 {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config13.class);
        Entity13 bean = context.getBean(Entity13.class);
        System.out.println(bean);
        context.getBeanFactory().destroyBean(bean);
    }
}

输出

com.example.lurenjia.spring.c22.jd13.Entity13 - Entity13 is init ... 
com.example.lurenjia.spring.c22.jd13.Entity13@318ba8c8
com.example.lurenjia.spring.c22.jd13.Entity13 - Entity13 is destroy ... 

案例2 @PreDestroy

public class Entity132 {

    private static final Logger logger = LoggerFactory.getLogger(Entity13.class);

    public Entity132() {
        logger.info("Entity132 is init ... ");
    }

    @PreDestroy
    public void destroy() {
        logger.info("Entity132 is destroy ... ");
    }
}

输出

 INFO com.example.lurenjia.spring.c22.jd13.Entity13 - Entity132 is destroy ... 

使用@PreDestroy标记销毁时调用的方法。

案例3 DestructionAwareBeanPostProcessor

public class MyDestructionAwareBeanPostProcessor implements DestructionAwareBeanPostProcessor {

    private static final Logger logger = LoggerFactory.getLogger(MyDestructionAwareBeanPostProcessor.class);

    @Override
    public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
        logger.info(beanName + "is destroy");
    }
}
public class Client2 {
    public static void main(String[] args) {
        DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
        //注册BeanPostProcessor
        factory.addBeanPostProcessor(new MyDestructionAwareBeanPostProcessor());
        //向容器中注入3个单例bean
        factory.registerBeanDefinition("entity2",
                BeanDefinitionBuilder.genericBeanDefinition(Entity2.class)
                        .getBeanDefinition());

        factory.preInstantiateSingletons();
        factory.destroySingleton("entity2");
    }
}

输出

INFO com.example.lurenjia.spring.c22.jd13.d2.Entity2 - Entity2 init ... 
INFO com.example.lurenjia.spring.c22.jd13.d2.MyDestructionAwareBeanPostProcessor - entity2is destroy

总结

  • 实现DisposableBean
  • @PreDestroy标记销毁方法
  • 针对BeanDefinition实现DestructionAwareBeanPostProcessor

We recommend that you do not use the DisposableBean callback interface, because it unnecessarily couples the code to Spring.

Spring官方建议不要使用DisposableBean接口,因为会和Spring进行耦合。

Alternatively, we suggest using the @PreDestroy annotation or specifying a generic method that is supported by bean definitions.

我们建议使用@PreDestroy或者指定bean定义支持的通用方法。

重要的类和接口

AbstractApplicationContext

public abstract class AbstractApplicationContext extends DefaultResourceLoader
		implements ConfigurableApplicationContext {}

BeanDefinitionRegistry

AutowiredAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor

BeanDefinition

在这里插入图片描述
在这里插入图片描述

综合案例

Container Extension Points 容器扩展点

https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#beans-factory-extension

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值