Spring Boot + Framework

Spring Boot + Framework

————《Spring Framework》————

第一部分 Spring Context

1.1 ApplicationContextInitializer

初始化 ApplicationContext

1
2
3
4
5
6
7
8
9
10
@FunctionalInterface
public interface ApplicationContextInitializer<C extends ConfigurableApplicationContext> {

/**
* Initialize the given application context.
* @param applicationContext the application to configure
*/
void initialize(C applicationContext);

}

1.2 AbstractApplicationContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {

/**
* Name of the MessageSource bean in the factory.
* If none is supplied, message resolution is delegated to the parent.
* @see MessageSource
*/
public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource";

/**
* Name of the LifecycleProcessor bean in the factory.
* If none is supplied, a DefaultLifecycleProcessor is used.
* @see org.springframework.context.LifecycleProcessor
* @see org.springframework.context.support.DefaultLifecycleProcessor
*/
public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor";

/**
* Name of the ApplicationEventMulticaster bean in the factory.
* If none is supplied, a default SimpleApplicationEventMulticaster is used.
* @see org.springframework.context.event.ApplicationEventMulticaster
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster";


static {
// Eagerly load the ContextClosedEvent class to avoid weird classloader issues
// on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.)
ContextClosedEvent.class.getName();
}


/** Logger used by this class. Available to subclasses. */
protected final Log logger = LogFactory.getLog(getClass());

/** Unique id for this context, if any. */
private String id = ObjectUtils.identityToString(this);

/** Display name. */
private String displayName = ObjectUtils.identityToString(this);

/** Parent context. */
@Nullable
private ApplicationContext parent;

/** Environment used by this context. */
@Nullable
private ConfigurableEnvironment environment;

/** BeanFactoryPostProcessors to apply on refresh. */
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

/** System time in milliseconds when this context started. */
private long startupDate;

/** Flag that indicates whether this context is currently active. */
private final AtomicBoolean active = new AtomicBoolean();

/** Flag that indicates whether this context has been closed already. */
private final AtomicBoolean closed = new AtomicBoolean();

/** Synchronization monitor for the "refresh" and "destroy". */
private final Object startupShutdownMonitor = new Object();

/** Reference to the JVM shutdown hook, if registered. */
@Nullable
private Thread shutdownHook;

/** ResourcePatternResolver used by this context. */
private final ResourcePatternResolver resourcePatternResolver;

/** LifecycleProcessor for managing the lifecycle of beans within this context. */
@Nullable
private LifecycleProcessor lifecycleProcessor;

/** MessageSource we delegate our implementation of this interface to. */
@Nullable
private MessageSource messageSource;

/** Helper class used in event publishing. */
@Nullable
private ApplicationEventMulticaster applicationEventMulticaster;

/** Application startup metrics. **/
private ApplicationStartup applicationStartup = ApplicationStartup.DEFAULT;

/** Statically specified listeners. */
private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

/** Local listeners registered before refresh. */
@Nullable
private Set<ApplicationListener<?>> earlyApplicationListeners;

/** ApplicationEvents published before the multicaster setup. */
@Nullable
private Set<ApplicationEvent> earlyApplicationEvents;

refresh

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
  // spring 初始化最重要的方法
@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.
// 调用实习 customizeBeanFactory 和 loadBeanDefinition
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// 三、Prepare the bean factory for use in this context.
// 一些需要提前加载的 Bean 注入(或者忽略)到 Spring 容器中
prepareBeanFactory(beanFactory);

try {
// 四、Allows post-processing of the bean factory in context subclasses.
// 四、运行 注册BeanFactoryProcessor 上下文注册 == 补充context
postProcessBeanFactory(beanFactory);

StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);

// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();

// Initialize message source for this context.
initMessageSource();

// Initialize event multicaster for this context.
initApplicationEventMulticaster();

// Initialize other special beans in specific context subclasses.
onRefresh();

// Check for listener beans and register them.
registerListeners();

// Instantiate all remaining (non-lazy-init) singletons.
// 初始化所有 非懒加载 的bean,容器初始化入口
finishBeanFactoryInitialization(beanFactory);

// Last step: publish corresponding event.
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.
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...
resetCommonCaches();
contextRefresh.end();
}
}
}
}

Lifecycle

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface Lifecycle {

void start();

void stop();


boolean isRunning();

}
// LifecycleProcessor == Lifecycle的加强方法
public interface LifecycleProcessor extends Lifecycle {

void onRefresh();

void onClose();

}

DefaultLifecycleProcessor

具体方法调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
public class DefaultLifecycleProcessor implements LifecycleProcessor, BeanFactoryAware {

@Override
public void stop() {
stopBeans();
this.running = false;
}

@Override
public void onRefresh() {
startBeans(true);
this.running = true;
}

@Override
public void onClose() {
stopBeans();
this.running = false;
}
// 调用 bean的start 方法
private void startBeans(boolean autoStartupOnly) {
Map<String, Lifecycle> lifecycleBeans = getLifecycleBeans();
Map<Integer, LifecycleGroup> phases = new TreeMap<>();

lifecycleBeans.forEach((beanName, bean) -> {
if (!autoStartupOnly || (bean instanceof SmartLifecycle smartLifecycle && smartLifecycle.isAutoStartup())) {
int phase = getPhase(bean);
phases.computeIfAbsent(
phase,
p -> new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly)
).add(beanName, bean);
}
}); // 具体调用
if (!phases.isEmpty()) {
phases.values().forEach(LifecycleGroup::start);
}
}
// 获取 Lifecycle.class 的子实现类
protected Map<String, Lifecycle> getLifecycleBeans() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
Map<String, Lifecycle> beans = new LinkedHashMap<>();
String[] beanNames = beanFactory.getBeanNamesForType(Lifecycle.class, false, false);
for (String beanName : beanNames) {
String beanNameToRegister = BeanFactoryUtils.transformedBeanName(beanName);
boolean isFactoryBean = beanFactory.isFactoryBean(beanNameToRegister);
String beanNameToCheck = (isFactoryBean ? BeanFactory.FACTORY_BEAN_PREFIX + beanName : beanName);
if ((beanFactory.containsSingleton(beanNameToRegister) &&
(!isFactoryBean || matchesBeanType(Lifecycle.class, beanNameToCheck, beanFactory))) ||
matchesBeanType(SmartLifecycle.class, beanNameToCheck, beanFactory)) {
Object bean = beanFactory.getBean(beanNameToCheck);
if (bean != this && bean instanceof Lifecycle lifecycle) {
beans.put(beanNameToRegister, lifecycle);
}
}
}
return beans;
}

}

image-20230730204319825

1.3 Refresh()

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备,记录容器的启动时间startupDate, 标记容器为激活,初始化上下文环境如文件路径信息,验证必填属性是否填写
prepareRefresh();
// 获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 初始化beanfactory的各种属性
prepareBeanFactory(beanFactory);
try {
// 模板方法,此时,所有的beanDefinition已经加载,但是还没有实例化。
//允许在子类中对beanFactory进行扩展处理。比如添加ware相关接口自动装配设置,添加后置处理器等,是子类扩展prepareBeanFactory(beanFactory)的方法
postProcessBeanFactory(beanFactory);
// 实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean,在beanFactory标准初始化之后执行)
invokeBeanFactoryPostProcessors(beanFactory);
// 实例化和注册beanFactory中扩展了BeanPostProcessor的bean
//例如:
// AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
// RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
// CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// 模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情。
onRefresh();
// 注册监听器,广播early application events
registerListeners();
// 实例化所有剩余的(非懒加载)单例
// 比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。
// 实例化的过程各种BeanPostProcessor开始起作用。
finishBeanFactoryInitialization(beanFactory);
// refresh做完之后需要做的其他事情。
// 清除上下文资源缓存(如扫描中的ASM元数据)
// 初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
// 发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
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.
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...
resetCommonCaches();
}
}
}

一、

二、obtainFreshBeanFactory

获取新的 BeanFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
// AbstractApplicationContext
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 调用子类的 refreshBeanFactory 创建 新的BeanFactory
// customize factory 和 bean definition 加载
refreshBeanFactory();
// 获取新的(上面刚创建的)beanFactory
return getBeanFactory();
}


// AbstractRefreshableApplicationContext
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {

@Nullable
private Boolean allowBeanDefinitionOverriding;

@Nullable
private Boolean allowCircularReferences;

/** Bean factory for this context. */
@Nullable
private volatile DefaultListableBeanFactory beanFactory;


// 刷新工厂
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 定制化工厂(暂时不知)
customizeBeanFactory(beanFactory);
// 加载 BeanDefinition (重点)
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
}

三、prepareBeanFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// ignoreDependencyInterface是Spring框架中的一个方法,用于在依赖注入过程中忽略指定的接口。
// 当使用自动装配(autowiring)进行依赖注入时,Spring会尝试将匹配类型的实例注入到依赖项中。但有时候,某些接口可能有多个实现类,而我们只想注入其中的一个实现类。
// 在这种情况下,可以使用ignoreDependencyInterface方法来告诉Spring忽略指定的接口,不进行自动装配。这样,Spring将会查找其他匹配的实现类进行注入。
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
beanFactory.ignoreDependencyInterface(ApplicationStartupAware.class);

// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.

// registerResolvableDependency是Spring框架中的一个注解,用于将一个可解析的依赖项注册到应用程序上下文中。
// 通过使用该注解,可以将一个特定类型的依赖项注册为可解析的,
// 这意味着当Spring容器无法找到该类型的实例时,可以使用注册的可解析依赖项作为默认值。这在某些情况下可以简化依赖注入的配置,提供默认值或占位符。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);

// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));

// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (!NativeDetector.inNativeImage() && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}

// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
} // 获取系统的 properties参数 beanname,map
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
} // 获取系统环境参数 beanname, map
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
}

四、postProcessBeanFactory

子类 在 context 中注册 BeanFactoryProcess,或者其他 增强逻辑

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// 在context标准初始化之后,内部定义资源将被加载;
// 但是没有 增加器将运行,没有bean被注册,没有bean被实例化
// 允许注册(子类context)特殊的 BeanPostProcessors
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}


