notes notes
首页
读书笔记
系统设计
项目实战
学习笔记
源码
运维
其它
极客时间 (opens new window)
GitHub (opens new window)
首页
读书笔记
系统设计
项目实战
学习笔记
源码
运维
其它
极客时间 (opens new window)
GitHub (opens new window)
  • 并发编程

    • 并发编程
    • 多线程
    • 高级篇
  • 设计模式

    • 设计模式
  • 网络编程

    • Netty

      • NIO基础
      • Netty入门
      • Netty进阶
      • 优化与源码
  • 源码篇

    • 环境搭建
    • Spring
      • 核心注解
      • 回顾 @Import和 @Loopup
      • Spring概述
      • debug Spring流程概述
        • refresh
        • prepareRefresh
        • obtainFreshBeanFactory
        • refreshBeanFactory
        • getBeanFactory
        • prepareBeanFactory
        • finishBeanFactoryInitialization
        • preInstantiateSingletons
      • 启动流程细节
      • 配置文件加载过程
  • 云原生

    • Kubernetes
    • Helm
  • ElasticSearch

    • ElasticSearch
  • Java 虚拟机

    • 深入拆解 Java 虚拟机
    • JVM与GC调优
  • MQ

    • RabbitMQ

      • RabbitMQ笔记
      • RabbitMQ集群搭建文档
  • Redis

    • Redis进阶
  • ShardingSphere

    • Sharding-JDBC
  • SpringCloud

    • SpringCloud
  • ZooKeeper

    • ZooKeeper
  • 学习笔记
  • 源码篇
starry
2023-08-03
目录

Spring

# 核心注解

注解 功能
@Bean 容器中注册组件
@Primary 同类组件如果有多个,标注主组件
@DependsOn 组件之间声明依赖关系
@Lazy 组件懒加载(最后使用的时候才创建)
@Scope 声明组件的作用范围(SCOPE_PROTOTYPE,SCOPE_SINGLETON)
@Configuration 声明这是一个配置类,替换以前配置文件
@Component @Controller、@Service、@Repository
@Indexed 加速注解,所有标注了 @Indexed 的组件,直接会启动快速加载
@Order 数字越小优先级越高,越先工作
@ComponentScan 包扫描
@Conditional 条件注入
@Import 导入第三方jar包中的组件,或定制批量导入组件逻辑
@ImportResource 导入以前的xml配置文件,让其生效
@Profile 基于多环境激活
@PropertySource 外部properties配置文件和JavaBean进行绑定.结合ConfigurationProperties
@PropertySources @PropertySource组合注解
@Autowired 自动装配
@Qualifier 精确指定
@Value 取值、计算机环境变量、JVM系统。xxxx。@Value(“${xx}”)
@Lookup 单例组件依赖非单例组件,非单例组件获取需要使用方法

注:@Indexed 需要引入依赖

<dependency>	
  <groupId>org.springframework</groupId>	
  <artifactId>spring-context-indexer</artifactId>	
  <optional>true</optional>
</dependency>

# 回顾 @Import和 @Loopup

之前我们用xml的方式读取bean的配置 ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext_(_"beans.xml"_)_;

还可以用注解的方式

查看关系图 Ctrl + Alt + Shift + U image.png 我们使用的是ApplicationContext image.pngCtrl + Alt + B,查看ApplicationContext的实现,其中就有AnnotationConfigApplicationContext,加载基于注解的bean配置 image.png 使用@Configuration+ 注解扫描

@Configuration
public class MainConfig {

	@Bean
	public Person person() {
        // 自定义属性
		Person person = new Person();
		person.setName("张三");
		return person;
	}
}
public class AnnotationMainTest {

	public static void main(String[] args) {
		// 传入配置类
		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(MainConfig.class);
		Person person = applicationContext.getBean(Person.class);
		System.out.println(person);

	}
}

输出

Person{name='张三'}

使用 @Import + 注解扫描

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Import {

	/**
	 * 1.直接传入Class:Person{name='null'},无参构造对象放入容器
	 * 2.ImportSelector
	 * 3.ImportBeanDefinitionRegistrar
	 * {@link Configuration @Configuration}, {@link ImportSelector},
	 * {@link ImportBeanDefinitionRegistrar}, or regular component classes to import.
	 */
	Class<?>[] value();

}

修改配置类

@Import(Person.class)
@Configuration
public class MainConfig {

	//@Bean
	//public Person person() {
	//	Person person = new Person();
	//	person.setName("张三");
	//	return person;
	//}
}

再次运行,输出

Person{name='null'}

# Spring概述

简化流程

  • 加载xml
  • 解析xml
  • 封装BeanDefinition
  • 实例化
  • 放入容器
  • 从容器中获取

容器就是Map,大体上分为

  • k:String, v:Object。k为beanName,v为bean实例
  • k:Class, v:Object。k为bean的Class,v为bean实例
  • k:String, v:ObjectFactory。为了解决循环依赖
  • k:String, v:BeanDefinition。将解析的xml内容封装为BeanDefinition,Bean的定义信息

资源加载 BeanDefinitionReader 通过xml,properties等加载我们的bean的配置 image.png image.png

# debug Spring流程概述

打断点

public class MainTest {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
		Person person = applicationContext.getBean(Person.class);
		System.out.println("### person.getName() = " + person.getName());
	}
}

各种重载最后到ClassPathXmlApplicationContext.java

