1.1 spring bean是如何创建的
spring中bean都是由spring框架来通过反射创建的;设想以下,如果需要自己实现一个bean管理的框架你会怎么设计?
- BeanFactory :bean的创建工厂
- IOC容器:bean创建后实例存储位置
- BeanDefinition:bean的定义信息,告诉框架你要创建的类是什么、bean名称是什么、成员变量、初始化方法等等
- bean的定义信息需要从配置文件或则java config中进行加载,则需要对应的BeanDefinitionReader 从文件中进行获取,根据不同的文件类型加载不同的Reader,生成统一的BeanDefinition
- 循环依赖和三级缓存
- 如何实现对应的后置处理,当我们想在bean实例创建前和创建后、及其创建需要执行的初始化方法时,该怎么做?需要给对应的实例属性赋值怎么做?
- AOP怎么设计:对应的前置处理器和后置处理器怎么设计?
- BeanPostProcessor:后置加载处理器,在bean实例化后可以进行一系列的初始化、属性赋值、执行方法的代理等等
- Bean有对应的PostProcessor,那工厂类也可以设计对应的PostProcessor,可以进行一些工厂类的包装以及一些对应的event的监听和发布等等
Spring5源码解析
Bean工厂实现应该尽可能地支持标准Bean生命周期接口。全套初始化方法及其标准顺序为:
- BeanNameAware’s {@code setBeanName} (bean名称的包装,设置bean的名称)
- BeanClassLoaderAware’s {@code setBeanClassLoader} (bean类加载器的包装,设置bean classLoader)
- BeanFactoryAware’s {@code setBeanFactory} (bean工厂类的包装,设置bean的工厂类)
- EnvironmentAware’s {@code setEnvironment} (环境类包装,设置环境变量)
- EmbeddedValueResolverAware’s {@code setEmbeddedValueResolver} (嵌入值的处理包装,设置嵌入值处理器)
- ResourceLoaderAware’s {@code setResourceLoader}----仅适用于在应用程序上下文中运行时 (资源加载包装,设置资源加载器)
- ApplicationEventPublisherAware’s {@code setApplicationEventPublisher}----仅适用于在应用程序上下文中运行时(应用事件发布包装,设置应用事件的发布者)
- MessageSourceAware’s {@code setMessageSource}----仅适用于在应用程序上下文中运行时(国际化包装)
- ApplicationContextAware’s {@code setApplicationContext}----仅适用于在应用程序上下文中运行时(应用上下文包装,设置应用上下文)
- ServletContextAware’s {@code setServletContext}----仅适用于在web应用程序上下文中运行时(servlet上下文包装)
- {@code postProcessBeforeInitialization} methods of BeanPostProcessors (bean初始化之前的后置处理器)
- InitializingBean’s {@code afterPropertiesSet}(初始化bean,属性填充之后)
- a custom init-method definition (自定义的init方法)
- {@code postProcessAfterInitialization} methods of BeanPostProcessors(bean初始化之后的后置处理器);
上面阐述了beanfactory工厂化的实现bean生命周期的接口有哪些及其顺序;下面展示对应的应用上下文 refresh方法源码,查看时如何对应上面的顺序;源码如下:
- AbstractApplicationContext.refresh方法
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 设置启动时间,active标识、上下文环境中的任何占位符属性源
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 告诉子类刷新内部beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 上下文加载beanFactory ------step 3
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses
// 在标准初始化之后修改应用程序上下文的内部bean工厂。所有bean定义都已加载,
// 但还没有实例化bean。这允许在某些ApplicationContext实现中注册特殊的 beanpostprocessor等。
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 实例化和调用所有注册的BeanFactoryPostProcessor bean,如果给定了显式的顺序。
// 必须在单例实例化之前调用。
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 实例化和注册所有BeanPostProcessor bean,如果给定的话,遵循显式顺序。
// 必须在应用程序bean的任何实例化之前调用。
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 设置国际化 ------step8
initMessageSource();
// Initialize event multicaster for this context.
// 设置应用上下文事件发布器 step7
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
// 添加将ApplicationListener实现为侦听器的bean。
// 不会影响其他侦听器,可以在不使用bean的情况下添加其他侦听器。
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 完成这个上下文的bean工厂的初始化,初始化所有剩余的单例bean。
// 实例化所有剩余的(非延迟-init)单例。
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 调用LifecycleProcessor来完成这个上下文的刷新:onRefresh()方法并发布 ContextRefreshedEvent
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// 销毁创建的实例
destroyBeans();
// Reset 'active' flag.
// 重置 active 标识
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
// 重置spring中的缓存
resetCommonCaches();
}
}
}
spring bean循环依赖
什么是循环依赖:beanA ->注入beanB ;beanB -> 注入beanA
循环依赖发生的前提:bean创建的scope为单例,采用set方式注入bean对象;
三级缓存: DefaultSingletonBeanRegistry 中:
/** Cache of singleton objects: bean name to bean instance. */
// 一级缓存
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
/** Cache of singleton factories: bean name to ObjectFactory. */、
// 三级缓存
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
/** Cache of early singleton objects: bean name to bean instance. */
// 二级缓存
private final Map<String, Object> earlySingletonObjects = new HashMap<>(16);
循环依赖解决逻辑:
如图:能够使用对应的二级缓存解决对应的循环依赖问题;
但是当beanA或beanB如果是代理类(AOP)代理了,上面还适用吗?当然是不行的;
首先AOP是是实现在BeanPostProcessor中的,BeanPostProcessor是在bean 实例化之前调用,如果要实例化beanA,那么就应该实例化beanA被代理后的对象bean(jdk/cglib),否则一个bean名称出现了不同效果的实例,会出现意想不到的结果。
那么该如何解决代理类的实例化呢?那就是三级缓存;
首先查看bean创建的代码执行过程:
- resfresh—>AbstractApplicationContext.finishBeanFactoryInitialization(beanFactory)
- beanFactory.preInsantiateSingletons()
- DefaultListableBeanFactory.preInstantiateSingletons()
- AbstractBeanFactory.doGetBean
- DefaultSingletonBeanRegistry.getSingleton(String beanName, boolean allowEarlyReference)
- DefaultSingletonBeanRegistry.getSingleton(String beanName, ObjectFactory<?> singletonFactory)—>singletonFactory.getObject()
- AbstractAutowireCapableBeanFactory.createBean()—》doCreateBean—>反射创建实例
- AbstractAutowireCapableBeanFactory.populateBean
- AbstractAutowireCapableBeanFactory.initializeBean(beanName, exposedObject, mbd)–>applyBeanPostProcessorsBeforeInitialization–>invokeInitMethods—>applyBeanPostProcessorsAfterInitialization
举例说明:
A 注入B,B注入A,
1.实例化A开始
1.1 实例化A
1.1.1 生成实例A,存入三级缓存,删除二级缓存
1.1.2 填充B
1.1.2.1 实例化B
1.1.2.1.1 生成实例B,存入三级缓存,删除二级缓存
1.1.2.1.2 填充A ->
- 从三级缓存中取出A,执行createBean,存入二级缓存,删除三级缓存
- 填充A结束
- B初始化等操作
1.1.2.2 B存入一级缓存,删除二三缓存–填充B结束
1.2A 初始化等操作, A存入一级缓存,删除二三级缓存
/**
* Return the (raw) singleton object registered under the given name.
* <p>Checks already instantiated singletons and also allows for an early
* reference to a currently created singleton (resolving a circular reference).
* @param beanName the name of the bean to look for
* @param allowEarlyReference whether early references should be created or not
* @return the registered singleton object, or {@code null} if none found
*/
@Nullable
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
synchronized (this.singletonObjects) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null && allowEarlyReference) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName);
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
return singletonObject;
}
1.2 spring bean 依赖注入的几种方式
1.3 spring bean 的生命周期
bean的生命周期从bean的创建可以看到,下面展示对应的执行顺序图,如下:
下面用代码实践来验证上面的执行顺序:
<?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="orderService" class="com.lww.spring.service.OrderServiceImpl" init-method="initOrder" destroy-method="destroyOrder">
<property name="id" value="1"></property>
<property name="orderNo" value="NUM-001"></property>
</bean>
<bean id="customBeanFactoryProcessor" class="com.lww.spring.postProcess.CustomBeanFactoryProcessor"></bean>
<bean id="customBeanPostProcessor" class="com.lww.spring.postProcess.CustomBeanPostProcessor"></bean>
<bean id="cusInstantiationAwareBeanPostProcessorAdapter" class="com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter"></bean>
</beans>
package com.lww.spring.service;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import java.util.logging.Logger;
public class OrderServiceImpl implements OrderService, BeanNameAware , BeanFactoryAware, InitializingBean, DisposableBean {
private final Logger logger = Logger.getLogger("OrderService");
private String id;
private String orderNo;
private String orderName;
private String je;
public OrderServiceImpl(){
logger.info("step6:----创建bean的实例----------");
}
@Override
public void getInfo() {
logger.info("id:"+id+",orderNo:"+orderNo+",orderName:"+orderName+",je:"+je);
}
public void initOrder(){
logger.info("step13:----执行init-method:OrderServiceImpl-----initOrder()----------");
}
public void destroyOrder(){
logger.info("last step:----执行destroy-method:OrderServiceImpl-----destroyOrder()----------");
}
@Override
public String addOrder(String info) {
logger.info("addOrder:"+info);
return "success";
}
@Override
public void setBeanName(String name) {
logger.info("step9:----执行BeanNameAware-----setBeanName()----------");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
logger.info("step10:----执行BeanFactoryAware-----setBeanFactory()----------");
}
@Override
public void afterPropertiesSet() throws Exception {
logger.info("step12:----执行InitializingBean-----afterPropertiesSet()----------");
}
@Override
public void destroy() throws Exception {
logger.info("销毁容器----执行DisposableBean-----destroy()----------");
}
public String getId() {
return id;
}
public void setId(String id) {
logger.info("step8:----属性填充(id)----------");
this.id = id;
}
public String getOrderNo() {
return orderNo;
}
public void setOrderNo(String orderNo) {
logger.info("step8:----属性填充(orderNo)----------");
this.orderNo = orderNo;
}
public String getOrderName() {
return orderName;
}
public void setOrderName(String orderName) {
this.orderName = orderName;
}
public String getJe() {
return je;
}
public void setJe(String je) {
this.je = je;
}
}
package com.lww.spring.postProcess;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import java.util.logging.Logger;
/**
* BeanFactoryPostProcessor 实现类,容器初始化第一步:实例化 step2: 执行postProcessBeanFactory
*/
public class CustomBeanFactoryProcessor implements BeanFactoryPostProcessor {
private static final Logger logger = Logger.getLogger("CustomBeanFactoryProcessor");
public CustomBeanFactoryProcessor(){
logger.info("------step 1: 实例化eanFactoryPostProcessor");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
logger.info("------step 2: 执行BeanFactoryPostProcessor.postProcessBeanFactory");
}
}
package com.lww.spring.postProcess;
import com.lww.spring.service.OrderServiceImpl;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
import java.util.logging.Logger;
/**
* BeanPostProcessor step3 实例化BeanPostProcessor ;step 11: 执行postProcessBeforeInitialization;
* step 14 :执行postProcessAfterInitialization
*/
public class CustomBeanPostProcessor implements BeanPostProcessor {
private static final Logger logger = Logger.getLogger("CustomBeanPostProcessor");
public CustomBeanPostProcessor(){
logger.info("------step 3: 实例化BeanPostProcessor");
}
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
logger.info("------step 11: 执行BeanPostProcessor.postProcessBeforeInitialization");
if(beanName.equals("orderService")){
OrderServiceImpl orderService = (OrderServiceImpl) bean;
logger.info("--------------------设置属性orderName");
orderService.setOrderName("订单名称");
logger.info("--------------------设置属性id为2");
orderService.setId("2");
}
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
logger.info("------step 14: 执行BeanPostProcessor.postProcessAfterInitialization");
if(beanName.equals("orderService")){
OrderServiceImpl orderService = (OrderServiceImpl) bean;
orderService.getInfo();
logger.info("--------------------设置属性je为100");
orderService.setJe("100.00");
}
return bean;
}
}
package com.lww.spring.postProcess;
import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyValues;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter;
import java.util.logging.Logger;
/**
* step4 实例化InstantiationAwareBeanPostProcessorAdapter
* step5 执行postProcessBeforeInstantiation
* step7 执行postProcessProperties
* step14 执行postProcessAfterInitialization
*/
public class CusInstantiationAwareBeanPostProcessorAdapter extends InstantiationAwareBeanPostProcessorAdapter {
private static final Logger logger = Logger.getLogger("CusInstantiationAwareBeanPostProcessorAdapter");
public CusInstantiationAwareBeanPostProcessorAdapter(){
logger.info("------step 4: 实例化InstantiationAwareBeanPostProcessorAdapter");
}
@Override
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
logger.info("------step 5: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation");
return super.postProcessBeforeInstantiation(beanClass, beanName);
}
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
logger.info("------step 7: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessProperties");
return super.postProcessProperties(pvs, bean, beanName);
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
logger.info("------ step15: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInitialization");
return super.postProcessAfterInitialization(bean, beanName);
}
}
package com.lww.spring;
import com.lww.spring.service.OrderService;
import com.lww.spring.service.UserService;
import com.lww.spring.service.UserServiceImpl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.util.logging.Logger;
public class CustomSpApplication {
private static final Logger logger = Logger.getLogger("CustomSpApplication");
public static void main(String[] args) {
logger.info("-------------初始化容器-------------");
ClassPathXmlApplicationContext applicationContext =
new ClassPathXmlApplicationContext("spring.xml");
OrderService orderService = (OrderService) applicationContext.getBean("orderService");
orderService.getInfo();
logger.info("-------------开始销毁容器-------------");
applicationContext.registerShutdownHook();
}
}
// 控制台打印如下:
八月 27, 2020 10:47:20 下午 com.lww.spring.CustomSpApplication main
信息: -------------初始化容器-------------
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanFactoryProcessor <init>
信息: ------step 1: 实例化eanFactoryPostProcessor
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanFactoryProcessor postProcessBeanFactory
信息: ------step 2: 执行BeanFactoryPostProcessor.postProcessBeanFactory
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor <init>
信息: ------step 3: 实例化BeanPostProcessor
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter <init>
信息: ------step 4: 实例化InstantiationAwareBeanPostProcessorAdapter
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter postProcessBeforeInstantiation
信息: ------step 5: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessBeforeInstantiation
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl <init>
信息: step6:----创建bean的实例----------
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter postProcessProperties
信息: ------step 7: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessProperties
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setId
信息: step8:----属性填充(id)----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setOrderNo
信息: step8:----属性填充(orderNo)----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setBeanName
信息: step9:----执行BeanNameAware-----setBeanName()----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setBeanFactory
信息: step10:----执行BeanFactoryAware-----setBeanFactory()----------
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessBeforeInitialization
信息: ------step 11: 执行BeanPostProcessor.postProcessBeforeInitialization
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessBeforeInitialization
信息: --------------------设置属性orderName
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessBeforeInitialization
信息: --------------------设置属性id为2
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl setId
信息: step8:----属性填充(id)----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl afterPropertiesSet
信息: step12:----执行InitializingBean-----afterPropertiesSet()----------
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl initOrder
信息: step13:----执行init-method:OrderServiceImpl-----initOrder()----------
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessAfterInitialization
信息: ------step 14: 执行BeanPostProcessor.postProcessAfterInitialization
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl getInfo
信息: id:2,orderNo:NUM-001,orderName:订单名称,je:null
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CustomBeanPostProcessor postProcessAfterInitialization
信息: --------------------设置属性je为100
八月 27, 2020 10:47:21 下午 com.lww.spring.postProcess.CusInstantiationAwareBeanPostProcessorAdapter postProcessAfterInitialization
信息: ------ step15: 执行InstantiationAwareBeanPostProcessorAdapter.postProcessAfterInitialization
八月 27, 2020 10:47:21 下午 com.lww.spring.service.OrderServiceImpl getInfo
信息: id:2,orderNo:NUM-001,orderName:订单名称,je:100.00
八月 27, 2020 10:47:21 下午 com.lww.spring.CustomSpApplication main
信息: -------------开始销毁容器-------------
销毁容器----执行DisposableBean-----destroy()----------
last step:----执行destroy-method:OrderServiceImpl-----destroyOrder()----------