// 子类 context
/**
* Register ServletContextAwareProcessor.
* @see ServletContextAwareProcessor
*/
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
registerWebApplicationScopes();
}


GenericWebApplicationContext

父类

1
2
3
4
5
6
7
8
9
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.servletContext != null) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}

子类:ServletWebServerApplicationContext

1
2
3
4
5
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new WebApplicationContextServletContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
registerWebApplicationScopes();
}

子子类:AnnotationConfigServletWebServerApplicationContext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public class AnnotationConfigServletWebServerApplicationContext extends ServletWebServerApplicationContext
implements AnnotationConfigRegistry {

// 业务逻辑增强:扫描包路径、注册
private final AnnotatedBeanDefinitionReader reader;

private final ClassPathBeanDefinitionScanner scanner;

private final Set<Class<?>> annotatedClasses = new LinkedHashSet<>();

@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
super.postProcessBeanFactory(beanFactory);
if (this.basePackages != null && this.basePackages.length > 0) {
this.scanner.scan(this.basePackages);
}
if (!this.annotatedClasses.isEmpty()) {
this.reader.register(ClassUtils.toClassArray(this.annotatedClasses));
}
}

五、invokeBeanFactoryPostProcessors

执行 Bean Factory 增强器

1
2
3
4
5
6
7
8
9
10
11
12
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// PostProcessorRegistrationDelegate ## 重要方法 ## 执行 BeanFactoryPostProcessors ## postProcessBeanFactory()
// BeanFactory 增加方法 (最重要:ConfigurationClassPostProcessor)
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());

// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}

六、registerBeanPostProcessors

注册Bean 的增强器

1
2
3
4

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}

1.3 AnnotationConfigApplicationContext

注册Bean

AnnotatedBeanDefinitionReader // ClassPathBeanDefinitionScanner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
/*
独立的应用程序上下文,接受 组件类 作为输入 — 特别是 @Configuration带注释的类,但也接受使用注释的普通 @Component 类型和符合 JSR-330 的 javax.inject 类。
允许使用 逐个注册类,也允许使用 scan(String...)进行register(Class...)类路径扫描。
在有多个 @Configuration 类的情况下, @Bean 后面类中定义的方法将覆盖前面类中定义的方法。可以利用这一点,通过额外的 @Configuration 类故意覆盖某些 Bean 定义。
有关使用示例,请参见 @Configuration的 javadoc。
因为:
3.0
另请参阅:
register, scan, AnnotatedBeanDefinitionReader, ClassPathBeanDefinitionScanner, org.springframework.context.support.GenericXmlApplicationContext
作者:
尤尔根·霍勒,克里斯·比姆斯*/
public class AnnotationConfigApplicationContext extends GenericApplicationContext implements AnnotationConfigRegistry {

private final AnnotatedBeanDefinitionReader reader;

private final ClassPathBeanDefinitionScanner scanner;
public AnnotationConfigApplicationContext() {
StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
this.reader = new AnnotatedBeanDefinitionReader(this);
createAnnotatedBeanDefReader.end();
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
}

1.3.1 AnnotatedBeanDefinitionReader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
public class AnnotatedBeanDefinitionReader {

private final BeanDefinitionRegistry registry;

private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

private ConditionEvaluator conditionEvaluator;


/**
* Create a new {@code AnnotatedBeanDefinitionReader} for the given registry.
* <p>If the registry is {@link EnvironmentCapable}, e.g. is an {@code ApplicationContext},
* the {@link Environment} will be inherited, otherwise a new
* {@link StandardEnvironment} will be created and used.
* @param registry the {@code BeanFactory} to load bean definitions into,
* in the form of a {@code BeanDefinitionRegistry}
* @see #AnnotatedBeanDefinitionReader(BeanDefinitionRegistry, Environment)
* @see #setEnvironment(Environment)
*/
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}

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);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
}

1.3.2 ClassPathBeanDefinitionScanner

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
```





# 1.4 even模块

事件

监听

广播

注解





# 1.5 Import



## 1.5.1 ImportSelector



```java
public interface ImportSelector {

/**
* Select and return the names of which class(es) should be imported based on
* the {@link AnnotationMetadata} of the importing @{@link Configuration} class.
* @return the class names, or an empty array if none
*/
String[] selectImports(AnnotationMetadata importingClassMetadata);

/**
* Return a predicate for excluding classes from the import candidates, to be
* transitively applied to all classes found through this selector's imports.
* <p>If this predicate returns {@code true} for a given fully-qualified
* class name, said class will not be considered as an imported configuration
* class, bypassing class file loading as well as metadata introspection.
* @return the filter predicate for fully-qualified candidate class names
* of transitively imported configuration classes, or {@code null} if none
* @since 5.2.4
*/
@Nullable
default Predicate<String> getExclusionFilter() {
return null;
}

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 被 ConfigurationClassParser 调用 Import 
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
} // 从spring.factories 获取需要被自动注册的 类的全路径
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
// 判断是否开启自动注入的配置
// String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
protected boolean isEnabled(AnnotationMetadata metadata) {
if (getClass() == AutoConfigurationImportSelector.class) {
return getEnvironment().getProperty(EnableAutoConfiguration.ENABLED_OVERRIDE_PROPERTY, Boolean.class, true);
}
return true;
}


protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
// 判断是否开启自动配置
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
// 获取@EnableAutoConfiguration注解的属性
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 从spring.factories文件中获取配置类的全限定名数组
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
// 去重
configurations = removeDuplicates(configurations);
// 获取注解中exclude或excludeName排除的类集合
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
// 检查被排除类是否可以实例化,是否被自动配置所使用,否则抛出异常
checkExcludedClasses(configurations, exclusions);
// 去除被排除的类
configurations.removeAll(exclusions);
// 使用spring.factories配置文件中配置的过滤器对自动配置类进行过滤
configurations = getConfigurationClassFilter().filter(configurations);
// 抛出事件
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}

第二部分 Spring Bean

BeanFactory

定义 获取Bean的 接口,bean工厂

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public interface BeanFactory {

/**
* Used to dereference a {@link FactoryBean} instance and distinguish it from
* beans <i>created</i> by the FactoryBean. For example, if the bean named
* {@code myJndiObject} is a FactoryBean, getting {@code &myJndiObject}
* will return the factory, not the instance returned by the factory.
*/
String FACTORY_BEAN_PREFIX = "&";

Object getBean(String name) throws BeansException;


<T> T getBean(String name, Class<T> requiredType) throws BeansException;

Object getBean(String name, Object... args) throws BeansException;

<T> T getBean(Class<T> requiredType) throws BeansException;


<T> ObjectProvider<T> getBeanProvider(Class<T> requiredType);

<T> ObjectProvider<T> getBeanProvider(ResolvableType requiredType);

boolean containsBean(String name);

boolean isSingleton(String name) throws NoSuchBeanDefinitionException;

boolean isPrototype(String name) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, ResolvableType typeToMatch) throws NoSuchBeanDefinitionException;

boolean isTypeMatch(String name, Class<?> typeToMatch) throws NoSuchBeanDefinitionException;

@Nullable
Class<?> getType(String name) throws NoSuchBeanDefinitionException;

@Nullable
Class<?> getType(String name, boolean allowFactoryBeanInit) throws NoSuchBeanDefinitionException;

String[] getAliases(String name);

}

《 增强器 Processor》

2.1 BeanFactoryPostProcessor

用于 BeanFactory的增强:包括获取 bean

image-20230730223204903

用于 Spring 整个过程初始化过程的增强

  1. BeanFactoryPostProcessor:它也可以被视为一种增强子接口。
    BeanFactoryPostProcessor在Bean工厂实例化Bean之前对Bean工厂进行修改,可以用于添加、修改或删除Bean定义。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@FunctionalInterface
public interface BeanFactoryPostProcessor {

/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for overriding or adding
* properties even to eager-initializing beans.
* @param beanFactory the bean factory used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

}

具体实现类作用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
BeanFactoryPostProcessor接口是Spring框架中的一个扩展点,用于在Bean工厂实例化Bean之前对Bean工厂进行修改。通过实现BeanFactoryPostProcessor接口,可以对Bean定义进行修改、添加新的Bean定义或者对Bean工厂进行其他自定义操作,以达到增强效果。

以下是一些常见的实现BeanFactoryPostProcessor接口的类,以及它们的主要用途:

1. PropertySourcesPlaceholderConfigurer:这是Spring框架内置的一个实现类,用于处理属性占位符(如${...})的解析和替换。它可以读取配置文件中的属性值,并将其解析为Bean定义,然后注册到Bean工厂中。

2. ConfigurationClassPostProcessor:这是Spring框架内置的一个实现类,用于处理@Configuration注解标记的配置类。它会扫描配置类中的@Bean注解,将其解析为Bean定义,并注册到Bean工厂中。

3. AutowiredAnnotationBeanPostProcessor:这是Spring框架内置的一个实现类,用于处理@Autowired和@Resource等注解的解析和处理。它会在Bean实例化之后,对带有这些注解的字段或方法进行依赖注入。

4. BeanDefinitionRegistryPostProcessor:虽然不是直接实现BeanFactoryPostProcessor接口,但是实现了BeanDefinitionRegistryPostProcessor接口的类也可以对Bean定义进行修改或添加。它在Bean定义注册过程中被调用,可以动态地注册额外的Bean定义。

这些实现类的主要用途是在Spring容器启动时对Bean工厂进行修改,以满足特定的需求。例如,通过PropertySourcesPlaceholderConfigurer可以实现属性占位符的解析和替换,通过ConfigurationClassPostProcessor可以处理@Configuration注解标记的配置类,通过AutowiredAnnotationBeanPostProcessor可以实现依赖注入等。

需要注意的是,BeanFactoryPostProcessor接口的实现类在Spring容器启动时会被自动检测并执行。它们可以通过实现Ordered接口或使用@Order注解来指定执行的顺序。

2.1.1 BeanDefinitionRegistryPostProcessor