public ClassPathXmlApplicationContext(
        String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
        throws BeansException {

    // 调用父类构造方法,相关对象创建,parent=null
    super(parent);
    // 设置配置文件路径,beans.xml
    setConfigLocations(configLocations);
    if (refresh) {
        // 准备工作
        refresh();
    }
}

调用父类的refresh方法AbstractApplicationContext.java

# refresh

	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			/*
			 * refresh context前进行的准备工作
			 * ● 记录开始时间
			 * ● 设置关闭状态为false
			 * ● 设置活跃状态为true
			 * ● 加载系统属性到Environment对象中,并验证必须属性是否可加载
			 * ● 准备监听器和事件集合,默认为空
			 */
			// 容器前期准备工作
			prepareRefresh();

			/*
			 * 子类刷新内部beanFactory,返回DefaultListableBeanFactory
			 * 加载、解析beanDefinition
			 */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// beanFactory的初始化,设置一堆对象和属性
			// beanFactory前期准备工作
			prepareBeanFactory(beanFactory);

			try {
				// 空方法,子类可自定义扩展
				// 此时,beanFactory初始化完成,所有的beanDefinition都将被加载,但是bean还没有实例化
				postProcessBeanFactory(beanFactory);

				// 执行之前beanFactory中注册的所有的BeanFactoryPostProcessor的postProcessBeanFactory方法
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册BeanPostProcessors
				registerBeanPostProcessors(beanFactory);

				// 初始化initMessageSource(国际化,i18n)
				initMessageSource();

				// 初始化事件多播器(广播器)
				initApplicationEventMulticaster();

				// 空方法,方便扩展。初始化特定上下文子类中的其他特殊 bean,在创建bean实例前
				onRefresh();

				// 检查并注册监听器
				registerListeners();

				// 实例化其余所有非懒加载的单例对象(重要方法)
				finishBeanFactoryInitialization(beanFactory);

				// 最后一步:发布相应的事件。
				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 {
				// 重置 Spring 常见的反射元数据缓存,因为我们可能不再需要单例 bean 的元数据了......
				resetCommonCaches();
			}
		}
	}

# prepareRefresh

refresh context前进行的准备工作

  • 记录开始时间
  • 设置关闭状态为false
  • 设置活跃状态为true
  • 加载系统属性到Environment对象中,并验证必须属性是否可加载
  • 准备监听器和事件集合,默认为空
protected void prepareRefresh() {
		// 记录开始时间
		this.startupDate = System.currentTimeMillis();
        // 切换标志位
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

        // 初始化context中的占位符的属性源,默认为null,由子类重写方法
		initPropertySources();

        // 验证所有被标记为required的属性都是可解析的:
		// see ConfigurablePropertyResolver#setRequiredProperties
		getEnvironment().validateRequiredProperties();

        // 存储预刷新的应用监听器
		if (this.earlyApplicationListeners == null) {
            // 应用程序监听器,这里是空集合,方便其他框架扩展
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
            // 重置预刷新的应用程序监听器状态
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

        // 允许收集早期应用程序事件,一旦多播器可用就发布...
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

# obtainFreshBeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
		refreshBeanFactory();
		return getBeanFactory();
	}

AbstractRefreshableApplicationContext.java

# refreshBeanFactory
  • 创建一个新的beanFactory
  • 配置属性
  • 加载beanDefinition
protected final void refreshBeanFactory() throws BeansException {
        // 之前有beanFactory
		if (hasBeanFactory()) {
            // 销毁所有的bean
			destroyBeans();
            // 关闭之前的beanFactory
			closeBeanFactory();
		}
		try {
            // 创建一个默认beanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 设置序列化id
			beanFactory.setSerializationId(getId());
            // 自定义beanFactory的两个配置
			customizeBeanFactory(beanFactory);
            // 加载并解析bean的定义信息
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}


protected DefaultListableBeanFactory createBeanFactory() {
		return new DefaultListableBeanFactory(getInternalParentBeanFactory());
	}


protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
        // 默认 allowBeanDefinitionOverriding 和 allowCircularReferences 都是true
        // 如果自定义了这两个参数,就使用自定义的
    
        // 是否允许beanDefinition被重写
		if (this.allowBeanDefinitionOverriding != null) {
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
        // 是否允许循环依赖
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}
# getBeanFactory
  • 判断beanFactory是否为null(为初始化完成/已经关闭)
  • 返回beanFactory
public final ConfigurableListableBeanFactory getBeanFactory() {
		DefaultListableBeanFactory beanFactory = this.beanFactory;
		if (beanFactory == null) {
			throw new IllegalStateException("BeanFactory not initialized or already closed - " +
					"call 'refresh' before accessing beans via the ApplicationContext");
		}
		return beanFactory;
	}

# prepareBeanFactory

  • 完成beanFactory的初始化,设置和添加一堆对象
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        // 设置类加载器
		beanFactory.setBeanClassLoader(getClassLoader());
        // 设置SPEL表达式的解析器
		beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
        // 添加属性编辑器注册器
		beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));

		// 添加bean的增强器
		beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
        // 忽略Aware接口
		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 interface not registered as resolvable type in a plain factory.
		// MessageSource registered (and found for autowiring) as a bean.
		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 (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());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
		}
		if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
			beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
		}
	}

总体来说就是图上的内容

# finishBeanFactoryInitialization

实例化其余所有非懒加载的单例对象(重要方法)

	protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
		// 设置类型转换服务
		if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
				beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
			beanFactory.setConversionService(
					beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
		}

        // 如果之前没有注册过任何 bean 后处理器(例如 PropertyPlaceholderConfigurer bean),则注册一个默认的嵌入值解析器:此时,主要用于解析注释属性值。
		if (!beanFactory.hasEmbeddedValueResolver()) {
			beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
		}

		// 初始化所有实现了LoadTimeWeaverAware接口的子类,用于类在加载进入jvm之前,动态增强类,这特别适用于Spring的JPA支持,其中load-time weaving加载织入对JPA类转换非常必要
		String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
		for (String weaverAwareName : weaverAwareNames) {
            // 实例化bean
			getBean(weaverAwareName);
		}

		// 停止使用临时的类加载器进行类型匹配
		beanFactory.setTempClassLoader(null);

		// 缓存(冻结)所有的BeanName(注册的bean定义不会被修改或进一步做处理了,因为下面马上要创建Bean的实例对象了)
		beanFactory.freezeConfiguration();

		// 实例化剩下所有非懒加载的单例bean
		beanFactory.preInstantiateSingletons();
	}
# preInstantiateSingletons

DefaultListableBeanFactory.java

	public void preInstantiateSingletons() throws BeansException {
		if (logger.isTraceEnabled()) {
			logger.trace("Pre-instantiating singletons in " + this);
		}

		// 迭代一个副本以允许 init 方法依次注册新的 beanDefinition
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// 遍历所有的beanDefinition,触发单例bean的实例化
		for (String beanName : beanNames) {
            // 获取beanName对应的MergedBeanDefinition.在实例化之前将所有的beanDefiniton对象在转换成RootBeanDefinition,进行缓存,后续在需要马上实例化的时候直接获取定义信息,而定义信息中如果包含了父类就需要先实例化父类。
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
            // 不是抽象类、是单例、不是懒加载
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
                // 实现了FactoryBean接口
				if (isFactoryBean(beanName)) {
                    // 前缀&,获取FactoryBean的实例,而不是工厂要创建bean的实例
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged(
									(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						}
						else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
                            // 如果着急初始化,则通过getBean获得bean的实例
							getBean(beanName);
						}
					}
				}
				else {
                    // 未实现FactoryBean接口,直接getBean
					getBean(beanName);
				}
			}
		}

		// 对实例完的bean进行后置处理,如果实现了SmartInitializingSingleton接口
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				}
				else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
	}

