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
我们使用的是ApplicationContext
Ctrl + Alt + B,查看ApplicationContext的实现,其中就有AnnotationConfigApplicationContext,加载基于注解的bean配置
使用@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的配置
# 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路径匹配
*/
}
构造方法走完了,继续 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();
}
至此环境对象创建完毕
注意:系统环境中有个username的key
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_)_;
就执行完了
来到最重要的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;
然后对beanFactory进行配置customizeBeanFactory
AbstractRefreshableApplicationContext.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;
}
}
xsd的构造方法没有读取操作,只是简单赋值操作,为什么会读取到文件数据
xsd的构造方法没有读取操作,只是简单赋值操作,它的toString方法却调用了读取操作(读取操作是懒加载的),idea的debug的参数值就是toString进行显示的,所以idea会自动隐式的调用此类的toString方法
@Override
public String toString() {
return "EntityResolver using schema mappings " + getSchemaMappings();
}
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;
}
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();
}
}