用于增强 BeanDefinition 的注册,也是获取Bean 的增强

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

}

BeanDefinitionRegistryPostProcessor 如何生效

1
2
3
4
5
6
7
8
9
10
11
12
13
BeanDefinitionRegistryPostProcessor接口是Spring框架中的一个扩展点,用于在Bean定义注册过程中对Bean定义进行修改或添加新的Bean定义。它的实现类可以通过自定义编写或使用Spring提供的一些内置实现类来实现。

以下是一些常见的实现BeanDefinitionRegistryPostProcessor接口的类:

1. ConfigurationClassPostProcessor:这是Spring框架内置的一个实现类,用于处理@Configuration注解标记的配置类。它会扫描配置类中的@Bean注解,将其解析为Bean定义,并注册到Bean工厂中。

2. PropertySourcesPlaceholderConfigurer:这是Spring框架内置的一个实现类,用于处理属性占位符(如${...})的解析和替换。它会读取配置文件中的属性值,并将其解析为Bean定义,然后注册到Bean工厂中。

3. ImportBeanDefinitionRegistrar:这是一个接口,用于通过编程方式注册Bean定义。实现该接口的类可以在Bean定义注册过程中动态地注册额外的Bean定义。

4. BeanFactoryPostProcessor:虽然不是直接实现BeanDefinitionRegistryPostProcessor接口,但是实现了BeanFactoryPostProcessor接口的类也可以对Bean定义进行修改或添加。BeanFactoryPostProcessor是另一个扩展点,用于在Bean工厂实例化Bean之前对Bean工厂进行修改。

需要注意的是,BeanDefinitionRegistryPostProcessor接口的实现类在Spring容器启动时会被自动检测并执行。它们可以通过实现Ordered接口或使用@Order注解来指定执行的顺序。

2.1.2 ConfigurationClassPostProcessor

配置类、@Component 、@Import 等注解 的扫描

注册 / 调用执行

注册为BeanDefinition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class AnnotatedBeanDefinitionReader {

private final BeanDefinitionRegistry registry;

private BeanNameGenerator beanNameGenerator = AnnotationBeanNameGenerator.INSTANCE;

private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

private ConditionEvaluator conditionEvaluator;

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);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
}

AnnotationConfigUtils

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public abstract class AnnotationConfigUtils {
/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
* @param source the configuration source element (already extracted)
* that this registration was triggered from. May be {@code null}.
* @return a Set of BeanDefinitionHolders, containing all bean definitions
* that have actually been registered by this call
*/
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {

DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
// AnnotationAwareOrderComparator
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
// ContextAnnotationAutowireCandidateResolver
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}

Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
// 11111、、、ConfigurationClassPostProcessor 注册为 RootBeanDefinition
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}

// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//EventListenerMethodProcessor
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
// DefaultEventListenerFactory
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}

return beanDefs;
}

调用:PostProcessorRegistrationDelegate

1
invokeBeanFactoryPostProcessors
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
final class PostProcessorRegistrationDelegate {

private PostProcessorRegistrationDelegate() {
}

// 执行时注册 ConfigurationClassPostProcessor ==》 BeanDefinitionRegistryPostProcessor
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {

// WARNING: Although it may appear that the body of this method can be easily
// refactored to avoid the use of multiple loops and multiple lists, the use
// of multiple lists and multiple passes over the names of processors is
// intentional. We must ensure that we honor the contracts for PriorityOrdered
// and Ordered processors. Specifically, we must NOT cause processors to be
// instantiated (via getBean() invocations) or registered in the ApplicationContext
// in the wrong order.
//
// Before submitting a pull request (PR) to change this method, please review the
// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
// to ensure that your proposal does not result in a breaking change:
// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

// 1、Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
// 1、执行 传入的(当前BeanFactory中的 beanFactoryPostProcessors) 中的 BeanDefinitionRegistryPostProcessor
if (beanFactory instanceof BeanDefinitionRegistry registry) {
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();

for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor registryProcessor) {
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();

// 2、PriorityOrdered 实现该接口的 BeanDefinitionRegistryPostProcessors 优先级最高 限制性
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 2、getBean() 显示创建 ConfigurationClassPostProcessor实例
// (问题:何处将 BeanDefinition 注册到容器中) ==》(回答: 在初始化容器context的时候会初始化 read\scan ,在refresh的 方法 postProcessBeanFactory
// 会调用 AbstractApplicationContext 的子类 ,web容器的 scan、register 方法,最终注册 BeanDefinition)
// 在这,通过BeanFactory的 getBean方法,实例化所有已经注册的BeanDefinition 为 BeanDefinitionRegistryPostProcessor 的类
// 即,初始化 会初始化ConfigurationClassPostProcessor (问题:何处将 ConfigurationClassPostProcessor 注册为BeanDefinition?)
// (回答:context 的 annotation 或者 scan 的时候自动注册,或者和BeanFactoryPostProcessor 一样被注册)
// (具体回答:ConfigurationClassPostProcessor, 会在 AnnotationConfigServletWebServerApplicationContext ==》 AnnotatedBeanDefinitionReader 的
// 初始化过程中被 注册,因为这个 reader,会注册一些额外的 Processor增强器,实现一些功能)
/**
* * <p>Registered by default when using {@code <context:annotation-config/>} or
* * {@code <context:component-scan/>}. Otherwise, may be declared manually as
* * with any other {@link BeanFactoryPostProcessor}.
*/
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 对 registerProcessor进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
// 优先调用postProcessBeanDefinitionRegistry
// 调用 registerProcessor的 postProcessBeanDefinitionRegistry()
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();

//
// Ordered 实现该接口的 BeanDefinitionRegistryPostProcessors 较后执行
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
// getBean() 根据AnnotatedBeanDefinitionReader注册的 BeanDefinition创建实列
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
//
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();

// 最后执行 普通的BeanDefinitionRegistryPostProcessors
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry, beanFactory.getApplicationStartup());
currentRegistryProcessors.clear();
}

// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}

else {
// 执行容器的实例
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}

// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);

// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}

// 先执行 invokeBeanDefinitionRegistryPostProcessors() ## postProcessor.postProcessBeanDefinitionRegistry(registry);
// 再执行 invokeBeanFactoryPostProcessors() ## postProcessor.postProcessBeanFactory(beanFactory);
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);

// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);

// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);

// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
}

}

功能 - Parser

ConfigurationClassParser

parse 入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
// 解析 已经有了 BeanDefinitionHolder对象,直接解析
public void parse(Set<BeanDefinitionHolder> configCandidates) {
// 循环遍历
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
// 判断当前BeanDefinition 适合那种解析
// 1、AnnotatedBeanDefinition、 == 元数据解析
// 2、AbstractBeanDefinition # hasBeanClass() == beanclass解析
// 3.其他 == beanname 解析
try {// 注解
if (bd instanceof AnnotatedBeanDefinition annotatedBeanDef) {
parse(annotatedBeanDef.getMetadata(), holder.getBeanName());
} //
else if (bd instanceof AbstractBeanDefinition abstractBeanDef && abstractBeanDef.hasBeanClass()) {
parse(abstractBeanDef.getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
//
this.deferredImportSelectorHandler.process();
}

// 通过 类路径获取 MetadataReader,创建ConfigurationClass
protected final void parse(@Nullable String className, String beanName) throws IOException {
Assert.notNull(className, "No bean class name for configuration class bean definition");
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
}
// 通过Class对象直接创建 ConfigurationClass
protected final void parse(Class<?> clazz, String beanName) throws IOException {
// 创建 ConfigurationClass对象
processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER);
}

// 通过注解信息 创建ConfigurationClass
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}

processConfigurationClass

解析 configuration Class

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}

ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
if (configClass.isImported()) {
if (existingClass.isImported()) {
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}

// Recursively process the configuration class and its superclass hierarchy.
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 具体 ConfigurationClass 的 解析
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 添加 解析好的 configClass
this.configurationClasses.put(configClass, configClass);
}

doProcessConfigurationClass

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85


@Nullable
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {

if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}

// Process any @PropertySource annotations
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.propertySourceRegistry != null) {
this.propertySourceRegistry.processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}

// Process any @ComponentScan annotations
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 关键 -- 自动注入 -- 实现接口,方法调用
// Process any @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);

// Process any @ImportResource annotations
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}

// Process individual @Bean methods
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}

// Process default methods on interfaces
processInterfaces(configClass, sourceClass);

// Process superclass, if any
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}

// No superclass -> processing is complete
return null;
}

ConfigurationClassBeanDefinitionReader

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ## ConfigurationClassPostProcessor ##
// ConfigurationClassParser ##
parser.parse(candidates);
parser.validate();

// 获取 parse 解析好的 configClass 集合
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);

// Read the model and create bean definitions based on its content
// 读取模式,并基于ConfigurationClass信息创建beanDefinition
if (this.reader == null) {
// 初始化 ConfigurationClassBeanDefinitionReader
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 通过ConfigurationClassParser 解析的ConfiguratioClass信息
// 加载 信息中的 BeanDefinition (@Bean, @ImportBeanDefinitionRegistrar,
// @ImportResource, @Configuration)
this.reader.loadBeanDefinitions(configClasses);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
// 读取一组已经被完整解析的配置类ConfigurationClass,向给定bean容器BeanDefinitionRegistry注册其中所有的bean定义。
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
// 遍历当前 ConfigurationClass 集合
for (ConfigurationClass configClass : configurationModel) {
// 通过 ConfigrationClass 加载对应的 BeanDefinition (@Bean, @ImportBeanDefinitionRegistrar, @ImportResource, @Configuration)
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}

/**
* Read a particular {@link ConfigurationClass}, registering bean definitions
* for the class itself and all of its {@link Bean} methods.
*/
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {

// 如果 条件Condition判断 应当跳过当前配置类,则从当前registry中移除 BeanDefinition信息
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}

if (configClass.isImported()) {
// 将 ConfigurationClass 自己加载为 BeanDefinition (@Configuration)
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 遍历configClass的 BeanMethod (@Bean注解信息),加载为BeanDefinition
// 将 @Bean 解析为 BeanDefinition
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 参数:Map<String, Class<? extends BeanDefinitionReader>>
// 将@ImportResource的信息 注册为BeanDefinition
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 参数:Map<ImportBeanDefinitionRegistrar, AnnotationMetadata>
// @ImportBeanDefinitionRegistrar 的 注解信息,床架BeanDefinition
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}

2.3 BeanPostProcessor

用于对Bean 初始化(initialization)过程的 前后进行增强

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface BeanPostProcessor {

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

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

}

2.3.1 接口interface

InstantiationAwareBeanPostProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
// 实例化前 (newInstance)
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
// 实例化后
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
// 属性增强(autowired)
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {

return pvs;
}

}