# 启动流程细节

public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application-${username}.xml");
		//Person person = applicationContext.getBean(Person.class);
		//System.out.println("### person.getName() = " + person.getName());
	}

ClassPathXmlApplicationContext.java

public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
    this(new String[] {configLocation}, true, null);
}
// 重载方法
public ClassPathXmlApplicationContext(
        String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
        throws BeansException {

    // 调用父类构造方法,相关对象创建,parent=null
    super(parent);
    setConfigLocations(configLocations);
    if (refresh) {
        // 准备工作
        refresh();
    }
}

一直调用父类构造方法,最终到AbstractApplicationContext.java



	/** 生成唯一id */
	private String id = ObjectUtils.identityToString(this);

	/** 显示名称 */
	private String displayName = ObjectUtils.identityToString(this);

	/** 父容器,null */
	@Nullable
	private ApplicationContext parent;

	/** 容器使用的环境 */
	@Nullable
	private ConfigurableEnvironment environment;

	/** beanFactory增强 */
	private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();

	/** 开始时间 */
	private long startupDate;

	/** 容器是活跃状态 */
	private final AtomicBoolean active = new AtomicBoolean();

	/** 容器已经关闭 */
	private final AtomicBoolean closed = new AtomicBoolean();

	/** refresh 和 destroy 时的锁的监视器 */
	private final Object startupShutdownMonitor = new Object();

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

	/** 资源匹配解析器 */
	private ResourcePatternResolver resourcePatternResolver;

	/** LifecycleProcessor 管理bean的生命周期 */
	@Nullable
	private LifecycleProcessor lifecycleProcessor;

	/** 国际化 i18n*/
	@Nullable
	private MessageSource messageSource;

	/** 事件发布中使用的helper类。 */
	@Nullable
	private ApplicationEventMulticaster applicationEventMulticaster;

	/** 监听器 */
	private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();

	/** 监听器在refresh之前 */
	@Nullable
	private Set<ApplicationListener<?>> earlyApplicationListeners;

	/** ApplicationEvents 在多播器设置之前发布。 */
	@Nullable
	private Set<ApplicationEvent> earlyApplicationEvents;



public AbstractApplicationContext(@Nullable ApplicationContext parent) {
        // 调用本类无参构造
		this();
		setParent(parent);
	}


public AbstractApplicationContext() {
        // 创建资源模式解析器,解析我们的配置文件资源(解析资源,不是内容)
		this.resourcePatternResolver = getResourcePatternResolver();
	}




protected ResourcePatternResolver getResourcePatternResolver() {
        // 路径匹配资源模式解析器
		return new PathMatchingResourcePatternResolver(this);
        /*
        * private PathMatcher pathMatcher = new AntPathMatcher();
        * 使用ant路径匹配
        */
	}



image.png 构造方法走完了,继续 setParent(parent);

public void setParent(@Nullable ApplicationContext parent) {
		this.parent = parent;
        // 这里的parent为null
		if (parent != null) {
            // 单纯spring环境没有父子容器,到mvc的时候有父子容器
			Environment parentEnvironment = parent.getEnvironment();
            // 获取父容器环境,如果父容器的环境是可配置的,就进行merge合并
			if (parentEnvironment instanceof ConfigurableEnvironment) {
				getEnvironment().merge((ConfigurableEnvironment) parentEnvironment);
			}
		}
	}

根父类的构造方法执行完了,往回走继续执行其他的父类构造方法 来到AbstractXmlApplicationContext.java

	// 是否进行xml格式校验,默认true,xsd/dtd
	private boolean validating = true;

至此super(parent);调用父类构造方法,初始化成员属性,就完成了,接下来到setConfigLocations(configLocations); AbstractRefreshableConfigApplicationContext.java

private String[] configLocations;

public void setConfigLocations(@Nullable String... locations) {
		if (locations != null) {
			Assert.noNullElements(locations, "Config locations must not be null");
			this.configLocations = new String[locations.length];
            // 将我们传入的配置文件逐一进行解析
			for (int i = 0; i < locations.length; i++) {
				this.configLocations[i] = resolvePath(locations[i]).trim();
			}
		}
		else {
			this.configLocations = null;
		}
	}


/**
 * 解析给定的路径,如有必要,将占位符替换为相应的环境属性
 */
protected String resolvePath(String path) {
		return getEnvironment().resolveRequiredPlaceholders(path);
	}

获取环境对象AbstractApplicationContext.java

public ConfigurableEnvironment getEnvironment() {
		if (this.environment == null) {
            // 没有就创建一个标准的环境对象
			this.environment = createEnvironment();
		}
		return this.environment;
	}


protected ConfigurableEnvironment createEnvironment() {
		return new StandardEnvironment();
	}


创建标准环境隐式调用父类构造方法,设置一些属性AbstractEnvironment.java

public static final String IGNORE_GETENV_PROPERTY_NAME = "spring.getenv.ignore";
public static final String ACTIVE_PROFILES_PROPERTY_NAME = "spring.profiles.active";
public static final String DEFAULT_PROFILES_PROPERTY_NAME = "spring.profiles.default";
protected static final String RESERVED_DEFAULT_PROFILE_NAME = "default";
protected final Log logger = LogFactory.getLog(getClass());
private final Set<String> activeProfiles = new LinkedHashSet<>();
private final Set<String> defaultProfiles = new LinkedHashSet<>(getReservedDefaultProfiles());
private final MutablePropertySources propertySources = new MutablePropertySources();
private final ConfigurablePropertyResolver propertyResolver =
        new PropertySourcesPropertyResolver(this.propertySources);


public AbstractEnvironment() {
        // 调用子类实现
		customizePropertySources(this.propertySources);
	}

子类方法AbstractApplicationContext.java

// 父类调用此方法 自定义属性源
protected void customizePropertySources(MutablePropertySources propertySources) {
		propertySources.addLast(
				new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties()));
		propertySources.addLast(
				new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment()));
	}

