注解 | 功能 |
---|---|
@Bean | 容器中注册组件 |
@Primary | 同类组件如果有多个,标注主组件 |
@DependsOn | 组件之间声明依赖关系 |
@Lazy | 组件懒加载(最后使用的时候才创建) |
@Scope | 声明组件的作用范围(SCOPE_PROTOTYPE,SCOPE_SINGLETON) |
@Configuration | 声明这是一个配置类,替换以前配置文件 |
@Component | @Controller、@Service、@Repository |
@Indexed | 加速注解,所有标注了 @Indexed 的组件,直接会启动快速加载 |
@Order | 数字越小优先级越高,越先工作 |
@ComponentScan | 包扫描 |
@Conditional | 条件注入 |
@Import | 导入第三方jar包中的组件,或定制批量导入组件逻辑 |
@ImportResource | 导入以前的xml配置文件,让其生效 |
@Profile | 基于多环境激活 |
@PropertySource | 外部properties配置文件和JavaBean进行绑定.结合ConfigurationProperties |
@PropertySources | @PropertySource组合注解 |
@Autowired | 自动装配 |
@Qualifier | 精确指定 |
@Value | 取值、计算机环境变量、JVM系统。xxxx。@Value(“${xx}”) |
@Lookup | 单例组件依赖非单例组件,非单例组件获取需要使用方法 |
注:@Indexed 需要引入依赖
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-context-indexerartifactId>
<optional>trueoptional>
dependency>
@Lookup用途:
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
public class Cat {}
@Component
public class Person{
// @Autowired:容器在启动时,创建Person,属性注入时创建Cat,用的cat是容器启动时首次创建那个,依赖的组件是多实例就不能Autowired
private Cat cat;
@Lookup //去容器中找。@Bean的这种方式注册的Person @Lookup不生效
public Cat getCat() {
return cat;
}
}
这儿使用了策略模式
ApplicationContext和BeanFactory什么区别?
二、ApplicationContenxt虽然是Beanfactory但是他管理bean或者说去实现那些功能并不是自己去完成的。而是靠DefaultListableBeanFactory去实现的。所以DefaultListableBeanFactory成了ApplicationContenxt组合模式中的叶子节点。所以,ApplicationContext更能说是ioc容器
BeanDefinition的设计初衷:spring可以通过xml、注解等方式将bean初始化当IOC容器中,每种方式对bean的描述都有区别,故而需要统一描述信息,BeanDefinition就诞生了
属性 | 描述 |
---|---|
beanClass | 表示一个bean的类型,比如UserService.class,Spring在创建Bean的过程中会根据此属性来实例化得到对象 |
scope | 表示一个bean的作用域,比如:scope等于singleton,该bean就是一个单例Bean; scope等 |
prototype | 该bean就是一个原型Bean |
isLazy | 表示一个bean是不是需要懒加载,原型bean的isLazy属性不起作用,懒加载的单例bean,会在第一次getBean的时候生成该bean,非懒加载的单例bean,会在Spring启动过程中直接生成好 |
dependsOn | 表示一个bean在创建之前所依赖的其他bean,在一个bean创建之前,它所依赖的这些bean得先全部创建好。 |
primary | 表示一个bean是主bean,在Spring中一个类型可以有多个bean对象,在进行依赖注入时,如果根据类型找到了多个bean,此时会判断这些bean中是否存在一个主bean,如果存在,则直接将这个bean注入给属性。 |
initMethodName | 表示一个bean的初始化方法,一个bean的生命周期过程中有一个步骤叫初始化,Spring会在这个步骤中去调用bean的初始化方法,初始化逻辑由程序员自己控制,表示程序员可以自定义逻辑对bean进行加工。 |
BeanDefinition的常见读取器:
BeanDefinition是如何存放的?
private final Map<String, BeanDefinition> beanDefinitionMap = newConcurrentHashMap<>(256)
当Bean注册完成后,会在spring容器中把扫描到的beanDefinition存放到beanDefinitionMap中,方便后续的使用。
是用于读取Spring配置文件的内容,并转换为BeanDefinition
根据beanName 判断是否包含beanDefiniation
实现 | 描述 |
---|---|
ApplicationContextAware | 通过ApplicationContext,可以访问Spring容器中缓存的的其他Bean |
EnvironmentAware | 实现该接口,项目启动时,可以获取环境变量配置 |
BeanFactoryAware | 获取加载该Bean的Bean工厂,可以动态加载Bean. |
ApplicationEventPublisherAware | ApplicationEventPublisher可以用来发布事件,结合ApplicationListener来共同使用 |
ResourceLoaderAware | 可以获取ResourceLoader,ResourceLoader可以获取classpath内所有的资源对象 |
BeanNameAware | 注入Bean的名字 |
ServletContextAware | 1. 可以获得ServletContext,ServletContext被称为域对象,是一个全局存储信息的空间。 2. 服务器会为每一个工程创建一个ServletContext对象,工程内所有Servlet都会共享这个Servlet上下文。 3. 应用被移除或服务器关闭时,才会被销毁,可以在整个应用过程中共享数据变量。 |
实现想要Aware接口就能拿到相应接口,如:
@Component
public class Person implements ApplicationContextAware, MessageSourceAware {
// @Autowired
ApplicationContext context; //可以要到ioc容器
MessageSource messageSource;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//利用回调机制,把ioc容器传入
this.context = applicationContext;
}
@Override
public void setMessageSource(MessageSource messageSource) {
this.messageSource = messageSource;
}
}
name=“Zsth1”>
// 会调用父类实例化一个beanFactory
public AnnotationConfigApplicationContext(Class>... componentClasses) {
// this()断点调试技巧,将断掉打在RootBeanDefinition和AbstractBeanDefinition的构造方法中
this();
register(componentClasses);
refresh(); //容器完整刷新(创建出所有组件,组织好所有功能)
}
AnnotationConfigApplicationContext父类->GenericApplicationContext父类->AbstractApplicationContext父类->DefaultResourceLoader
在构造中调用到父类GenericApplicationContext构造
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
// 初始化reader
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
// 初始化scanner
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
// 注册相关BeanDefinition
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
registerAnnotationConfigProcessors(this.registry):注册相关BeanDefinition
ClassPathBeanDefinitionScanner:BeanDefinition扫描注册
通过AnnotatedBeanDefinitionReder注册配置类,将主配置类解析为BeanDefinition加入注册容器。后续通过ConfigurationClassPostProcessor解析加入容器
@Override //容器刷新的十二大步。模板模式
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
//1. 准备上下文环境 Prepare this context for refreshing.
prepareRefresh();
//2. 工厂创建:BeanFactory第一次开始创建的时候,有xml解析逻辑。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//3. 给容器中注册了环境信息作为单实例Bean方便后续自动装配;放了一些后置处理器处理(监听、xxAware功能) Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
//4. 留给子类的模板方法,允许子类继续对工厂执行一些处理; Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
//5. 【大核心】工厂增强:执行所有的BeanFactory后置增强器;利用BeanFactory后置增强器对工厂进行修改或者增强,配置类会在这里进行解析。 Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
//6. 【核心】注册所有的Bean的后置处理器 Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
//7. 初始化国际化功能 Initialize message source for this context.
initMessageSource();
//8. 初始化事件多播功能(事件派发) Initialize event multicaster for this context.
initApplicationEventMulticaster();
//9. 初始化特定上下文子类中的其他特殊bean. Initialize other special beans in specific context subclasses.
onRefresh();
//10. 注册监听器,从容器中获取所有的ApplicationListener; Check for listener beans and register them.
registerListeners();
//实例化所有剩余的(非惰性初始化)单例 Instantiate all remaining (non-lazy-init) singletons.
//11. 【大核心】bean创建;完成 BeanFactory 初始化。(工厂里面所有的组件都好了)
finishBeanFactoryInitialization(beanFactory);
//12. 发布事件 Last step: publish corresponding event.
finishRefresh();
}
。。。
}
}
4. invokeBeanFactoryPostProcessors执行Bean工厂后置处理【重要,关系SpringBoot自动装配原理等】
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, ApplicationStartupAware, BeanClassLoaderAware, EnvironmentAware {
初始化MessageSource组件(做国际化功能;消息绑定,消息解析),这个接口提供了消息处理功能。主要用于国际化/i18n。
在Spring容器中初始化事件广播器,事件广播器用于事件的发布。默认实现:SimpleApplicationEventMulticaster,可重新注入一个名称必须为applicationEventMulticaster
一个模板方法,不同的Spring容器做不同的事情。如SpringBoot中web容器启动tomccat
注册应用的监听器。就是注册实现了ApplicationListener接口的监听器bean,这些监听器是注册到ApplicationEventMulticaster中的。这不会影响到其它监听器bean。在注册完以后,还会将其前期的事件发布给相匹配的监听器。
public static void main(String[] args) {
// 入口
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("beans2.xml");
Cat bean = context.getBean(Cat.class);
System.out.println(bean);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh(); //刷新容器
}
}
@Override //容器刷新的十二大步。模板模式
public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
//准备上下文环境 Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 工厂创建:BeanFactory第一次开始创建的时候,有xml解析逻辑。
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
.....
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory(); //刷新整个BeanFactory,注解模式下就是准备工厂,设置工厂id;xml模式下会解析xml
return getBeanFactory(); // 创建BenaFactory
}
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
//创建保存所有Bean定义信息的档案馆
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
// 加载bean定义信息,说明档案馆BeanDefinitionRegistry创建好了
// 入参为beanFactory,猜测beanFactory具备BeanDefinitionRegistry功能
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
....
}
loadBeanDefinitions(beanFactory);入参为beanFactory,猜测beanFactory具备BeanDefinitionRegistry功能
...
// 逐个节点解析
loadBeanDefinitions(beanFactory);
...
逐个节点解析(非核心)
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
initBeanDefinitionReader(beanDefinitionReader);
// 核心
loadBeanDefinitions(beanDefinitionReader);
}
最后进入:XmlBeanDefinitionReader#loadBeanDefinitions(EncodedResource)
简单概述:就是通过Resource+ResourceLoader+dom解析,将xml中的bean标签解析为BeanDefinition
查找入口断点打在:
@Component
public class Person implements ApplicationContextAware {
// @Autowired
ApplicationContext context; //可以要到ioc容器
MessageSource messageSource;
public Person(){
System.out.println("person创建...."); // 断点
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
//利用回调机制,把ioc容器传入
this.context = applicationContext; // 断点
}
}
堆栈信息发现关键调用顺序:
public Object getBean(String name) throws BeansException {
return doGetBean(name, null, null, false);
}
// 创建bean的实例;Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try { return createBean(beanName, mbd, args); } //创建bean对象的实例
...
});
//看当前bean是否是FactoryBean
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
try {
//会调用lamda表达式的内容,真正创建对象
singletonObject = singletonFactory.getObject();
newSingleton = true;
}
AbstractBeanFactory#doGetBean
// 创建bean的实例;Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, /**lamda表达式进入*/() -> {
try { return createBean(beanName, mbd, args); } //创建bean对象的实例
....
}
}
进入
try {
//Spring真正自己创建对象
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
// 初始化bean实例 Initialize the bean instance.
Object exposedObject = bean;
try {
populateBean(beanName, mbd, instanceWrapper); //给创建好的对象每个属性进行赋值,@Autowired发生在这里
exposedObject = initializeBean(beanName, exposedObject, mbd);//初始化bean
}
if (mbd == null || !mbd.isSynthetic()) {
//执行后置处理器的BeforeInitialization方法
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName) throws BeansException {
Object result = existingBean;
// 遍历所有bean后置处理器,执行后置处理器的postProcessBeforeInitialization方法
for (BeanPostProcessor processor : getBeanPostProcessors()) {
Object current = processor.postProcessBeforeInitialization(result, beanName);
if (current == null) { //不管null的东西
return result;
}
result = current;
}
return result;
}
ApplicationContextAwareProcessor为aware接口的后置处理器,最后会执行到ApplicationContextAwareProcessor.postProcessBeforeInitialization
invokeAwareInterfaces(bean); //执行aware接口规定的方法
private void invokeAwareInterfaces(Object bean) {
....
if (bean instanceof ApplicationContextAware) {
// 执行Aware接口回到
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
通过ApplicationContextAware接口,applicationContext属性注入分析,我们知道是通过后置处理器ApplicationContextAwareProcessor最后为applicationContext回调赋值。
思考:@Autowired原理,猜测应该也是有相应的后置处理器进行属性注入。
通过断点跟踪堆栈,分析@Autowired
@Autowired //去发现一下.....
public void setCat(Cat cat) {
this.cat = cat;
}
public static void main(String[] args) {
ApplicationContext applicationContext =
new AnnotationConfigApplicationContext(MainConfig.class);
Person bean = applicationContext.getBean(Person.class);
}}
回溯堆栈信息发现入口:发现@Autowired对应的后置处理器是AutowiredAnnotationBeanPostProcessor
AbstractAutowireCapableBeanFactory#populateBean
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
...
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
...
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; //封装了当前bean的所有属性名和值,可以由后置处理器处理得到
}
}
AutowiredAnnotationBeanPostProcessor#postProcessProperties
@Override
public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) {
//找到自动装配的元信息
InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass(), pvs);
try {
// 元数据注入,最后会通过反射将属性值注入
metadata.inject(bean, beanName, pvs);
}
...
return pvs;
}
总结:
核心容器源码-组件创建流程
后置处理器的创建先不做讨论,在beanFactory创建后执行prepareBeanFactory(beanFactory)会初始化一些后置处理器。
后置处理器调用时机参考:
后置处理介绍参考:
解析BeanDefinition,通过反射创建bean,创建bean的过程交给了spring容器
早期单例池【二级缓存】中bean存在依赖,会挨个创建依赖bean进行注入
属性注入源码: AbstractAutowireCapableBeanFactory#populateBean
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);
if (resolvedAutowireMode == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs); // 会调用到getBean获取注入的实际对象
}
if (resolvedAutowireMode == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
pvs = newPvs;
}
....
if (pvs != null) { //把以前处理好的PropertyValues给bean里面设置一下。主要是上面步骤没有给bean里面设置的属性
applyPropertyValues(beanName, mbd, bw, pvs); //xml版的所有配置会来到这里给属性赋值
}
DefaultSingletonBeanRegistry#getSingleton()
@Nullable //双检查锁
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
// 快速检查现有实例,没有完整的单例锁 Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName); //一级缓存:先检查单例缓存池,获取当前对象
//如果当前bean正在创建过程中,而且缓存中没有则继续
if (singletonObject == null && isSingletonCurrentlyInCreation(beanName)) {
singletonObject = this.earlySingletonObjects.get(beanName); //二级
if (singletonObject == null && allowEarlyReference) {
synchronized (this.singletonObjects) {
// Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); //三级
if (singletonFactory != null) {
singletonObject = singletonFactory.getObject();
this.earlySingletonObjects.put(beanName, singletonObject);
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
核心实现:ConfigurationClassPostProcess【配置类后置处理器】工厂准备好后就得解析配置类的信息
执行时机:PostProcessorRegistrationDelegate#invokeBeanDefinitionRegistryPostProcessors
ConfigurationClassPostProcess解析配置类
@Override //把配置类中所有bean的定义信息导入进来
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
...
processConfigBeanDefinitions(registry); //处理配置的BeanDefinition信息
}
PostProcessorRegistrationDelegate原理:
//执行工厂的后置处理器
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
...
// 首先:从工厂中获取所有的实现了 PriorityOrdered 接口的 BeanDefinitionRegistryPostProcessor; First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); //拿到系统中每一个组件的BD信息,进行类型对比,是否匹配指定的类型
...//下面利用优先级排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
...
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); //执行这些BeanDefinitionRegistryPostProcessor的
currentRegistryProcessors.clear();
// 接下来,获取所有实现了Ordered接口的 BeanDefinitionRegistryPostProcessor Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 【核心】invokeBeanDefinitionRegistryPostProcessors方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup()); //执行
currentRegistryProcessors.clear(); //防止重复执行
// 最后,我们自定义的一般没有任何优先级和排序接口 Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
...
// 接下来,再来执行postProcessBeanFactory的回调, Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
}
private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry, ApplicationStartup applicationStartup) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanDefRegistry = applicationStartup.start("spring.context.beandef-registry.post-process").tag("postProcessor", postProcessor::toString);
//核心,配置类的后置处理器会在此解析配置类
postProcessor.postProcessBeanDefinitionRegistry(registry);
postProcessBeanDefRegistry.end();
}
}
执行postProcessBeanFactory的回调【执行后置处理方法】
private static void invokeBeanFactoryPostProcessors(Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
// 此处重点关注:ConfigurationClassPostProcess
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
StartupStep postProcessBeanFactory = beanFactory.getApplicationStartup().start("spring.context.bean-factory.post-process").tag("postProcessor", postProcessor::toString);
// 执行后置处理器回调
postProcessor.postProcessBeanFactory(beanFactory);
postProcessBeanFactory.end();
}
}
注冊后置处理器
作用:预测bean的类型,最后一次改变组件类型
执行时机:
执行时机:AbstractAutowireCapableBeanFactory#createBean#resolveBeforeInstantiation,bean实例化前
//初始化之前进行后置处理,Spring留给我们给这个组件创建对象的回调。
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessBeforeInstantiation=>"+beanClass+"--"+beanName); //if(class.isAssFrom(Cat.class)){return new Dog()}
return null; //如果我们自己创建了对象返回。Spring则不会帮我们创建对象,用我们自己创建的对象? 我们创建的这个对象,Spring会保存单实例?还是每次getBean都调到我们这里创建一个新的?
}
作用:返回我们要使用的构造器候选列表
执行时机:AbstractAutowireCapableBeanFactory#createBeanInstance:bean实例化时
作用:
执行时机:
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
System.out.println("MyInstantiationAwareBeanPostProcessor...postProcessAfterInstantiation=>"+bean+"--"+beanName); //提前改变一些Spring不管的bean里面的属性
return true; //返回false则bean的赋值全部结束
}
作用:
执行时机:AbstractAutowireCapableBeanFactory#populateBean
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
if (!bp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
return; // 中断springbean的赋值
}
}
}
作用:解析自定义注解进行属性值注入;pvs 封装了所有的属性信息
执行时机:
执行时机:
执行时机:AbstractAutowireCapableBeanFactory#initializeBean(Object, RootBeanDefinition)
执行时机:AbstractAutowireCapableBeanFactory#initializeBean(Object, RootBeanDefinition)
执行时机:AbstractAutowireCapableBeanFactory#initializeBean(Object, RootBeanDefinition)
执行时机:AbstractAutowireCapableBeanFactory#createBean(String, RootBeanDefinition, Object[])
参考:
核心:提前暴露未完全创建的Bean
三级缓存:
public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
//【一级缓存】(单例池)享元模式的单例。用于保存实例化、注入、初始化完成的bean实例
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
//【三级缓存】(单例工厂池)三级缓存用于保存bean创建工厂,以便后面扩展有机会创建代理对象
private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>(16);
//【二级缓存】(早期单例池)二级缓存,存放早期暴露出来的 Bean 对象,Bean 的生命周期未结束(属性还未填充完)
private final Map<String, Object> earlySingletonObjects = new ConcurrentHashMap<>(16);
// 一组已注册的单实例,按注册顺序包含bean名称 Set of registered singletons, containing the bean names in registration order.
private final Set<String> registeredSingletons = new LinkedHashSet<>(256);
//当前正在创建的bean的名称 Names of beans that are currently in creation.
private final Set<String> singletonsCurrentlyInCreation =
Collections.newSetFromMap(new ConcurrentHashMap<>(16));
}
A依赖B,B依赖A:
@Nullable //双检查锁
protected Object getSingleton(String beanName, boolean allowEarlyReference) {
//先检查单例缓存池,获取当前对象 Quick check for existing instance without full singleton lock
Object singletonObject = this.singletonObjects.get(beanName); //一级缓存
//如果当前bean正在创建过程中,而且缓存中没有则继续
if (singletonObject == null // 一级缓存没有
&& isSingletonCurrentlyInCreation(beanName) /*是否正在创建*/) {
// 从【二级缓存】早期单例对象的缓存中获取
singletonObject = this.earlySingletonObjects.get(beanName); //二级
if (singletonObject == null && allowEarlyReference /*是否应创建早期引用,解决循环依赖*/) {
synchronized (this.singletonObjects) { // 锁定一级缓存
// 在完全单例锁中一致地创建早期引用 Consistent creation of early reference within full singleton lock
singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = this.earlySingletonObjects.get(beanName);
if (singletonObject == null) {
// 【三级缓存】(单例工厂池)
ObjectFactory<?> singletonFactory = this.singletonFactories.get(beanName); //三级
if (singletonFactory != null) {
// 单例对象
singletonObject = singletonFactory.getObject();
// 放入【二级缓存】早期单例对象的缓存
this.earlySingletonObjects.put(beanName, singletonObject);
// 从【三级缓存】(单例工厂池)移除
this.singletonFactories.remove(beanName);
}
}
}
}
}
}
return singletonObject;
}
4. 返回A,最后B完成A注入
5. initializeBean完成B的初始化
AbstractAutowireCapableBeanFactory#doCreateBean创建B使用后置处理器处理属性
//使用后置处理器处理属性
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; //封装了当前bean的所有属性名和值,可以由后置处理器处理得到
}
DefaultListableBeanFactory#doResolveDependency
if (instanceCandidate instanceof Class) {
instanceCandidate = descriptor.resolveCandidate(autowiredBeanName, type, this);
}
Object result = instanceCandidate;
DependencyDescriptor#resolveCandidate获取A
public Object resolveCandidate(String beanName, Class<?> requiredType, BeanFactory beanFactory)
throws BeansException {
return beanFactory.getBean(beanName); //所有自动注入的属性都是beanFactory.getBean(beanName);的结果
}
入口:@EnableAspectJAutoProxy
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {}
ConfiqurationClassPostProcessor后置处理器会解析配置类中的@Import导入AspectJAutoProxyRegistrar
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
//注册切面的基于注解的自动代理创建器
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
....
}
// 最后调用到,注册AnnotationAwareAspectJAutoProxyCreator
public static BeanDefinition registerAspectJAnnotationAutoProxyCreatorIfNecessary(
BeanDefinitionRegistry registry, @Nullable Object source) {
return registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
}
AnnotationAwareAspectJAutoProxyCreator是自动代理创建器。容器刷新中registerBeanPostProcessors(beanFactory)注册后置处理器,会在Bean创建的时候发现所有的Advisor并进行拦截代理。