InitializingBean

1
2
3
4
5
6
7
8
9
10
11
12
13
public interface InitializingBean {

/**
* Invoked by the containing {@code BeanFactory} after it has set all bean properties
* and satisfied {@link BeanFactoryAware}, {@code ApplicationContextAware} etc.
* <p>This method allows the bean instance to perform validation of its overall
* configuration and final initialization when all bean properties have been set.
* @throws Exception in the event of misconfiguration (such as failure to set an
* essential property) or if initialization fails for any other reason
*/
void afterPropertiesSet() throws Exception;

}

SmartInstantiationAwareBeanPostProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
// 推测bean 类型
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
// 确定bean type
default Class<?> determineBeanType(Class<?> beanClass, String beanName) throws BeansException {
return beanClass;
}
// 确定候选 构造器列表(可用构造器)
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {

return null;
}

/**
* Obtain a reference for early access to the specified bean,
* typically for the purpose of resolving a circular reference.
* <p>This callback gives post-processors a chance to expose a wrapper
* early - that is, before the target bean instance is fully initialized.
* The exposed object should be equivalent to the what
* {@link #postProcessBeforeInitialization} / {@link #postProcessAfterInitialization}
* would expose otherwise. Note that the object returned by this method will
* be used as bean reference unless the post-processor returns a different
* wrapper from said post-process callbacks. In other words: Those post-process
* callbacks may either eventually expose the same reference or alternatively
* return the raw bean instance from those subsequent callbacks (if the wrapper
* for the affected bean has been built for a call to this method already,
* it will be exposes as final bean reference by default).
* <p>The default implementation returns the given {@code bean} as-is.
* @param bean the raw bean instance
* @param beanName the name of the bean
* @return the object to expose as bean reference
* (typically with the passed-in bean instance as default)
* @throws org.springframework.beans.BeansException in case of errors
*/
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}

}

MergedBeanDefinitionPostProcessor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {

/**
* Post-process the given merged bean definition for the specified bean.
* @param beanDefinition the merged bean definition for the bean
* @param beanType the actual type of the managed bean instance
* @param beanName the name of the bean
* @see AbstractAutowireCapableBeanFactory#applyMergedBeanDefinitionPostProcessors
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);

/**
* A notification that the bean definition for the specified name has been reset,
* and that this post-processor should clear any metadata for the affected bean.
* <p>The default implementation is empty.
* @param beanName the name of the bean
* @since 5.1
* @see DefaultListableBeanFactory#resetBeanDefinition
*/
default void resetBeanDefinition(String beanName) {
}

}

具体作用类(实现类)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
eanPostProcessor接口是Spring框架中的一个扩展点,用于在Bean实例化和初始化的过程中对Bean进行增强或修改。通过实现BeanPostProcessor接口,可以在Bean的生命周期中插入自定义的逻辑,以达到增强效果。

以下是一些常见的实现BeanPostProcessor接口的类,以及它们的主要用途:

1. CommonAnnotationBeanPostProcessor:这是Spring框架内置的一个实现类,用于处理常见的注解,如@PostConstruct和@PreDestroy。它会在Bean的初始化阶段调用相应的方法。

2. AutowiredAnnotationBeanPostProcessor:这是Spring框架内置的一个实现类,用于处理@Autowired和@Resource等注解的解析和处理。它会在Bean的实例化和初始化阶段对带有这些注解的字段或方法进行依赖注入。

3. BeanValidationPostProcessor:这是Spring框架内置的一个实现类,用于支持Bean的校验。它会在Bean的初始化阶段对带有校验注解(如@Valid)的字段进行校验。

4. CustomBeanPostProcessor:这是自定义的实现类,可以根据具体需求实现自定义的Bean后置处理逻辑。例如,可以在Bean的初始化阶段对特定的属性进行修改或添加额外的逻辑。

这些实现类的主要用途是在Bean的生命周期中对Bean进行增强或修改。例如,CommonAnnotationBeanPostProcessor用于处理常见的注解,AutowiredAnnotationBeanPostProcessor用于处理依赖注入,BeanValidationPostProcessor用于支持校验等。

需要注意的是,BeanPostProcessor接口的实现类在Spring容器启动时会被自动检测并应用于相应的Bean。它们可以通过实现Ordered接口或使用@Order注解来指定执行的顺序。

这些是一些常见的BeanPostProcessor实现类及其主要用途的介绍。如果您想了解更多关于BeanPostProcessor的实现类的信息,建议查阅Spring框架的官方文档或相关的教程资料。

如果您有其他问题,请随时提问。

实现接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
除了BeanPostProcessor接口外,Spring框架还提供了其他一些增强子接口,用于在Bean的生命周期中进行特定的操作。以下是一些常见的增强子接口及其主要用途:

1. InstantiationAwareBeanPostProcessor:该接口继承自BeanPostProcessor接口,提供了在Bean实例化之前和之后进行自定义处理的能力。它可以在Bean实例化之前修改Bean的实例化方式,或者在Bean实例化之后对Bean进行进一步的处理。

2. DestructionAwareBeanPostProcessor:该接口继承自BeanPostProcessor接口,提供了在Bean销毁之前进行自定义处理的能力。它可以在Bean销毁之前执行一些清理操作,例如释放资源或发送通知。



4. SmartInstantiationAwareBeanPostProcessor:该接口继承自InstantiationAwareBeanPostProcessor接口,提供了更精细的控制能力。它可以在Bean实例化之前选择自定义的实例化策略,并在实例化之后对Bean进行进一步的处理。

这些增强子接口可以根据具体需求进行实现,以实现对Bean的定制化操作。通过实现这些接口,可以在Bean的生命周期中插入自定义的逻辑,例如修改Bean的实例化方式、对Bean进行进一步的处理或执行清理操作。

需要注意的是,增强子接口的实现类在Spring容器启动时会被自动检测并应用于相应的Bean。它们可以通过实现Ordered接口或使用@Order注解来指定执行的顺序。

希望这个回答对您有帮助。如果您有其他问题,请随时提问。

2.3.2 实现类

AutowiredAnnotationBeanPostProcessor

自动注入

2.1.2.1 DefaultListableBeanFactory

1

《注册 Registry》

2.4 BeanDefinitionRegistry

管理BeanDefinition , 管理容器的 BeanDefinition

实现类都是 Context ,用于上下文管理BeanDefinition

image-20230808210957497

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
public interface BeanDefinitionRegistry extends AliasRegistry {

/**
* Register a new bean definition with this registry.
* Must support RootBeanDefinition and ChildBeanDefinition.
* @param beanName the name of the bean instance to register
* @param beanDefinition definition of the bean instance to register
* @throws BeanDefinitionStoreException if the BeanDefinition is invalid
* @throws BeanDefinitionOverrideException if there is already a BeanDefinition
* for the specified bean name and we are not allowed to override it
* @see GenericBeanDefinition
* @see RootBeanDefinition
* @see ChildBeanDefinition
*/
void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException;

/**
* Remove the BeanDefinition for the given name.
* @param beanName the name of the bean instance to register
* @throws NoSuchBeanDefinitionException if there is no such bean definition
*/
void removeBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

/**
* Return the BeanDefinition for the given bean name.
* @param beanName name of the bean to find a definition for
* @return the BeanDefinition for the given name (never {@code null})
* @throws NoSuchBeanDefinitionException if there is no such bean definition
*/
BeanDefinition getBeanDefinition(String beanName) throws NoSuchBeanDefinitionException;

/**
* Check if this registry contains a bean definition with the given name.
* @param beanName the name of the bean to look for
* @return if this registry contains a bean definition with the given name
*/
boolean containsBeanDefinition(String beanName);

/**
* Return the names of all beans defined in this registry.
* @return the names of all beans defined in this registry,
* or an empty array if none defined
*/
String[] getBeanDefinitionNames();

/**
* Return the number of beans defined in the registry.
* @return the number of beans defined in the registry
*/
int getBeanDefinitionCount();

/**
* Determine whether the given bean name is already in use within this registry,
* i.e. whether there is a local bean or alias registered under this name.
* @param beanName the name to check
* @return whether the given bean name is already in use
*/
boolean isBeanNameInUse(String beanName);

}

2.5 AnnotationConfigRegistry

web、servlet、react (web容器)的实现,注解扫描 注册 Bean

image-20230808212447647

注解配置的 注册

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public interface AnnotationConfigRegistry {

/**
* Register one or more component classes to be processed.
* <p>Calls to {@code register} are idempotent; adding the same
* component class more than once has no additional effect.
* @param componentClasses one or more component classes,
* e.g. {@link Configuration @Configuration} classes
*/
void register(Class<?>... componentClasses);

/**
* Perform a scan within the specified base packages.
* @param basePackages the packages to scan for component classes
*/
void scan(String... basePackages);

}

第三部分 Spring Core

3.1 Utils

SpringFactoriesLoader