获取系统配置和环境AbstractEnvironment.java

public Map<String, Object> getSystemProperties() {
		try {
			return (Map) System.getProperties();
		}
		catch (AccessControlException ex) {
			return (Map) new ReadOnlySystemAttributesMap() {
				@Override
				@Nullable
				protected String getSystemAttribute(String attributeName) {
					try {
						return System.getProperty(attributeName);
					}
					catch (AccessControlException ex) {
						if (logger.isInfoEnabled()) {
							logger.info("Caught AccessControlException when accessing system property '" +
									attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage());
						}
						return null;
					}
				}
			};
		}
	}

	public Map<String, Object> getSystemEnvironment() {
		if (suppressGetenvAccess()) {
			return Collections.emptyMap();
		}
		try {
			return (Map) System.getenv();
		}
		catch (AccessControlException ex) {
			return (Map) new ReadOnlySystemAttributesMap() {
				@Override
				@Nullable
				protected String getSystemAttribute(String attributeName) {
					try {
						return System.getenv(attributeName);
					}
					catch (AccessControlException ex) {
						if (logger.isInfoEnabled()) {
							logger.info("Caught AccessControlException when accessing system environment variable '" +
									attributeName + "'; its value will be returned [null]. Reason: " + ex.getMessage());
						}
						return null;
					}
				}
			};
		}
	}

System.java

public static Properties getProperties() {
        SecurityManager sm = getSecurityManager();
        if (sm != null) {
            sm.checkPropertiesAccess();
        }

        return props;
    }


public static java.util.Map<String,String> getenv() {
        SecurityManager sm = getSecurityManager();
        if (sm != null) {
            sm.checkPermission(new RuntimePermission("getenv.*"));
        }

        return ProcessEnvironment.getenv();
    }

至此环境对象创建完毕 image.png 注意:系统环境中有个username的key image.png Environment对象创建完了,接下来要进行解析占位符resolveRequiredPlaceholders 一直到 PropertyPlaceholderHelper.java 才是真正的解析

	protected String parseStringValue(
			String value, PlaceholderResolver placeholderResolver, @Nullable Set<String> visitedPlaceholders) {

        // 找到占位符的开始索引 ${
		int startIndex = value.indexOf(this.placeholderPrefix);
        // 遍历完了
		if (startIndex == -1) {
			return value;
		}

		StringBuilder result = new StringBuilder(value);
        // 还没遍历完
		while (startIndex != -1) {
            // 占位符的结束位置 }
			int endIndex = findPlaceholderEndIndex(result, startIndex);
			if (endIndex != -1) {
                // 截取占位符中的内容
				String placeholder = result.substring(startIndex + this.placeholderPrefix.length(), endIndex);
				String originalPlaceholder = placeholder;
				if (visitedPlaceholders == null) {
                    // 存放找到的占位符中的内容
					visitedPlaceholders = new HashSet<>(4);
				}
                // 解析到占位符的内容放入set
				if (!visitedPlaceholders.add(originalPlaceholder)) {
					throw new IllegalArgumentException(
							"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
				}
				// 递归解析 eg:${aaa${bbb}}
				placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
				// 从环境对象中的的系统属性和环境中找到匹配的属性值
				String propVal = placeholderResolver.resolvePlaceholder(placeholder);
                // 环境中找不到对应的值,但是找到了分隔符 : ${server.port:8888},就使用冒号后的值
				if (propVal == null && this.valueSeparator != null) {
					int separatorIndex = placeholder.indexOf(this.valueSeparator);
					if (separatorIndex != -1) {
						String actualPlaceholder = placeholder.substring(0, separatorIndex);
						String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
						propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
						if (propVal == null) {
							propVal = defaultValue;
						}
					}
				}
				if (propVal != null) {
					// 递归
					propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
                    // 字符串替换,将占位符替换为属性值
					result.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
					if (logger.isTraceEnabled()) {
						logger.trace("Resolved placeholder '" + placeholder + "'");
					}
					startIndex = result.indexOf(this.placeholderPrefix, startIndex + propVal.length());
				}
				else if (this.ignoreUnresolvablePlaceholders) {
					// Proceed with unprocessed value.
					startIndex = result.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
				}
				else {
					throw new IllegalArgumentException("Could not resolve placeholder '" +
							placeholder + "'" + " in value \"" + value + "\"");
				}
                // set中移除已经解析完的占位符
				visitedPlaceholders.remove(originalPlaceholder);
			}
			else {
				startIndex = -1;
			}
		}
        // 返回的就是替换完占位符后的字符串
		return result.toString();
	}

placeholderResolver.resolvePlaceholder(placeholder)最终走到这里PropertySourcesPropertyResolver.java

protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
		if (this.propertySources != null) {
            // 遍历systemProperties和systemEnvironment(之前Environment对象初始化时添加的)
			for (PropertySource<?> propertySource : this.propertySources) {
				if (logger.isTraceEnabled()) {
					logger.trace("Searching for key '" + key + "' in PropertySource '" +
							propertySource.getName() + "'");
				}
				Object value = propertySource.getProperty(key);
				if (value != null) {
					if (resolveNestedPlaceholders && value instanceof String) {
						value = resolveNestedPlaceholders((String) value);
					}
					logKeyFound(key, propertySource, value);
					return convertValueIfNecessary(value, targetValueType);
				}
			}
		}
		if (logger.isTraceEnabled()) {
			logger.trace("Could not find key '" + key + "' in any property source");
		}
		return null;
	}

