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

22 KiB
Raw Blame History

Java and Spring

来源:原 mongodb 集合 t_blog · 整理日期:2026-08-25 分类 ID:00000000000002 · 排序:1 · 文章数:14

目录

  1. Springboot AbstractApplicationContext
  2. Map Set List
  3. Java8 AQS
  4. Java8 Stream
  5. Spring superinterface
  6. Springboot DefaultSingletonBeanRegistry
  7. Springboot SpringApplication
  8. Springboot AbstractBeanFactory
  9. Springboot AbstractAutowireCapableBeanFactory
  10. Springboot AbstractBeanDefinition
  11. Springboot ConfigurationClassPostProcessor
  12. Spring ASM
  13. PostProcessorRegistrationDelegate
  14. Spring Aop

1. Springboot AbstractApplicationContext

bid: 00000000000003

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

bid: 2022051816085000000000000006

1. Summary

我们在开发过程在,最常见的三种数据存储结构就是 Map Set 和List了

这三种结构最明显的特征就是Map 是键值,Set是对象存储唯一,List是有序数组

Map<K, V>

键值存储,主键不允许重复

添加元素 使用put方法,如果key重复,则value被覆盖

Set

对象存储,对象不允许重复

/**
 * 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

list是由数组构成的,这就意味着,list是有顺序的,因为数组在内存中是一段连续的内存。


3. Java8 AQS

bid: 2022052314143400000000000014

AQ


4. Java8 Stream

bid: 2022060810550500000000000022

S


5. Spring superinterface

bid: 2022120915183100000000000001

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

bid: 2022121513519200000000000002

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

bid: 2022121513597200000000000003

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

bid: 2022121515315000000000000004

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

bid: 2022121523309700000000000005

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

bid: 2022121523361800000000000006

AbstractBeanDefinition

AbstractBeanDefinition 定义了 一个bean的各种描述。

x.1

String[] dependsOn

Resource resource


11. Springboot ConfigurationClassPostProcessor

bid: 2022121612282000000000000009

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

bid: 2022121615335100000000000010

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

bid: 2022121915527600000000000011

PostProcessorRegistrationDelegate

作为 Delegate 提供了 静态方法 invokeBeanFactoryPostProcessors。

主要是将beanFactory和beanFactoryPostProcessors做matching, 然后对beanFactoryPostProcessors做遍历调用postProcessBeanFactory(beanFactory)

ConfigurationClassPostProcessor

postProcessBeanFactory(beanFactory)

processConfigBeanDefinitions(beanFactory)

核心的 处理方法,


14. Spring Aop

bid: 2022122715594900000000000012

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