加载 spring.factories 文件的类 k-v 类,loadFactories

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
public final class SpringFactoriesLoader {

/**
* The location to look for factories.
* <p>Can be present in multiple JAR files.
*/
public static final String FACTORIES_RESOURCE_LOCATION = "META-INF/spring.factories";


private static final Log logger = LogFactory.getLog(SpringFactoriesLoader.class);

static final Map<ClassLoader, Map<String, List<String>>> cache = new ConcurrentReferenceHashMap<>();


private SpringFactoriesLoader() {
}

public static <T> List<T> loadFactories(Class<T> factoryType, @Nullable ClassLoader classLoader) {
Assert.notNull(factoryType, "'factoryType' must not be null");
ClassLoader classLoaderToUse = classLoader;
if (classLoaderToUse == null) {
classLoaderToUse = SpringFactoriesLoader.class.getClassLoader();
}
List<String> factoryImplementationNames = loadFactoryNames(factoryType, classLoaderToUse);
if (logger.isTraceEnabled()) {
logger.trace("Loaded [" + factoryType.getName() + "] names: " + factoryImplementationNames);
}
List<T> result = new ArrayList<>(factoryImplementationNames.size());
for (String factoryImplementationName : factoryImplementationNames) {
result.add(instantiateFactory(factoryImplementationName, factoryType, classLoaderToUse));
}
AnnotationAwareOrderComparator.sort(result);
return result;
}
}

3.2 IO

InputStreamSource

1
2
3
4
public interface InputStreamSource {

InputStream getInputStream() throws IOException;
}

Resource

URI URL File

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
/** * @see #getInputStream()
* @see #getURL()
* @see #getURI()
* @see #getFile()
* @see WritableResource
* @see ContextResource
* @see UrlResource
* @see FileUrlResource
* @see FileSystemResource
* @see ClassPathResource
* @see ByteArrayResource
* @see InputStreamResource
*/
public interface Resource extends InputStreamSource {
URL getURL() throws IOException;

URI getURI() throws IOException;

File getFile() throws IOException;
default ReadableByteChannel readableChannel() throws IOException {
return Channels.newChannel(getInputStream());
}

default byte[] getContentAsByteArray() throws IOException {
return FileCopyUtils.copyToByteArray(getInputStream());
}

default String getContentAsString(Charset charset) throws IOException {
return FileCopyUtils.copyToString(new InputStreamReader(getInputStream(), charset));
}
}

ResourceLoader

用于加载资源,获取Resource

1
2
3
4
5
6
7
8
9
10
public interface ResourceLoader {

/** Pseudo URL prefix for loading from the class path: "classpath:". */
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
// Resource
Resource getResource(String location);
// ClassLoader
@Nullable
ClassLoader getClassLoader();
}

第四部分 Spring AOP

4.1 创建代理对象

AbstractAutoProxyCreator

-》BeanPostProcessor

在Bean 初始化的时候,为其生成代理对象,是 AOP的切入重点

image-20230730231209293

1
2
3
public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport
implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
}

最后一部分 特殊名词

AOT == Ahead-Of-Time

Spring中的AOT是Ahead-Of-Time的缩写,是指将应用程序在编译时预先转译成本地机器代码的技术。AOT可以提高应用程序的性能和启动速度,因为它省去了运行时动态编译的过程。在Spring中,AOT支持是通过Spring Native项目实现的,它可以将Spring应用程序编译成原生镜像,以提供更快的启动时间和更小的内存占用。Spring Native通过GraalVM将Spring应用程序进行AOT编译,使用新的AOT引擎深度分析应用程序,并生成所需的GraalVM本机配置。这些转换由Maven和Gradle的Spring AOT插件执行。

参考搜索结果:

[1]更快更省:带有新AOT引擎的Spring Native 0.11 发布- spring.io - 解道Jdon

[4]Spring Native 项目,把Spring 项目编译成原生程序! - 博客园

JNDI(Java Naming and Directory Interface)

1
2
3
4
5
6
7
8
9
10
11
12
13
JNDI是Java Naming and Directory Interface的缩写,是Java提供的一种标准的API,用于访问命名和目录服务。JNDI提供了一种统一的方式来查找和访问各种命名服务,如目录服务、命名空间、配置信息等。

具体来说,JNDI的主要作用包括:

1. 命名服务:JNDI可以用于访问和管理命名服务,如LDAP(轻量级目录访问协议)服务器、DNS(域名系统)等。它提供了一组API,可以通过名称来查找和获取对象,实现对象的命名和查找功能。

2. 目录服务:JNDI可以用于访问和管理目录服务,如LDAP目录服务器。它提供了一组API,可以对目录中的条目进行增删改查操作,实现目录的管理和维护功能。

3. 配置信息:JNDI可以用于访问和管理配置信息,如数据库连接信息、资源配置等。它可以将配置信息存储在命名服务中,并通过JNDI API进行访问和获取,实现配置信息的统一管理和动态更新。

4. 分布式对象:JNDI可以用于查找和获取分布式对象,如EJB(企业JavaBean)等。它提供了一组API,可以通过名称来查找和获取远程对象,实现分布式对象的访问和调用功能。

总结:JNDI是Java提供的一种标准API,用于访问命名和目录服务。它可以用于访问和管理命名服务、目录服务、配置信息和分布式对象等,提供了一种统一的方式来查找和访问各种命名服务。

JMH(基准测试)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
JMH(Java Microbenchmark Harness)是Java语言的一个基准测试框架,用于编写、运行和分析Java程序的性能基准测试。它是由OpenJDK项目提供的一个开源工具,旨在提供可靠、准确和可重复的性能测试环境。

JMH的主要特点和功能包括:

1. 提供丰富的基准测试注解:JMH提供了一组注解,用于定义基准测试方法、迭代次数、线程数等测试参数。这些注解可以帮助开发人员编写清晰、可读的基准测试代码。

2. 自动化的基准测试运行:JMH可以自动化地运行基准测试,并提供准确的性能度量和统计数据。它会自动进行预热、测量和迭代,并输出详细的测试结果和报告。

3. 微基准测试支持:JMH支持微基准测试,即对单个方法或代码片段进行性能测试。它可以精确地测量方法的执行时间、吞吐量、延迟等性能指标。

4. 避免优化干扰:JMH会自动处理JIT(即时编译器)优化的干扰,以确保测试结果的准确性。它会使用黑盒测试的方式,避免编译器对测试代码进行过度优化。

5. 高度可配置:JMH提供了丰富的配置选项,可以调整测试的参数和行为。开发人员可以根据需要设置测试的迭代次数、线程数、预热次数等,以及输出结果的格式和详细程度。

总结:JMH是Java语言的一个基准测试框架,用于编写、运行和分析Java程序的性能基准测试。它提供了丰富的基准测试注解、自动化的测试运行、微基准测试支持、避免优化干扰和高度可配置等功能,帮助开发人员准确、可靠地评估和优化Java程序的性能。

JMX(监控管理 Java程序)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
JMX(Java Management Extensions)是Java平台提供的一套管理和监控Java应用程序的标准API。它提供了一种标准化的方式来管理和监控Java应用程序的运行状态、性能指标和配置信息。

JMX的主要特点和功能包括:

1. MBean(Managed Bean):JMX使用MBean作为管理和监控的基本单元。MBean是一种Java对象,通过暴露一组操作和属性来提供管理和监控功能。

2. JMX代理:JMX提供了代理机制,允许远程管理和监控Java应用程序。通过JMX代理,可以在远程机器上访问和操作应用程序的MBean。

3. 通信协议:JMX支持多种通信协议,如RMI(远程方法调用)、HTTP、SNMP(简单网络管理协议)等。这些协议可以用于在不同的环境中进行管理和监控操作。

4. JMX连接:JMX连接是通过JMX连接器建立的,它允许管理和监控工具与Java应用程序进行通信。常见的JMX连接器包括RMI连接器、HTTP连接器和JMXMP连接器。

5. JMX管理工具:JMX提供了一些管理和监控工具,如JConsole、VisualVM等。这些工具可以连接到Java应用程序的JMX代理,提供可视化的界面来查看和操作MBean。

总结:JMX是Java平台提供的一套管理和监控Java应用程序的标准API。它使用MBean作为管理和监控的基本单元,提供了代理机制和多种通信协议,允许远程管理和监控Java应用程序。通过JMX连接器建立连接,可以使用JMX管理工具来查看和操作应用程序的MBean。

————《Spring Boot》————

第一部分 Spring Boot

第一章 事件监听机制

1.1 Listener - 监听者

ApplicationListener - Spring Context

由Spring Context 管理的监听者,最终执行 回调方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@FunctionalInterface
public interface ApplicationListener<E extends ApplicationEvent> extends EventListener {

/**
* Handle an application event.
* @param event the event to respond to
*/
void onApplicationEvent(E event);


/**
* Create a new {@code ApplicationListener} for the given payload consumer.
* @param consumer the event payload consumer
* @param <T> the type of the event payload
* @return a corresponding {@code ApplicationListener} instance
* @since 5.3
* @see PayloadApplicationEvent
*/
static <T> ApplicationListener<PayloadApplicationEvent<T>> forPayload(Consumer<T> consumer) {
return event -> consumer.accept(event.getPayload());
}

}

SpringApplicationRunListener - Spring Boot - Event

定义回调方法(类似于事件 – 与listener没关系)