传入的每个配置文件都进行解析替换,setConfigLocations_(_configLocations_)_;就执行完了 image.png 来到最重要的refresh()

	@Override
	public void refresh() throws BeansException, IllegalStateException {
        // 加锁,初始化
		synchronized (this.startupShutdownMonitor) {
			/*
			 * refresh context前进行的准备工作
			 * ● 记录开始时间
			 * ● 设置关闭状态为false
			 * ● 设置活跃状态为true
			 * ● 加载系统属性到Environment对象中,并验证必须属性是否可加载
			 * ● 准备监听器和事件集合,默认为空
			 */
			// 容器前期准备工作
			prepareRefresh();

			/*
			 * 子类刷新内部beanFactory,返回DefaultListableBeanFactory
			 * 加载、解析beanDefinition
			 */
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// beanFactory的初始化,设置一堆对象和属性
			// beanFactory前期准备工作
			prepareBeanFactory(beanFactory);

			try {
				// 空方法,子类可自定义扩展
				// 此时,beanFactory初始化完成,所有的beanDefinition都将被加载,但是bean还没有实例化
				postProcessBeanFactory(beanFactory);

				// 执行之前beanFactory中注册的所有的BeanFactoryPostProcessor的postProcessBeanFactory方法
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注册BeanPostProcessors
				registerBeanPostProcessors(beanFactory);

				// 初始化initMessageSource
				initMessageSource();

				// 初始化事件多播器(广播器)
				initApplicationEventMulticaster();

				// 空方法,子类扩展。初始化特定上下文子类中的其他特殊 bean,在创建bean实例前
				onRefresh();

				// 检查并注册监听器
				registerListeners();

				// 实例化其余所有非懒加载的单例对象
				finishBeanFactoryInitialization(beanFactory);

				// 最后一步:发布相应的事件。
				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 {
				// 重置 Spring 常见的反射元数据缓存,因为我们可能不再需要单例 bean 的元数据了......
				resetCommonCaches();
			}
		}
	}



prepareRefresh

protected void prepareRefresh() {
		// 开始时间
		this.startupDate = System.currentTimeMillis();
		// 设置标志位
		this.closed.set(false);
		this.active.set(true);

		if (logger.isDebugEnabled()) {
			if (logger.isTraceEnabled()) {
				logger.trace("Refreshing " + this);
			}
			else {
				logger.debug("Refreshing " + getDisplayName());
			}
		}

		// 留给子类扩展,初始化属性资源
		initPropertySources();

		// see ConfigurablePropertyResolver#setRequiredProperties
		// 验证必需环境,之前创建的标准环境对象,默认必需属性是null
		getEnvironment().validateRequiredProperties();

        // 这些集合在spring中都是空的,留给其他框架做扩展
    
		// 判断刷新前的应用程序监听器集合是否为空,如果为空,将监听器加入到集合
		if (this.earlyApplicationListeners == null) {
			this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
		}
		else {
            // 集合不等于空,清空集合,放入刷新前的应用程序监听器
			this.applicationListeners.clear();
			this.applicationListeners.addAll(this.earlyApplicationListeners);
		}

        // 创建刷新前的监听事件集合
		this.earlyApplicationEvents = new LinkedHashSet<>();
	}

自定义扩展initPropertySources

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {

	public MyClassPathXmlApplicationContext(String... configLocations) {
		// 调用父类构造方法
		super(configLocations);
	}

	/**
	 * 自定义扩展
	 */
	@Override
	protected void initPropertySources() {
		System.out.println("扩展initPropertySources");
		// 设置必需属性,如果没有启动时就会报错
		//super.getEnvironment().setRequiredProperties("aaa");
		super.getEnvironment().setRequiredProperties("username");
	}
}


public class MainTest {

	public static void main(String[] args) {
		ClassPathXmlApplicationContext applicationContext = new MyClassPathXmlApplicationContext("application-${username}.xml");
		//Person person = applicationContext.getBean(Person.class);
		//System.out.println("### person.getName() = " + person.getName());
	}
}

prepareBeanFactory

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
        // 初始化BeanFactory,并进行xml读取,将得到的BeanFactory记录在当前实体的实现中
		refreshBeanFactory();
        // 返回beanFactory对象
		return getBeanFactory();
	}
	protected final void refreshBeanFactory() throws BeansException {
        // beanFactory存在,就销毁
		if (hasBeanFactory()) {
			destroyBeans();
			closeBeanFactory();
		}
		try {
            // 创建beanFactory
			DefaultListableBeanFactory beanFactory = createBeanFactory();
            // 设置序列化id
			beanFactory.setSerializationId(getId());
            // 定制beanFactory,设置相关属性,包括是否允许覆盖同名称的不同定义的对象以及循环依赖
			customizeBeanFactory(beanFactory);
            // 初始化documentReader,并进行xml文件读取及解析
			loadBeanDefinitions(beanFactory);
			this.beanFactory = beanFactory;
		}
		catch (IOException ex) {
			throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
		}
	}

返回的beanFactory默认允许循环依赖和beanDefinition重写 DefaultListableBeanFactory.java private boolean allowCircularReferences = true; private boolean allowBeanDefinitionOverriding = true; image.png 然后对beanFactory进行配置customizeBeanFactoryAbstractRefreshableApplicationContext.java

// 未进行赋值,默认为null
private Boolean allowBeanDefinitionOverriding;


private Boolean allowCircularReferences;

protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
    // 构造方法未对属性进行赋值,所以都是null,不会进行任何操作
		if (this.allowBeanDefinitionOverriding != null) {
            // 如果不是null,就相当于采用自定义的配置
			beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
		}
		if (this.allowCircularReferences != null) {
			beanFactory.setAllowCircularReferences(this.allowCircularReferences);
		}
	}

自定义配置customizeBeanFactory

public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext {

	public MyClassPathXmlApplicationContext(String... configLocations) {
		// 调用父类构造方法
		super(configLocations);
	}

	/**
	 * 自定义扩展
	 */
	@Override
	protected void initPropertySources() {
		System.out.println("扩展initPropertySources");
		// 设置必需属性,如果没有启动时就会报错
		//super.getEnvironment().setRequiredProperties("aaa");
		super.getEnvironment().setRequiredProperties("username");
	}

	/**
	 * 自定义配置
	 * @param beanFactory the newly created bean factory for this context
	 */
	@Override
	protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
		super.setAllowBeanDefinitionOverriding(false);
		super.setAllowCircularReferences(false);
		super.customizeBeanFactory(beanFactory);
	}
}

# 配置文件加载过程

loadBeanDefinitions加载bean的定义信息AbstractXmlApplicationContext.java

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
		// Create a new XmlBeanDefinitionReader for the given BeanFactory.
        // 创建一个beanDefinitionReader,设到beanFactory中,用来解析xml文件
		XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);

        // 设置属性
		beanDefinitionReader.setEnvironment(this.getEnvironment());
		beanDefinitionReader.setResourceLoader(this);
        // 实体解析器,读取本地xml格式文件(xsd,dtd文件),完成解析工作
		beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));

        // 子类可以进行扩展
		initBeanDefinitionReader(beanDefinitionReader);
        // 加载bean的定义信息
		loadBeanDefinitions(beanDefinitionReader);
	}

