Files
knowledge-base/语言/Java/Java and Spring.md
T
2026-08-25 22:44:19 +08:00

660 lines
22 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Java and Spring
> 来源:原 mongodb 集合 `t_blog` · 整理日期:2026-08-25
> 分类 ID:`00000000000002` · 排序:1 · 文章数:14
## 目录
1. [Springboot AbstractApplicationContext](#springboot-abstractapplicationcontext)
2. [Map Set List](#map-set-list)
3. [Java8 AQS](#java8-aqs)
4. [Java8 Stream](#java8-stream)
5. [Spring superinterface](#spring-superinterface)
6. [Springboot DefaultSingletonBeanRegistry](#springboot-defaultsingletonbeanregistry)
7. [Springboot SpringApplication](#springboot-springapplication)
8. [Springboot AbstractBeanFactory](#springboot-abstractbeanfactory)
9. [Springboot AbstractAutowireCapableBeanFactory](#springboot-abstractautowirecapablebeanfactory)
10. [Springboot AbstractBeanDefinition](#springboot-abstractbeandefinition)
11. [Springboot ConfigurationClassPostProcessor](#springboot-configurationclasspostprocessor)
12. [Spring ASM](#spring-asm)
13. [PostProcessorRegistrationDelegate](#postprocessorregistrationdelegate)
14. [Spring Aop](#spring-aop)
---
## 1. Springboot AbstractApplicationContext
<sub>bid: `00000000000003`</sub>
## AbstractApplicationContext
AbstractApplicationContext 是 SpringBoot的 核心应用上下文父类。
## x.1 properties
### beanFactoryPostProcessors
### environment
## x.2 methods
### refresh
refresh 是 Springboot启动中核心方法。
- prepareRefresh
- obtainFreshBeanFactory
- prepareBeanFactory
- postProcessBeanFactory
- invokeBeanFactoryPostProcessors
- registerBeanPostProcessors
- onRefresh
- finishBeanFactoryInitialization
- finishRefresh
---
## 2. Map Set List
<sub>bid: `2022051816085000000000000006`</sub>
### 1. Summary
我们在开发过程在,最常见的三种数据存储结构就是 Map Set 和List了
这三种结构最明显的特征就是Map 是键值,Set是对象存储唯一,List是有序数组
### Map<K, V>
键值存储,主键不允许重复
添加元素 使用put方法,如果key重复,则value被覆盖
### Set<E>
对象存储,对象不允许重复
/**
* if this set did not already contain the specified element will return {@code true}
* f this set already contains the element, the call leaves the set
* unchanged and returns {@code false}
*/
public boolean add(E e)
### List<E>
list是由数组构成的,这就意味着,list是有顺序的,因为数组在内存中是一段连续的内存。
---
## 3. Java8 AQS
<sub>bid: `2022052314143400000000000014`</sub>
## AQ
---
## 4. Java8 Stream
<sub>bid: `2022060810550500000000000022`</sub>
## S
---
## 5. Spring superinterface
<sub>bid: `2022120915183100000000000001`</sub>
## summary
## 1. Aware(感知)
Spring Ioc 是解耦行为,我们的业务代码其实是没有感知或者意识到spring框架的存在。如果我们需要使用spring Ioc中的资源时候,我们就需要有意识的去获取这个资源,而Aware 就是这样的存在。
@Service
public class AppContextAware implements ApplicationContextAware {
ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext=applicationContext;
}
public void hello(){
//user为容器中存在的bean
User user = applicationContext.getBean("user", User.class);
System.out.println(user);
//获取容器的环境、User.name为设置好的属性
Environment environment = applicationContext.getEnvironment();
String property = environment.getProperty("User.name");
System.out.println(" 属性:"+property);
}
}
一些常用的Aware interface
BeanNameAware
ApplicationContextAware
ResourceLoaderAware
EnvironmentAware
## 2. BeanFactory
BeanFactory 提供了获取bean和判断bean的方法,包括
getBean(String beanName)
getBean(String beanName, Class<T> requiredType)
getBean(Class<T> requiredType)
containsBean(String name)
isSingleton(String name)
isPrototype(String name)
sTypeMatch(String name)
getType(String name)
String[] getAliases(String name);
## 3. BeanPostProcessor
## 4. BeanFactoryPostProcessor
## 5. ApplicationContext
## 6. InitializingBean
---
## 6. Springboot DefaultSingletonBeanRegistry
<sub>bid: `2022121513519200000000000002`</sub>
## DefaultSingletonBeanRegistry
DefaultSingletonBeanRegistry 是Springboot bean 自动装配的核心实现类。
顾名思义,是默认的单例bean 注册器。
## x.1 properties
### dependentBeanMap
存放(依赖对象key -> 被依赖Set)的 ConcurrentHashMap
private final Map<String, Set<String>> dependentBeanMap = new ConcurrentHashMap<>(64);
### dependenciesForBeanMap
存放(被依赖对象key -> 依赖Set)的 ConcurrentHashMap
private final Map<String, Set<String>> dependenciesForBeanMap = new ConcurrentHashMap<>(64);
###
## x.2 methods
### registerDependentBean
我们知道Spring DI 依赖注入,此方法就是依赖注入的核心组成。注意,这段逻辑是加锁的,即存在并行处理逻辑。
Springboot 在 AbstractApplicationContext 进行 refresh 操作时候,在最后一步会实例化bean,参照AbstractApplicationContext.finishBeanFactoryInitialization 方法,此方法的流程我们会在xxx讲解。源码如下
/**
* Register a dependent bean for the given bean。
*/
public void registerDependentBean(String beanName, String dependentBeanName) {
String canonicalName = canonicalName(beanName);
synchronized (this.dependentBeanMap) {
Set<String> dependentBeans =
this.dependentBeanMap.computeIfAbsent(canonicalName, k -> new LinkedHashSet<>(8));
if (!dependentBeans.add(dependentBeanName)) {
return;
}
}
synchronized (this.dependenciesForBeanMap) {
Set<String> dependenciesForBean =
this.dependenciesForBeanMap.computeIfAbsent(dependentBeanName, k -> new LinkedHashSet<>(8));
dependenciesForBean.add(canonicalName);
}
}
DI 在此处的实现逻辑可以通过下面例子来通俗说明:
① A对象 依赖 B对象
② A对象 依赖 C对象
③ D对象 依赖 B对象
所以 必须要提前先把 B 对象和 C对象进行实例化后,才能 创建A对象和 D对象。
我们从RootBeanDefinition中获取 dependsOn的数组,遍历调用registerDependentBean方法
参数beanName是依赖对象,即 B 或者 C,参数dependentBeanName是被依赖对象A
1. 传入参数是 (B,A) 时,为 B 创建一个 LinkedHashSet,并在该Set中存放A, 并把 B -> Set的映射关系放入dependentBeanMap中。
紧接着 为 A 创建一个 LinkedHashSet, 并在该Set中存放B,并把 A -> Set的映射关系放入dependenciesForBeanMap中。
2. 传入参数是 (C, A) 时,为 C 创建一个 LinkedHashSet,并在该Set中存放A, 并把 C -> Set的映射关系放入dependentBeanMap中。
因为 dependenciesForBeanMap 已经存在了 A -> Set这个映射,我们只需将 C 也存入这个Set就可以。
3. 传入参数是 (B, D) 时,因为 dependentBeanMap 已经存在了 B -> Set这个映射,我们只需将 D 也存入这个Set就可以。
紧接着 为 D 创建一个 LinkedHashSet, 并在该Set中存放B,并把 D -> Set的映射关系放入dependenciesForBeanMap中。
`注意` 依赖和被依赖总是成对出现的,dependentBeans.add(dependentBeanName) 返回 false,视为添加失败,即视为已经存在,根据 依赖和被依赖总是成对出现的,所以后面dependenciesForBean.add(canonicalName) 这部分就没必要执行了,因为执行了也没有意义,所以直接 return了。毕竟dependenciesForBean中已经存在了canonicalName。
---
## 7. Springboot SpringApplication
<sub>bid: `2022121513597200000000000003`</sub>
## SpringApplication
## x.1 properties
### sources
### environment
### webApplicationType
###
## x.2 methods
### run
1. 创建 DefaultBootstrapContext
2. 获取 SpringApplicationRunListeners
3. 转换 ApplicationArguments 将commandLine args
4. 装备环境 ConfigurableEnvironment
5. 配置忽略bean情报 configureIgnoreBeanInfo
6. 创建 ApplicationContext
7. 准备 ApplicationContext prepareContext
设置上下文环境,加载source
8. 刷新 ApplicationContext
9. 刷新后处理
---
## 8. Springboot AbstractBeanFactory
<sub>bid: `2022121515315000000000000004`</sub>
## AbstractBeanFactory
## x.2 methods
### doGetBean
AbstractBeanFactory 的核心方法 doGetBean,doGetBean方法是由getBean调用的,如果有dependsOn存在,就会将注册依赖, 然调用getBean(dep),从而形成了递归操作。
当不存dependsOn的时候mbd.isSingleton 时候,就会调用 getSingleton方法,子类会回调createBean(beanName, mbd, args)方法,去创建bean。
源码
protected <T> T doGetBean(String name, @Nullable Class<T> requiredType) {
String beanName = transformedBeanName(name);
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
checkMergedBeanDefinition(mbd, beanName, args);
// Guarantee initialization of beans that the current bean depends on.
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
for (String dep : dependsOn) {
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
registerDependentBean(dep, beanName);
try {
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
// Create bean instance.
if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
beanInstance = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
}
---
## 9. Springboot AbstractAutowireCapableBeanFactory
<sub>bid: `2022121523309700000000000005`</sub>
## AbstractAutowireCapableBeanFactory
父类是AbstractBeanFactory,实现了AutowireCapableBeanFactory 的方法,其中最主要的还是createBean方法。
源码
/**
* Central method of this class: creates a bean instance,
* populates the bean instance, applies post-processors, etc.
* @see #doCreateBean
*/
@Override
protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
throws BeanCreationException {
if (logger.isTraceEnabled()) {
logger.trace("Creating instance of bean '" + beanName + "'");
}
RootBeanDefinition mbdToUse = mbd;
// Make sure bean class is actually resolved at this point, and
// clone the bean definition in case of a dynamically resolved Class
// which cannot be stored in the shared merged bean definition.
Class<?> resolvedClass = resolveBeanClass(mbd, beanName);
if (resolvedClass != null && !mbd.hasBeanClass() && mbd.getBeanClassName() != null) {
mbdToUse = new RootBeanDefinition(mbd);
mbdToUse.setBeanClass(resolvedClass);
}
// Prepare method overrides.
try {
mbdToUse.prepareMethodOverrides();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(mbdToUse.getResourceDescription(),
beanName, "Validation of method overrides failed", ex);
}
try {
// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
if (bean != null) {
return bean;
}
}
catch (Throwable ex) {
throw new BeanCreationException(mbdToUse.getResourceDescription(), beanName,
"BeanPostProcessor before instantiation of bean failed", ex);
}
try {
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
if (logger.isTraceEnabled()) {
logger.trace("Finished creating instance of bean '" + beanName + "'");
}
return beanInstance;
}
catch (BeanCreationException | ImplicitlyAppearedSingletonException ex) {
// A previously detected exception with proper bean creation context already,
// or illegal singleton state to be communicated up to DefaultSingletonBeanRegistry.
throw ex;
}
catch (Throwable ex) {
throw new BeanCreationException(
mbdToUse.getResourceDescription(), beanName, "Unexpected exception during bean creation", ex);
}
}
---
## 10. Springboot AbstractBeanDefinition
<sub>bid: `2022121523361800000000000006`</sub>
## AbstractBeanDefinition
AbstractBeanDefinition 定义了 一个bean的各种描述。
## x.1
### String[] dependsOn
### Resource resource
###
---
## 11. Springboot ConfigurationClassPostProcessor
<sub>bid: `2022121612282000000000000009`</sub>
## ConfigurationClassPostProcessor
这一节主要讲的是ConfigurationClassPostProcessor和他的一些生态。
他的生态有
- ConfigurationClassParser 真正的处理者。
- ComponentScanAnnotationParser 扫描classpath,把beanName加入到registry的beanDefinitionMap中。
- doProcessConfigurationClass 是该 postProcessor最核心的处理方法
/**
* Apply processing and build a complete {@link ConfigurationClass} by reading the
* annotations, members and methods from the source class. This method can be called
* multiple times as relevant sources are discovered.
* @param configClass the configuration class being build
* @param sourceClass a source class
* @return the superclass, or {@code null} if none found or previously processed
*/
@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.environment instanceof ConfigurableEnvironment) {
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;
}
---
## 12. Spring ASM
<sub>bid: `2022121615335100000000000010`</sub>
## asm
在spring中其实很少听到asm这个关键字,asm -> Assembly,跟多是指汇编语言。
spring也是用到asm,而且asm包是spring-core的组成部分。spring asm 大体上跟 原生的asm 都是差不多了。
(参照链接)[ https://docs.spring.io/spring-framework/docs/current/javadoc-api/org/springframework/asm/package-summary.htm ]
package org.springframework.asm
Spring's repackaging of ASM 9.x (with Spring-specific patches; for internal use only).
This repackaging technique avoids any potential conflicts with dependencies on ASM at the application level or from third-party libraries and frameworks.
As this repackaging happens at the class file level, sources and javadocs are not available here.
从package-info可以看出,repackaging,avoids any potential conflicts
---
## 13. PostProcessorRegistrationDelegate
<sub>bid: `2022121915527600000000000011`</sub>
## PostProcessorRegistrationDelegate
作为 Delegate 提供了 静态方法 invokeBeanFactoryPostProcessors。
主要是将beanFactory和beanFactoryPostProcessors做matching,
然后对beanFactoryPostProcessors做遍历调用postProcessBeanFactory(beanFactory)
## ConfigurationClassPostProcessor
postProcessBeanFactory(beanFactory)
processConfigBeanDefinitions(beanFactory)
核心的 处理方法,
---
## 14. Spring Aop
<sub>bid: `2022122715594900000000000012`</sub>
## Aop
Aspect Oriented Programming的缩写,意为:面向切面编程。
Spring aop 作为spring的一个模块,在springboot中是在bean的实例化中使用的。
AbstractAutowireCapableBeanFactory#initializeBean
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
invokeAwareMethods(beanName, bean);
return null;
}, getAccessControlContext());
}
else {
# 实现了Aware接口<BeanNameAware><BeanClassLoaderAware><BeanFactoryAware>会invoke对应的set方法。
invokeAwareMethods(beanName, bean);
}
Object wrappedBean = bean;
if (mbd == null || !mbd.isSynthetic()) {
# beanPostProcesser的before方法。
wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}
try {
# 实现了InitializingBean接口的会invoke afterPropertiesSet方法。
invokeInitMethods(beanName, wrappedBean, mbd);
}
catch (Throwable ex) {
throw new BeanCreationException(
(mbd != null ? mbd.getResourceDescription() : null),
beanName, "Invocation of init method failed", ex);
}
if (mbd == null || !mbd.isSynthetic()) {
# beanPostProcesser的after方法。
wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
}
return wrappedBean;
}
AbstractAdvisingBeanPostProcessor#postProcessAfterInitialization
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (this.advisor == null || bean instanceof AopInfrastructureBean) {
// Ignore AOP infrastructure such as scoped proxies.
return bean;
}
if (bean instanceof Advised) {
Advised advised = (Advised) bean;
if (!advised.isFrozen() && isEligible(AopUtils.getTargetClass(bean))) {
// Add our local Advisor to the existing proxy's Advisor chain...
if (this.beforeExistingAdvisors) {
advised.addAdvisor(0, this.advisor);
}
else {
advised.addAdvisor(this.advisor);
}
return bean;
}
}
if (isEligible(bean, beanName)) {
ProxyFactory proxyFactory = prepareProxyFactory(bean, beanName);
if (!proxyFactory.isProxyTargetClass()) {
evaluateProxyInterfaces(bean.getClass(), proxyFactory);
}
proxyFactory.addAdvisor(this.advisor);
customizeProxyFactory(proxyFactory);
// Use original ClassLoader if bean class not locally loaded in overriding class loader
ClassLoader classLoader = getProxyClassLoader();
if (classLoader instanceof SmartClassLoader && classLoader != bean.getClass().getClassLoader()) {
classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
}
# ProxyFactory 其实就是创建动态代理或者Cglib的 InvocationHandler调用Proxy.newProxyInstance返回代理对象
return proxyFactory.getProxy(classLoader);
}
// No proxy needed.
return bean;
}
---