1
作用:定义回调方法,在Spring Boot初始化过程中,通过调用方法,通过 EventPublishingRunListener 方法,持有Spring ContextMulticast 广播器,通知具体的 listener执行
1
2
3
4
5
6
7
8
包含的事件:(这些事件可以对应Spring Boot的启动流程)
1、starting
2、environmentPrepared
3、contextPrepared
4、contextLoaded
5、started
6、ready
7、failed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
// 1、starting
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
// 2、environmentPrepared
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
// 3、contextPrepared --- 4、contextLoaded
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
}
// 5、started
listeners.started(context, timeTakenToStartup);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
// 6、ready
listeners.ready(context, timeTakenToReady);
}
catch (Throwable ex) {
// 7、failed
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
public interface SpringApplicationRunListener {

/**
* Called immediately when the run method has first started. Can be used for very
* early initialization.
* @param bootstrapContext the bootstrap context
*/
default void starting(ConfigurableBootstrapContext bootstrapContext) {
}

/**
* Called once the environment has been prepared, but before the
* {@link ApplicationContext} has been created.
* @param bootstrapContext the bootstrap context
* @param environment the environment
*/
default void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment) {
}

/**
* Called once the {@link ApplicationContext} has been created and prepared, but
* before sources have been loaded.
* @param context the application context
*/
default void contextPrepared(ConfigurableApplicationContext context) {
}

/**
* Called once the application context has been loaded but before it has been
* refreshed.
* @param context the application context
*/
default void contextLoaded(ConfigurableApplicationContext context) {
}

/**
* The context has been refreshed and the application has started but
* {@link CommandLineRunner CommandLineRunners} and {@link ApplicationRunner
* ApplicationRunners} have not been called.
* @param context the application context.
* @param timeTaken the time taken to start the application or {@code null} if unknown
* @since 2.6.0
*/
default void started(ConfigurableApplicationContext context, Duration timeTaken) {
started(context);
}

/**
* The context has been refreshed and the application has started but
* {@link CommandLineRunner CommandLineRunners} and {@link ApplicationRunner
* ApplicationRunners} have not been called.
* @param context the application context.
* @since 2.0.0
* @deprecated since 2.6.0 for removal in 3.0.0 in favor of
* {@link #started(ConfigurableApplicationContext, Duration)}
*/
@Deprecated
default void started(ConfigurableApplicationContext context) {
}

/**
* Called immediately before the run method finishes, when the application context has
* been refreshed and all {@link CommandLineRunner CommandLineRunners} and
* {@link ApplicationRunner ApplicationRunners} have been called.
* @param context the application context.
* @param timeTaken the time taken for the application to be ready or {@code null} if
* unknown
* @since 2.6.0
*/
default void ready(ConfigurableApplicationContext context, Duration timeTaken) {
running(context);
}

/**
* Called immediately before the run method finishes, when the application context has
* been refreshed and all {@link CommandLineRunner CommandLineRunners} and
* {@link ApplicationRunner ApplicationRunners} have been called.
* @param context the application context.
* @since 2.0.0
* @deprecated since 2.6.0 for removal in 3.0.0 in favor of
* {@link #ready(ConfigurableApplicationContext, Duration)}
*/
@Deprecated
default void running(ConfigurableApplicationContext context) {
}

/**
* Called when a failure occurs when running the application.
* @param context the application context or {@code null} if a failure occurred before
* the context was created
* @param exception the failure
* @since 2.0.0
*/
default void failed(ConfigurableApplicationContext context, Throwable exception) {
}

}

具体实现 EventPublishingRunListener – Spring Boot

广播通知 所有的事件 (start 、environmentPrepared、等)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
public class EventPublishingRunListener implements SpringApplicationRunListener, Ordered {

private final SpringApplication application;

private final String[] args;
// 持有Context 的 multicast,通过它广播Spring Boot的事件
private final SimpleApplicationEventMulticaster initialMulticaster;

public EventPublishingRunListener(SpringApplication application, String[] args) {
this.application = application;
this.args = args;
this.initialMulticaster = new SimpleApplicationEventMulticaster();
for (ApplicationListener<?> listener : application.getListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}

@Override
public int getOrder() {
return 0;
}

@Override
public void starting(ConfigurableBootstrapContext bootstrapContext) {
this.initialMulticaster
.multicastEvent(new ApplicationStartingEvent(bootstrapContext, this.application, this.args));
}

@Override
public void environmentPrepared(ConfigurableBootstrapContext bootstrapContext,
ConfigurableEnvironment environment) {
this.initialMulticaster.multicastEvent(
new ApplicationEnvironmentPreparedEvent(bootstrapContext, this.application, this.args, environment));
}

@Override
public void contextPrepared(ConfigurableApplicationContext context) {
this.initialMulticaster
.multicastEvent(new ApplicationContextInitializedEvent(this.application, this.args, context));
}

@Override
public void contextLoaded(ConfigurableApplicationContext context) {
for (ApplicationListener<?> listener : this.application.getListeners()) {
if (listener instanceof ApplicationContextAware) {
((ApplicationContextAware) listener).setApplicationContext(context);
}
context.addApplicationListener(listener);
}
this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));
}

@Override
public void started(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationStartedEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, LivenessState.CORRECT);
}

@Override
public void ready(ConfigurableApplicationContext context, Duration timeTaken) {
context.publishEvent(new ApplicationReadyEvent(this.application, this.args, context, timeTaken));
AvailabilityChangeEvent.publish(context, ReadinessState.ACCEPTING_TRAFFIC);
}

@Override
public void failed(ConfigurableApplicationContext context, Throwable exception) {
ApplicationFailedEvent event = new ApplicationFailedEvent(this.application, this.args, context, exception);
if (context != null && context.isActive()) {
// Listeners have been registered to the application context so we should
// use it at this point if we can
context.publishEvent(event);
}
else {
// An inactive context may not have a multicaster so we use our multicaster to
// call all the context's listeners instead
if (context instanceof AbstractApplicationContext) {
for (ApplicationListener<?> listener : ((AbstractApplicationContext) context)
.getApplicationListeners()) {
this.initialMulticaster.addApplicationListener(listener);
}
}
this.initialMulticaster.setErrorHandler(new LoggingErrorHandler());
this.initialMulticaster.multicastEvent(event);
}
}

private static class LoggingErrorHandler implements ErrorHandler {

private static final Log logger = LogFactory.getLog(EventPublishingRunListener.class);

@Override
public void handleError(Throwable throwable) {
logger.warn("Error calling ApplicationEventListener", throwable);
}

}

}

创建 通知事件 Event

image-20230723170427758

1
2
// ApplicationPreparedEvent
this.initialMulticaster.multicastEvent(new ApplicationPreparedEvent(this.application, this.args, context));

ApplicationPreparedEvent –> ApplicationEvent == Spring Context

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class ApplicationPreparedEvent extends SpringApplicationEvent {

private final ConfigurableApplicationContext context;

/**
* Create a new {@link ApplicationPreparedEvent} instance.
* @param application the current application
* @param args the arguments the application is running with
* @param context the ApplicationContext about to be refreshed
*/
public ApplicationPreparedEvent(SpringApplication application, String[] args,
ConfigurableApplicationContext context) {
super(application, args);
this.context = context;
}

/**
* Return the application context.
* @return the context
*/
public ConfigurableApplicationContext getApplicationContext() {
return this.context;
}

}

通过事件找到 ApplicationListener

并调用onApplicationEvent() 方法

SimpleApplicationEventMulticaster

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {

@Nullable
private Executor taskExecutor;

@Nullable
private ErrorHandler errorHandler;

@Nullable
private volatile Log lazyLogger;

protected void invokeListener(ApplicationListener<?> listener, ApplicationEvent event) {
ErrorHandler errorHandler = getErrorHandler();
if (errorHandler != null) {
try {
doInvokeListener(listener, event);
}
catch (Throwable err) {
errorHandler.handleError(err);
}
}
else {
doInvokeListener(listener, event);
}
}
}

SpringApplicationRunListeners

回调方法的 注册具体的调用入口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
class SpringApplicationRunListeners {

private final Log log;
// 保存注册的 listeners
private final List<SpringApplicationRunListener> listeners;

private final ApplicationStartup applicationStartup;

SpringApplicationRunListeners(Log log, Collection<? extends SpringApplicationRunListener> listeners,
ApplicationStartup applicationStartup) {
this.log = log;
this.listeners = new ArrayList<>(listeners);
this.applicationStartup = applicationStartup;
}

void starting(ConfigurableBootstrapContext bootstrapContext, Class<?> mainApplicationClass) {
doWithListeners("spring.boot.application.starting", (listener) -> listener.starting(bootstrapContext),
(step) -> {
if (mainApplicationClass != null) {
step.tag("mainApplicationClass", mainApplicationClass.getName());
}
});
}

void environmentPrepared(ConfigurableBootstrapContext bootstrapContext, ConfigurableEnvironment environment) {
doWithListeners("spring.boot.application.environment-prepared",
(listener) -> listener.environmentPrepared(bootstrapContext, environment));
}

void contextPrepared(ConfigurableApplicationContext context) {
doWithListeners("spring.boot.application.context-prepared", (listener) -> listener.contextPrepared(context));
}

void contextLoaded(ConfigurableApplicationContext context) {
doWithListeners("spring.boot.application.context-loaded", (listener) -> listener.contextLoaded(context));
}

void started(ConfigurableApplicationContext context, Duration timeTaken) {
doWithListeners("spring.boot.application.started", (listener) -> listener.started(context, timeTaken));
}

void ready(ConfigurableApplicationContext context, Duration timeTaken) {
doWithListeners("spring.boot.application.ready", (listener) -> listener.ready(context, timeTaken));
}

void failed(ConfigurableApplicationContext context, Throwable exception) {
doWithListeners("spring.boot.application.failed",
(listener) -> callFailedListener(listener, context, exception), (step) -> {
step.tag("exception", exception.getClass().toString());
step.tag("message", exception.getMessage());
});
}

private void callFailedListener(SpringApplicationRunListener listener, ConfigurableApplicationContext context,
Throwable exception) {
try {
listener.failed(context, exception);
}
catch (Throwable ex) {
if (exception == null) {
ReflectionUtils.rethrowRuntimeException(ex);
}
if (this.log.isDebugEnabled()) {
this.log.error("Error handling failed", ex);
}
else {
String message = ex.getMessage();
message = (message != null) ? message : "no error message";
this.log.warn("Error handling failed (" + message + ")");
}
}
}

private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction) {
doWithListeners(stepName, listenerAction, null);
}
/// 调用 所有listener 执行 listener 的 方法(对应的方法)
//Consumer:
// forEach(listenerAction)
// listenerAction.accept(listener);
// (listener) -> listener.ready(context, timeTaken) // 假设 调用ready
private void doWithListeners(String stepName, Consumer<SpringApplicationRunListener> listenerAction,
Consumer<StartupStep> stepAction) {
StartupStep step = this.applicationStartup.start(stepName);
this.listeners.forEach(listenerAction);
if (stepAction != null) {
stepAction.accept(step);
}
step.end();
}

}

1.2 Multicaster - 广播 – Spring Context

ApplicationEventMulticaster – Spring Boot