资源实体解析器ResourceEntityResolver new的过程,最终调用父类DelegatingEntityResolver.java

public DelegatingEntityResolver(@Nullable ClassLoader classLoader) {
    // 解析dtd
    this.dtdResolver = new BeansDtdResolver();
    // 解析xsd
    this.schemaResolver = new PluggableSchemaResolver(classLoader);
}

dtd BeansDtdResolver.java

public class BeansDtdResolver implements EntityResolver {

	private static final String DTD_EXTENSION = ".dtd";

	private static final String DTD_NAME = "spring-beans";
    // 读取spring-beans.dtd
//...
}

xsd PluggableSchemaResolver.java

public class PluggableSchemaResolver implements EntityResolver {

	/**
	 * The location of the file that defines schema mappings.
	 * Can be present in multiple JAR files.
	 */
	public static final String DEFAULT_SCHEMA_MAPPINGS_LOCATION = "META-INF/spring.schemas";
    
    public PluggableSchemaResolver(@Nullable ClassLoader classLoader) {
		this.classLoader = classLoader;
		this.schemaMappingsLocation = DEFAULT_SCHEMA_MAPPINGS_LOCATION;
	}

}

image.png xsd的构造方法没有读取操作,只是简单赋值操作,为什么会读取到文件数据 image.png

xsd的构造方法没有读取操作,只是简单赋值操作,它的toString方法却调用了读取操作(读取操作是懒加载的),idea的debug的参数值就是toString进行显示的,所以idea会自动隐式的调用此类的toString方法


@Override
	public String toString() {
		return "EntityResolver using schema mappings " + getSchemaMappings();
	}

image.png initBeanDefinitionReader(beanDefinitionReader);就是设置一个标志位,是进行xml的验证,默认为true private boolean validating = true;

接下来就是执行解析加载bean的定义信息loadBeanDefinitions(beanDefinitionReader);

protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
        // 默认为null,修改我们启动的参数可以进行赋值
		Resource[] configResources = getConfigResources();
		if (configResources != null) {
			reader.loadBeanDefinitions(configResources);
		}
        // 启动时传入的参数
		String[] configLocations = getConfigLocations();
		if (configLocations != null) {
			reader.loadBeanDefinitions(configLocations);
		}
	}

AbstractBeanDefinitionReader.java

public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
		Assert.notNull(locations, "Location array must not be null");
		int count = 0;
        // 可能传入多个配置文件,逐一加载
		for (String location : locations) {
			count += loadBeanDefinitions(location);
		}
		return count;
	}

// 传入单个String
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
		return loadBeanDefinitions(location, null);
	}


public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
        // 获取资源解析器,就是我们new的启动类,它实现了ResourcePatternResolver接口
		ResourceLoader resourceLoader = getResourceLoader();
		if (resourceLoader == null) {
			throw new BeanDefinitionStoreException(
					"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
		}

		if (resourceLoader instanceof ResourcePatternResolver) {
			// Resource pattern matching available.
			try {
                // 将String字符串解析为Resource[]资源数组,因为可能有通配符
				Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
				int count = loadBeanDefinitions(resources);
				if (actualResources != null) {
					Collections.addAll(actualResources, resources);
				}
				if (logger.isTraceEnabled()) {
					logger.trace("Loaded " + count + " bean definitions from location pattern [" + location + "]");
				}
				return count;
			}
			catch (IOException ex) {
				throw new BeanDefinitionStoreException(
						"Could not resolve bean definition resource pattern [" + location + "]", ex);
			}
		}
		else {
			// Can only load single resources by absolute URL.
			Resource resource = resourceLoader.getResource(location);
			int count = loadBeanDefinitions(resource);
			if (actualResources != null) {
				actualResources.add(resource);
			}
			if (logger.isTraceEnabled()) {
				logger.trace("Loaded " + count + " bean definitions from location [" + location + "]");
			}
			return count;
		}
	}


// 相当于传入Resource[]
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
		Assert.notNull(resources, "Resource array must not be null");
		int count = 0;
		for (Resource resource : resources) {
			count += loadBeanDefinitions(resource);
		}
		return count;
	}

image.png XmlBeanDefinitionReader.java

public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
        // 直接new(而不是设置),默认的编码(没特殊设置,属性都是null),可以自定义
        // 将resource再次封装为EncodedResource
		return loadBeanDefinitions(new EncodedResource(resource));
	}

public int loadBeanDefinitions(EncodedResource encodedResource) throws BeanDefinitionStoreException {
		Assert.notNull(encodedResource, "EncodedResource must not be null");
		if (logger.isTraceEnabled()) {
			logger.trace("Loading XML bean definitions from " + encodedResource);
		}

        // 返回null,进行创建
		Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
		if (currentResources == null) {
			currentResources = new HashSet<>(4);
            // 设置到threadLocal中
			this.resourcesCurrentlyBeingLoaded.set(currentResources);
		}
        // 将resource添加到set中
		if (!currentResources.add(encodedResource)) {
			throw new BeanDefinitionStoreException(
					"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
		}
		try {
            // 获取资源的输入流
			InputStream inputStream = encodedResource.getResource().getInputStream();
			try {
				InputSource inputSource = new InputSource(inputStream);
				if (encodedResource.getEncoding() != null) {
					inputSource.setEncoding(encodedResource.getEncoding());
				}
				return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
			}
			finally {
				inputStream.close();
			}
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(
					"IOException parsing XML document from " + encodedResource.getResource(), ex);
		}
		finally {
			currentResources.remove(encodedResource);
			if (currentResources.isEmpty()) {
				this.resourcesCurrentlyBeingLoaded.remove();
			}
		}
	}



protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
			throws BeanDefinitionStoreException {

		try {
            // 将文件解析为document文档,
			Document doc = doLoadDocument(inputSource, resource);
			int count = registerBeanDefinitions(doc, resource);
			if (logger.isDebugEnabled()) {
				logger.debug("Loaded " + count + " bean definitions from " + resource);
			}
			return count;
		}
		catch (BeanDefinitionStoreException ex) {
			throw ex;
		}
		catch (SAXParseException ex) {
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"Line " + ex.getLineNumber() + " in XML document from " + resource + " is invalid", ex);
		}
		catch (SAXException ex) {
			throw new XmlBeanDefinitionStoreException(resource.getDescription(),
					"XML document from " + resource + " is invalid", ex);
		}
		catch (ParserConfigurationException ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Parser configuration exception parsing XML from " + resource, ex);
		}
		catch (IOException ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"IOException parsing XML document from " + resource, ex);
		}
		catch (Throwable ex) {
			throw new BeanDefinitionStoreException(resource.getDescription(),
					"Unexpected exception parsing XML document from " + resource, ex);
		}
	}


protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
		return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
				getValidationModeForResource(resource), isNamespaceAware());
	}


protected int getValidationModeForResource(Resource resource) {
		int validationModeToUse = getValidationMode();
        // 如果没有进行自定义配置,就相等
		if (validationModeToUse != VALIDATION_AUTO) {
			return validationModeToUse;
		}
        // 逐行读取文件内容,进行格式判断,现在一般为xsd
		int detectedMode = detectValidationMode(resource);
		if (detectedMode != VALIDATION_AUTO) {
			return detectedMode;
		}
		return VALIDATION_XSD;
	}

DefaultDocumentLoader.java

public Document loadDocument(InputSource inputSource, EntityResolver entityResolver,
			ErrorHandler errorHandler, int validationMode, boolean namespaceAware) throws Exception {

        // 返回一个工厂实例,如果是xsd,强制使用namespaceAward
		DocumentBuilderFactory factory = createDocumentBuilderFactory(validationMode, namespaceAware);
		if (logger.isTraceEnabled()) {
			logger.trace("Using JAXP provider [" + factory.getClass().getName() + "]");
		}
        // 工厂创建一个文档构建对象
		DocumentBuilder builder = createDocumentBuilder(factory, entityResolver, errorHandler);
        // 解析配置,返回文档对象
		return builder.parse(inputSource);
	}

至此doLoadDocument走完了,继续registerBeanDefinitions

public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
        // 创建一个读取document的对象
		BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
        // 还没进行解析,所以是0
		int countBefore = getRegistry().getBeanDefinitionCount();
		documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
		return getRegistry().getBeanDefinitionCount() - countBefore;
	}

DefaultBeanDefinitionDocumentReader.java

public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
		this.readerContext = readerContext;
		doRegisterBeanDefinitions(doc.getDocumentElement());
	}


	protected void doRegisterBeanDefinitions(Element root) {

		BeanDefinitionParserDelegate parent = this.delegate;
        // 创建一个解析器
		this.delegate = createDelegate(getReaderContext(), root, parent);

		if (this.delegate.isDefaultNamespace(root)) {
            // 是否包含profile,不包含
			String profileSpec = root.getAttribute(PROFILE_ATTRIBUTE);
			if (StringUtils.hasText(profileSpec)) {
				String[] specifiedProfiles = StringUtils.tokenizeToStringArray(
						profileSpec, BeanDefinitionParserDelegate.MULTI_VALUE_ATTRIBUTE_DELIMITERS);
				// We cannot use Profiles.of(...) since profile expressions are not supported
				// in XML config. See SPR-12458 for details.
				if (!getReaderContext().getEnvironment().acceptsProfiles(specifiedProfiles)) {
					if (logger.isDebugEnabled()) {
						logger.debug("Skipped XML bean definition file due to specified profiles [" + profileSpec +
								"] not matching: " + getReaderContext().getResource());
					}
					return;
				}
			}
		}

        // 解析前扩展,空方法
		preProcessXml(root);
        // 从根节点进行解析
		parseBeanDefinitions(root, this.delegate);
        // 解析后扩展,空方法
		postProcessXml(root);

		this.delegate = parent;
	}


	protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) {
		if (delegate.isDefaultNamespace(root)) {
			NodeList nl = root.getChildNodes();
			for (int i = 0; i < nl.getLength(); i++) {
				Node node = nl.item(i);
				if (node instanceof Element) {
					Element ele = (Element) node;
                    // 是否默认的命名空间 “import”、“alias”、“bean”
                    // <import/>
                    // <bean/>
					if (delegate.isDefaultNamespace(ele)) {
						parseDefaultElement(ele, delegate);
					}
					else {
                        // 解析自定义命名空间
                        // <tx:/>
                        // <context:/>
						delegate.parseCustomElement(ele);
					}
				}
			}
		}
		else {
			delegate.parseCustomElement(root);
		}
	}


	private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
		if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
            // 解析import标签
			importBeanDefinitionResource(ele);
		}
		else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
            // 解析alias标签
			processAliasRegistration(ele);
		}
		else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
            // 解析bean标签
			processBeanDefinition(ele, delegate);
		}
        // beans
		else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
			// recurse
			doRegisterBeanDefinitions(ele);
		}
	}


	protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
        // 解析完的对象封装成holder,包含bean定义信息、bean名称和别名
		BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
		if (bdHolder != null) {
            // 自定义标签解析(若默认标签下有自定义标签)
			bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
			try {
                // 将beanDefinition注册到ioc容器
				BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
			}
			catch (BeanDefinitionStoreException ex) {
				getReaderContext().error("Failed to register bean definition with name '" +
						bdHolder.getBeanName() + "'", ele, ex);
			}
			// 发出响应事件,通知相关的监听器,完成 bean 加载
            getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
		}
	}

public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
		return parseBeanDefinitionElement(ele, null);
	}


public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
        // 解析id属性
		String id = ele.getAttribute(ID_ATTRIBUTE);
		// 解析name属性
        String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
        // 可能存在多个别名
		List<String> aliases = new ArrayList<>();
		if (StringUtils.hasLength(nameAttr)) {
			String[] nameArr = StringUtils.tokenizeToStringArray(nameAttr, MULTI_VALUE_ATTRIBUTE_DELIMITERS);
			aliases.addAll(Arrays.asList(nameArr));
		}

		String beanName = id;
		if (!StringUtils.hasText(beanName) && !aliases.isEmpty()) {
			beanName = aliases.remove(0);
			if (logger.isTraceEnabled()) {
				logger.trace("No XML 'id' specified - using '" + beanName +
						"' as bean name and " + aliases + " as aliases");
			}
		}

		if (containingBean == null) {
            // bean的id的唯一性检查
            checkNameUniqueness(beanName, aliases, ele);
		}

        // 解析完xml信息的都填充到beanDefinition
		AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
		if (beanDefinition != null) {
			if (!StringUtils.hasText(beanName)) {
				try {
					if (containingBean != null) {
						beanName = BeanDefinitionReaderUtils.generateBeanName(
								beanDefinition, this.readerContext.getRegistry(), true);
					}
					else {
						beanName = this.readerContext.generateBeanName(beanDefinition);
						// Register an alias for the plain bean class name, if still possible,
						// if the generator returned the class name plus a suffix.
						// This is expected for Spring 1.2/2.0 backwards compatibility.
						String beanClassName = beanDefinition.getBeanClassName();
						if (beanClassName != null &&
								beanName.startsWith(beanClassName) && beanName.length() > beanClassName.length() &&
								!this.readerContext.getRegistry().isBeanNameInUse(beanClassName)) {
							aliases.add(beanClassName);
						}
					}
					if (logger.isTraceEnabled()) {
						logger.trace("Neither XML 'id' nor 'name' specified - " +
								"using generated bean name [" + beanName + "]");
					}
				}
				catch (Exception ex) {
					error(ex.getMessage(), ele);
					return null;
				}
			}
            // 别名
			String[] aliasesArray = StringUtils.toStringArray(aliases);
            // 将bean的定义信息、bean名称和别名封装成一个holder对象
			return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
		}

		return null;
	}