管理 LIstener

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
public interface ApplicationEventMulticaster {

/**
* Add a listener to be notified of all events.
* @param listener the listener to add
* @see #removeApplicationListener(ApplicationListener)
* @see #removeApplicationListeners(Predicate)
*/
void addApplicationListener(ApplicationListener<?> listener);

/**
* Add a listener bean to be notified of all events.
* @param listenerBeanName the name of the listener bean to add
* @see #removeApplicationListenerBean(String)
* @see #removeApplicationListenerBeans(Predicate)
*/
void addApplicationListenerBean(String listenerBeanName);

/**
* Remove a listener from the notification list.
* @param listener the listener to remove
* @see #addApplicationListener(ApplicationListener)
* @see #removeApplicationListeners(Predicate)
*/
void removeApplicationListener(ApplicationListener<?> listener);

/**
* Remove a listener bean from the notification list.
* @param listenerBeanName the name of the listener bean to remove
* @see #addApplicationListenerBean(String)
* @see #removeApplicationListenerBeans(Predicate)
*/
void removeApplicationListenerBean(String listenerBeanName);

/**
* Remove all matching listeners from the set of registered
* {@code ApplicationListener} instances (which includes adapter classes
* such as {@link ApplicationListenerMethodAdapter}, e.g. for annotated
* {@link EventListener} methods).
* <p>Note: This just applies to instance registrations, not to listeners
* registered by bean name.
* @param predicate the predicate to identify listener instances to remove,
* e.g. checking {@link SmartApplicationListener#getListenerId()}
* @since 5.3.5
* @see #addApplicationListener(ApplicationListener)
* @see #removeApplicationListener(ApplicationListener)
*/
void removeApplicationListeners(Predicate<ApplicationListener<?>> predicate);

/**
* Remove all matching listener beans from the set of registered
* listener bean names (referring to bean classes which in turn
* implement the {@link ApplicationListener} interface directly).
* <p>Note: This just applies to bean name registrations, not to
* programmatically registered {@code ApplicationListener} instances.
* @param predicate the predicate to identify listener bean names to remove
* @since 5.3.5
* @see #addApplicationListenerBean(String)
* @see #removeApplicationListenerBean(String)
*/
void removeApplicationListenerBeans(Predicate<String> predicate);

/**
* Remove all listeners registered with this multicaster.
* <p>After a remove call, the multicaster will perform no action
* on event notification until new listeners are registered.
* @see #removeApplicationListeners(Predicate)
*/
void removeAllListeners();

/**
* Multicast the given application event to appropriate listeners.
* <p>Consider using {@link #multicastEvent(ApplicationEvent, ResolvableType)}
* if possible as it provides better support for generics-based events.
* @param event the event to multicast
*/
void multicastEvent(ApplicationEvent event);

/**
* Multicast the given application event to appropriate listeners.
* <p>If the {@code eventType} is {@code null}, a default type is built
* based on the {@code event} instance.
* @param event the event to multicast
* @param eventType the type of event (can be {@code null})
* @since 4.2
*/
void multicastEvent(ApplicationEvent event, @Nullable ResolvableType eventType);

}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
```



# 1.3 Event

## ApplicationEvent



## SpringApplicationEvent

```java
public abstract class SpringApplicationEvent extends ApplicationEvent {

private final String[] args;

public SpringApplicationEvent(SpringApplication application, String[] args) {
super(application);
this.args = args;
}

public SpringApplication getSpringApplication() {
return (SpringApplication) getSource();
}

public final String[] getArgs() {
return this.args;
}

}

第二章 环境加载 – Spring Boot

2.1 EnvironmentPostProcessor - Boot -

image-20230723171852456

Spring boot 注册到Spring Framework 到容器中,进行

1
2
3
4
5
6
7
8
9
10
11
@FunctionalInterface
public interface EnvironmentPostProcessor {

/**
* Post-process the given {@code environment}.
* @param environment the environment to post-process
* @param application the application to which the environment belongs
*/
void postProcessEnvironment(ConfigurableEnvironment environment, SpringApplication application);

}
1
2
3
4
5
6
7
8
# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,\
org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor

IntegrationPropertiesEnvironmentPostProcessor

继承EnvironmentPostProcessor, 初始化加载 PropertiesPropertySourceLoader

1
2
3
4
5
6
7
8
9
10
11
12
13
class IntegrationPropertiesEnvironmentPostProcessor implements EnvironmentPostProcessor, Ordered {
protected void registerIntegrationPropertiesPropertySource(ConfigurableEnvironment environment, Resource resource) {
PropertiesPropertySourceLoader loader = new PropertiesPropertySourceLoader();
try {
OriginTrackedMapPropertySource propertyFileSource = (OriginTrackedMapPropertySource) loader
.load("META-INF/spring.integration.properties", resource).get(0);
environment.getPropertySources().addLast(new IntegrationPropertiesPropertySource(propertyFileSource));
}
catch (IOException ex) {
throw new IllegalStateException("Failed to load integration properties from " + resource, ex);
}
}
}

1.2 PropertySourceLoader - 加载器

1
2
3
4
# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

PropertiesPropertySourceLoader

加载 Properties == .xml .properties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public class PropertiesPropertySourceLoader implements PropertySourceLoader {

private static final String XML_FILE_EXTENSION = ".xml";

@Override
public String[] getFileExtensions() {
return new String[] { "properties", "xml" };
}

@Override
public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
List<Map<String, ?>> properties = loadProperties(resource);
if (properties.isEmpty()) {
return Collections.emptyList();
}
List<PropertySource<?>> propertySources = new ArrayList<>(properties.size());
for (int i = 0; i < properties.size(); i++) {
String documentNumber = (properties.size() != 1) ? " (document #" + i + ")" : "";
propertySources.add(new OriginTrackedMapPropertySource(name + documentNumber,
Collections.unmodifiableMap(properties.get(i)), true));
}
return propertySources;
}

@SuppressWarnings({ "unchecked", "rawtypes" })
private List<Map<String, ?>> loadProperties(Resource resource) throws IOException {
String filename = resource.getFilename();
List<Map<String, ?>> result = new ArrayList<>();
if (filename != null && filename.endsWith(XML_FILE_EXTENSION)) {
result.add((Map) PropertiesLoaderUtils.loadProperties(resource));
}
else {
List<Document> documents = new OriginTrackedPropertiesLoader(resource).load();
documents.forEach((document) -> result.add(document.asMap()));
}
return result;
}

}

YamlPropertySourceLoader

加载 yml, yaml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
public class YamlPropertySourceLoader implements PropertySourceLoader {

@Override
public String[] getFileExtensions() {
return new String[] { "yml", "yaml" };
}

@Override
public List<PropertySource<?>> load(String name, Resource resource) throws IOException {
if (!ClassUtils.isPresent("org.yaml.snakeyaml.Yaml", getClass().getClassLoader())) {
throw new IllegalStateException(
"Attempted to load " + name + " but snakeyaml was not found on the classpath");
}
List<Map<String, Object>> loaded = new OriginTrackedYamlLoader(resource).load();
if (loaded.isEmpty()) {
return Collections.emptyList();
}
List<PropertySource<?>> propertySources = new ArrayList<>(loaded.size());
for (int i = 0; i < loaded.size(); i++) {
String documentNumber = (loaded.size() != 1) ? " (document #" + i + ")" : "";
propertySources.add(new OriginTrackedMapPropertySource(name + documentNumber,
Collections.unmodifiableMap(loaded.get(i)), true));
}
return propertySources;
}

}

2.3 Listener

EnvironmentPostProcessorApplicationListener –Spring boot

SmartApplicationListener. –Spring Context

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// SmartApplicationListener  -> ApplicationListener
// 能够被 Spring Context 的listener 回调函数调用
public interface SmartApplicationListener extends ApplicationListener<ApplicationEvent>, Ordered {

/**
* Determine whether this listener actually supports the given event type.
* @param eventType the event type (never {@code null})
*/
boolean supportsEventType(Class<? extends ApplicationEvent> eventType);

/**
* Determine whether this listener actually supports the given source type.
* <p>The default implementation always returns {@code true}.
* @param sourceType the source type, or {@code null} if no source
*/
default boolean supportsSourceType(@Nullable Class<?> sourceType) {
return true;
}

/**
* Determine this listener's order in a set of listeners for the same event.
* <p>The default implementation returns {@link #LOWEST_PRECEDENCE}.
*/
@Override
default int getOrder() {
return LOWEST_PRECEDENCE;
}

/**
* Return an optional identifier for the listener.
* <p>The default value is an empty String.
* @since 5.3.5
* @see EventListener#id
* @see ApplicationEventMulticaster#removeApplicationListeners
*/
default String getListenerId() {
return "";
}

EnvironmentPostProcessorApplicationListener

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
public class EnvironmentPostProcessorApplicationListener implements SmartApplicationListener, Ordered {
//
@Override
public void onApplicationEvent(ApplicationEvent event) {
if (event instanceof ApplicationEnvironmentPreparedEvent) {
onApplicationEnvironmentPreparedEvent((ApplicationEnvironmentPreparedEvent) event);
}
if (event instanceof ApplicationPreparedEvent) {
onApplicationPreparedEvent();
}
if (event instanceof ApplicationFailedEvent) {
onApplicationFailedEvent();
}
}
//
private void onApplicationEnvironmentPreparedEvent(ApplicationEnvironmentPreparedEvent event) {
ConfigurableEnvironment environment = event.getEnvironment();
SpringApplication application = event.getSpringApplication();
for (EnvironmentPostProcessor postProcessor : getEnvironmentPostProcessors(application.getResourceLoader(),
event.getBootstrapContext())) {
// 调用到 EnvironmentPostProcessor 的实现类
// 例如:IntegrationPropertiesEnvironmentPostProcessor 的 postProcessEnvironment
// IntegrationPropertiesEnvironmentPostProcessor 会 初始化PropertiesxxxLoader 加载 properties文件
postProcessor.postProcessEnvironment(environment, application);
}
}
// SpringApplication 的 ApplicationEnvironmentPreparedEvent() 事件
// 调用进行 环境准备
//ApplicationPreparedEvent. ApplicationFailedEvent
@Override
public boolean supportsEventType(Class<? extends ApplicationEvent> eventType) {
return ApplicationEnvironmentPreparedEvent.class.isAssignableFrom(eventType)
|| ApplicationPreparedEvent.class.isAssignableFrom(eventType)
|| ApplicationFailedEvent.class.isAssignableFrom(eventType);
}
}

第三部分 启动流程

3.0 @SpringBootApplication

SpringBootApplication

1
2
3
4
5
6
7
8
9
10
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}

EnableAutoConfiguration

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {

/**
* Environment property that can be used to override when auto-configuration is
* enabled.
*/
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";

/**
* Exclude specific auto-configuration classes such that they will never be applied.
* @return the classes to exclude
*/
Class<?>[] exclude() default {};

/**
* Exclude specific auto-configuration class names such that they will never be
* applied.
* @return the class names to exclude
* @since 1.3.0
*/
String[] excludeName() default {};

}

AutoConfigurationImportSelector

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {

private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();

private static final String[] NO_IMPORTS = {};

private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);

private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";

private ConfigurableListableBeanFactory beanFactory;

private Environment environment;

private ClassLoader beanClassLoader;

private ResourceLoader resourceLoader;

private ConfigurationClassFilter configurationClassFilter;

@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}

/**
* Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata}
* of the importing {@link Configuration @Configuration} class.
* @param annotationMetadata the annotation metadata of the configuration class
* @return the auto-configurations that should be imported
*/
protected AutoConfigurationEntry getAutoConfigurationEntry(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
configurations = getConfigurationClassFilter().filter(configurations);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
}

3.1 SpringApplication

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
	/**
* Create a new {@link SpringApplication} instance. The application context will load
* beans from the specified primary sources (see {@link SpringApplication class-level}
* documentation for details). The instance can be customized before calling
* {@link #run(String...)}.
* @param resourceLoader the resource loader to use
* @param primarySources the primary bean sources
* @see #run(Class, String[])
* @see #setSources(Set)
*/

// ## SpringApplication()
@SuppressWarnings({ "unchecked", "rawtypes" })
public SpringApplication(ResourceLoader resourceLoader, Class<?>... primarySources) {
this.resourceLoader = resourceLoader;
Assert.notNull(primarySources, "PrimarySources must not be null");
this.primarySources = new LinkedHashSet<>(Arrays.asList(primarySources));
this.webApplicationType = WebApplicationType.deduceFromClasspath();
this.bootstrapRegistryInitializers = new ArrayList<>(
getSpringFactoriesInstances(BootstrapRegistryInitializer.class));
setInitializers((Collection) getSpringFactoriesInstances(ApplicationContextInitializer.class));
setListeners((Collection) getSpringFactoriesInstances(ApplicationListener.class));
this.mainApplicationClass = deduceMainApplicationClass();
}


// ## run()
public ConfigurableApplicationContext run(String... args) {
long startTime = System.nanoTime();
// 一、
DefaultBootstrapContext bootstrapContext = createBootstrapContext();
ConfigurableApplicationContext context = null;
configureHeadlessProperty();
SpringApplicationRunListeners listeners = getRunListeners(args);
listeners.starting(bootstrapContext, this.mainApplicationClass);
try {
ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
ConfigurableEnvironment environment = prepareEnvironment(listeners, bootstrapContext, applicationArguments);
configureIgnoreBeanInfo(environment);
Banner printedBanner = printBanner(environment);
context = createApplicationContext();
context.setApplicationStartup(this.applicationStartup);
prepareContext(bootstrapContext, context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
Duration timeTakenToStartup = Duration.ofNanos(System.nanoTime() - startTime);
if (this.logStartupInfo) {
new StartupInfoLogger(this.mainApplicationClass).logStarted(getApplicationLog(), timeTakenToStartup);
}
listeners.started(context, timeTakenToStartup);
callRunners(context, applicationArguments);
}
catch (Throwable ex) {
handleRunFailure(context, ex, listeners);
throw new IllegalStateException(ex);
}
try {
Duration timeTakenToReady = Duration.ofNanos(System.nanoTime() - startTime);
listeners.ready(context, timeTakenToReady);
}
catch (Throwable ex) {
handleRunFailure(context, ex, null);
throw new IllegalStateException(ex);
}
return context;
}

3.2 run()

1

SpringBoot’s spring.facorties

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
# Logging Systems
org.springframework.boot.logging.LoggingSystemFactory=\
org.springframework.boot.logging.logback.LogbackLoggingSystem.Factory,\
org.springframework.boot.logging.log4j2.Log4J2LoggingSystem.Factory,\
org.springframework.boot.logging.java.JavaLoggingSystem.Factory

# PropertySource Loaders
org.springframework.boot.env.PropertySourceLoader=\
org.springframework.boot.env.PropertiesPropertySourceLoader,\
org.springframework.boot.env.YamlPropertySourceLoader

# ConfigData Location Resolvers
org.springframework.boot.context.config.ConfigDataLocationResolver=\
org.springframework.boot.context.config.ConfigTreeConfigDataLocationResolver,\
org.springframework.boot.context.config.StandardConfigDataLocationResolver

# ConfigData Loaders
org.springframework.boot.context.config.ConfigDataLoader=\
org.springframework.boot.context.config.ConfigTreeConfigDataLoader,\
org.springframework.boot.context.config.StandardConfigDataLoader

# Application Context Factories
org.springframework.boot.ApplicationContextFactory=\
org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext.Factory,\
org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext.Factory

# Run Listeners
org.springframework.boot.SpringApplicationRunListener=\
org.springframework.boot.context.event.EventPublishingRunListener

# Error Reporters
org.springframework.boot.SpringBootExceptionReporter=\
org.springframework.boot.diagnostics.FailureAnalyzers

# Application Context Initializers
org.springframework.context.ApplicationContextInitializer=\
org.springframework.boot.context.ConfigurationWarningsApplicationContextInitializer,\
org.springframework.boot.context.ContextIdApplicationContextInitializer,\
org.springframework.boot.context.config.DelegatingApplicationContextInitializer,\
org.springframework.boot.rsocket.context.RSocketPortInfoApplicationContextInitializer,\
org.springframework.boot.web.context.ServerPortInfoApplicationContextInitializer

# Application Listeners
org.springframework.context.ApplicationListener=\
org.springframework.boot.ClearCachesApplicationListener,\
org.springframework.boot.builder.ParentContextCloserApplicationListener,\
org.springframework.boot.context.FileEncodingApplicationListener,\
org.springframework.boot.context.config.AnsiOutputApplicationListener,\
org.springframework.boot.context.config.DelegatingApplicationListener,\
org.springframework.boot.context.logging.LoggingApplicationListener,\
org.springframework.boot.env.EnvironmentPostProcessorApplicationListener

# Environment Post Processors
org.springframework.boot.env.EnvironmentPostProcessor=\
org.springframework.boot.cloud.CloudFoundryVcapEnvironmentPostProcessor,\
org.springframework.boot.context.config.ConfigDataEnvironmentPostProcessor,\
org.springframework.boot.env.RandomValuePropertySourceEnvironmentPostProcessor,\
org.springframework.boot.env.SpringApplicationJsonEnvironmentPostProcessor,\
org.springframework.boot.env.SystemEnvironmentPropertySourceEnvironmentPostProcessor,\
org.springframework.boot.reactor.DebugAgentEnvironmentPostProcessor

# Failure Analyzers
org.springframework.boot.diagnostics.FailureAnalyzer=\
org.springframework.boot.context.config.ConfigDataNotFoundFailureAnalyzer,\
org.springframework.boot.context.properties.IncompatibleConfigurationFailureAnalyzer,\
org.springframework.boot.context.properties.NotConstructorBoundInjectionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanCurrentlyInCreationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanDefinitionOverrideFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BeanNotOfRequiredTypeFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.BindValidationFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.UnboundConfigurationPropertyFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.MutuallyExclusiveConfigurationPropertiesFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoSuchMethodFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.NoUniqueBeanDefinitionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PortInUseFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.ValidationExceptionFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyNameFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.InvalidConfigurationPropertyValueFailureAnalyzer,\
org.springframework.boot.diagnostics.analyzer.PatternParseFailureAnalyzer,\
org.springframework.boot.liquibase.LiquibaseChangelogMissingFailureAnalyzer,\
org.springframework.boot.web.context.MissingWebServerFactoryBeanFailureAnalyzer,\
org.springframework.boot.web.embedded.tomcat.ConnectorStartFailureAnalyzer

# Failure Analysis Reporters
org.springframework.boot.diagnostics.FailureAnalysisReporter=\
org.springframework.boot.diagnostics.LoggingFailureAnalysisReporter

# Database Initializer Detectors
org.springframework.boot.sql.init.dependency.DatabaseInitializerDetector=\
org.springframework.boot.flyway.FlywayDatabaseInitializerDetector,\
org.springframework.boot.jdbc.AbstractDataSourceInitializerDatabaseInitializerDetector,\
org.springframework.boot.jdbc.init.DataSourceScriptDatabaseInitializerDetector,\
org.springframework.boot.liquibase.LiquibaseDatabaseInitializerDetector,\
org.springframework.boot.orm.jpa.JpaDatabaseInitializerDetector,\
org.springframework.boot.r2dbc.init.R2dbcScriptDatabaseInitializerDetector

# Depends On Database Initialization Detectors
org.springframework.boot.sql.init.dependency.DependsOnDatabaseInitializationDetector=\
org.springframework.boot.sql.init.dependency.AnnotationDependsOnDatabaseInitializationDetector,\
org.springframework.boot.jdbc.SpringJdbcDependsOnDatabaseInitializationDetector,\
org.springframework.boot.jooq.JooqDependsOnDatabaseInitializationDetector,\
org.springframework.boot.orm.jpa.JpaDependsOnDatabaseInitializationDetector


Spring Boot + Framework
http://example.com/2023/07/30/Spring家族/Spring Boot + Framework/
作者
where
发布于
2023年7月30日
许可协议