public AbstractBeanDefinition parseBeanDefinitionElement(
			Element ele, String beanName, @Nullable BeanDefinition containingBean) {

		this.parseState.push(new BeanEntry(beanName));

		String className = null;
        // 解析class属性
		if (ele.hasAttribute(CLASS_ATTRIBUTE)) {
			className = ele.getAttribute(CLASS_ATTRIBUTE).trim();
		}
        // 解析parent属性
		String parent = null;
		if (ele.hasAttribute(PARENT_ATTRIBUTE)) {
			parent = ele.getAttribute(PARENT_ATTRIBUTE);
		}

		try {
            // 返回GenericBeanDefinition 解析parent和class,必须属性
			AbstractBeanDefinition bd = createBeanDefinition(className, parent);
            // 解析bean的其他属性,scope,abstract,lazy-init等等
			parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
			// 设置description
            bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));

            // 解析元数据
			parseMetaElements(ele, bd);
            // 解析lookup-method属性
			parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
			// 解析replace-method属性
            parseReplacedMethodSubElements(ele, bd.getMethodOverrides());

            // 解析构造函数
			parseConstructorArgElements(ele, bd);
            // 解析property子元素
			parsePropertyElements(ele, bd);
            // 解析qualifier子元素
			parseQualifierElements(ele, bd);

			bd.setResource(this.readerContext.getResource());
			bd.setSource(extractSource(ele));

			return bd;
		}
		catch (ClassNotFoundException ex) {
			error("Bean class [" + className + "] not found", ele, ex);
		}
		catch (NoClassDefFoundError err) {
			error("Class that bean class [" + className + "] depends on not found", ele, err);
		}
		catch (Throwable ex) {
			error("Unexpected failure during bean definition parsing", ele, ex);
		}
		finally {
			this.parseState.pop();
		}

		return null;
	}

AbstractXmlApplicationContext.java

public static void registerBeanDefinition(
			BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
			throws BeanDefinitionStoreException {

		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

        // 注册别名到别名map中 private final Map<String, String> aliasMap = new ConcurrentHashMap<>(16);
        // key是别名,value是beanName
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

DefaultListableBeanFactory.java

private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
// 已至少创建一次的 bean 的名称
private final Set<String> alreadyCreated = Collections.newSetFromMap(new ConcurrentHashMap<>(256));
// bean定义信息名称,按注册顺序排列。
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
			throws BeanDefinitionStoreException {

		Assert.hasText(beanName, "Bean name must not be empty");
		Assert.notNull(beanDefinition, "BeanDefinition must not be null");

		if (beanDefinition instanceof AbstractBeanDefinition) {
			try {
				((AbstractBeanDefinition) beanDefinition).validate();
			}
			catch (BeanDefinitionValidationException ex) {
				throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
						"Validation of bean definition failed", ex);
			}
		}

        // 判断bean定义信息的map中有没有对应的bean,首次加载没有
		BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
		if (existingDefinition != null) {
            // 已经加载过,判断如果不允许重写,直接报错
			if (!isAllowBeanDefinitionOverriding()) {
				throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
			}
			else if (existingDefinition.getRole() < beanDefinition.getRole()) {
				// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
				if (logger.isInfoEnabled()) {
					logger.info("Overriding user-defined bean definition for bean '" + beanName +
							"' with a framework-generated bean definition: replacing [" +
							existingDefinition + "] with [" + beanDefinition + "]");
				}
			}
			else if (!beanDefinition.equals(existingDefinition)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Overriding bean definition for bean '" + beanName +
							"' with a different definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
			else {
				if (logger.isTraceEnabled()) {
					logger.trace("Overriding bean definition for bean '" + beanName +
							"' with an equivalent definition: replacing [" + existingDefinition +
							"] with [" + beanDefinition + "]");
				}
			}
            // 放入新的bean定义信息,key是bean名称,value是bean的定义信息
			this.beanDefinitionMap.put(beanName, beanDefinition);
		}
        // map中没有
		else {
            // 判断set的大小是否不为0,首次为0
			if (hasBeanCreationStarted()) {
				// Cannot modify startup-time collection elements anymore (for stable iteration)
				synchronized (this.beanDefinitionMap) {
					this.beanDefinitionMap.put(beanName, beanDefinition);
					List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
					updatedDefinitions.addAll(this.beanDefinitionNames);
					updatedDefinitions.add(beanName);
					this.beanDefinitionNames = updatedDefinitions;
					removeManualSingletonName(beanName);
				}
			}
			else {
                // 放入bean的定义信息,key是bean名称,value是bean的定义信息
				this.beanDefinitionMap.put(beanName, beanDefinition);
                // 放入bean名称,用于顺序解析
				this.beanDefinitionNames.add(beanName);
				removeManualSingletonName(beanName);
			}
			this.frozenBeanDefinitionNames = null;
		}

		if (existingDefinition != null || containsSingleton(beanName)) {
			resetBeanDefinition(beanName);
		}
		else if (isConfigurationFrozen()) {
			clearByTypeCache();
		}
	}

上次更新: 2024/03/03, 08:36:37
环境搭建
Kubernetes

← 环境搭建 Kubernetes→

Theme by Vdoing | Copyright © 2023-2024 Starry | MIT License
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式