02-refresh
observer 英 /əbˈzɜːvə(r)/ n. 观察员;观察者;观察家;观测者;目击者;评论员;旁听者
registrar 英 /ˌredʒɪˈstrɑː(r)/ n. 登记员;局长;注册机构;域名注册商;注册者
registry 英 /ˈredʒɪstri/ n. 登记处;注册处
register 英 /ˈredʒɪstə(r)/ v. 注册;登记;记录; n.登记簿;登记表
pluggable 英 /ˈplʌgəbl/ adj. 可插拔的;可插的
AbstractApplicationContext.refresh()
包含13个Spring最重要方法- do开头方法为实际干活方法
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
/*
* 前戏,做容器刷新前的准备工作
* 1. 设置容器的启动时间
* 2. 设置关闭标志位为false,激活标志位为true
* 3. 设置Environment,并加载当前系统的属性值到Environment
* 4. 准备监听器、事件集合,Spring默认为空
*/
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
/*
* 1. 创建容器对象:DefaultListableBeanFactory
* 2. 加载xml到BF => BeanDefinition
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// BF前戏,各种属性填充`add(), register()`
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
/*
* 1. 模板方法,后续拓展
* 2. 子类重写做额外的处理,查看web中的代码,有具体实现的
*/
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
/*
* 1. 实例化 & 执行BFPP
* 2. 首次getBean()
*/
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
/*
* 1. 实例化前戏
* 2. 实例化 & 注册BPP。真正调用是getBean()
*/
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
/*
* 1. 国际化处理。为上下文初始化message源,即不同语言消息体
* 2. SpringMVC,国际化的代码重点讲
*/
initMessageSource();
// Initialize event multicaster for this context.
/*
* 1. 实例化前戏
* 2. init Multicaster(多路广播器),用于bean各阶段事件监听
*/
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 模板方法,后续拓展
onRefresh();
// Check for listener beans and register them.
/*
* 1. 实例化前戏
* 2. 注册监听器。bean中查找listener_bean,注册到消息广播器中
*/
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 1. 生命周期处理器lifecycleProcessor初始化并onRefresh
// 2. 发布ContextRefreshEvent
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.
// 为防止bean资源占用,在异常处理中,销毁已经在前面过程中生成的单件bean
destroyBeans();
// Reset 'active' flag.
// 重置active标志
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
} finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
}
}
}
}
0. ClassPathXmlAC
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
this(new String[]{configLocation}, true, null);
}
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
// 1. 父类构造,相关的对象创建、属性赋值。PathMatchingResourcePatternResolver
super(parent);
// 2. 解析 & 设置配置文件路径(占位符)
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
}
1. super(parent)
// 父类构造,相关的对象创建、属性赋值。PathMatchingResourcePatternResolver
super(parent);
AbstractApplicationContext#getResourcePatternResolver()
AbstractApplicationContext.resourcePatternResolver = new PathMatchingResourcePatternResolver()
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
private ResourcePatternResolver resourcePatternResolver;
public AbstractApplicationContext() {
// 1.. 创建<资源模式处理器>
this.resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver() {
// 2. 创建一个<资源模式解析器>(用来解析xml配置文件)
return new PathMatchingResourcePatternResolver(this);
}
}
public class PathMatchingResourcePatternResolver implements ResourcePatternResolver {
}
public interface ResourcePatternResolver extends ResourceLoader {
}
// 资源加载器
public interface ResourceLoader {
/** Pseudo URL prefix for loading from the class path: "classpath:". */
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
}
2. setConfigLocations()
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
implements BeanNameAware, InitializingBean {
// 配置路径集合,默认为字符串数组
@Nullable
private String[] configLocations;
public void setConfigLocations(@Nullable String... locations) {
if (locations != null) {
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
// 1.. 解析给定路径,x1_${user}.xml => x1_list.xml
this.configLocations[i] = resolvePath(locations[i]).trim();
}
} else {
this.configLocations = null;
}
}
protected String resolvePath(String path) {
// 1... AbstractApplicationContext => StandardEnvironment
return getEnvironment().resolveRequiredPlaceholders(path);
}
/**
* Triggers {@link #refresh()} if not refreshed in the concrete context's
* constructor already.
*/
@Override
public void afterPropertiesSet() {
if (!isActive()) {
refresh();
}
}
}
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
@Nullable
private ConfigurableEnvironment environment;
@Override
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
// 1..
this.environment = createEnvironment();
}
return this.environment;
}
protected ConfigurableEnvironment createEnvironment() {
// 1.
return new StandardEnvironment();
}
}
1. StandardEnvironment
public class StandardEnvironment extends AbstractEnvironment {
public static final String SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME = "systemEnvironment";
public static final String SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME = "systemProperties";
@Override // SpringBoot继承了该类,进行了Environment拓展
protected void customizePropertySources(MutablePropertySources propertySources) {
// 1... AbstractEnvironment
propertySources.addLast(
new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); // systemProperties
propertySources.addLast(
new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); // systemEnvironment
}
}
StandardEnvironment#customizePropertySources()
1. AbstractEnvironment
// 获取当前系统的属性值
(Map) System.getProperties();
// 获取当前系统的环境值
(Map) System.getenv();
public abstract class AbstractEnvironment implements ConfigurableEnvironment {
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";
// 99. systemProperties, systemEnvironment最终位置
private final MutablePropertySources propertySources = new MutablePropertySources();
public AbstractEnvironment() {
// 1... StandardEnvironment
customizePropertySources(this.propertySources);
}
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public Map<String, Object> getSystemProperties() {
try {
// 1. 获取当前系统的属性值
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;
}
}
};
}
}
@Override
@SuppressWarnings({"rawtypes", "unchecked"})
public Map<String, Object> getSystemEnvironment() {
if (suppressGetenvAccess()) {
return Collections.emptyMap();
}
try {
// 1. 获取当前系统的环境值
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;
}
}
};
}
}
}
2. x1_${user}.xml解析
T1_setConfigLocations => x1_list.xml
class T1_setConfigLocations {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x1_${user}.xml");
System.out.println("------------------- ac.over -------------------");
Ooxx ooxx = ac.getBean("ooxx", Ooxx.class);
System.out.println("ooxx = " + ooxx);
ac.close();
}
}
<bean id="ooxx" class="com.listao.Ooxx">
<property name="id" value="1"/>
<property name="name" value="ooxx"/>
</bean>
PropertyPlaceholderHelper#parseStringValue()
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
implements BeanNameAware, InitializingBean {
protected String resolvePath(String path) {
// 1. 核心方法
return getEnvironment().resolveRequiredPlaceholders(path);
}
}
1. prepareRefresh()
// Prepare this context for refreshing.
/*
* 前戏,做容器刷新前的准备工作
* 1. 设置容器的启动时间
* 2. 设置关闭标志位为false,激活标志位为true
* 3. 设置Environment,并加载当前系统的属性值到Environment
* 4. 准备监听器、事件集合,Spring默认为空
*/
prepareRefresh();
protected void prepareRefresh() {
// Switch to active.
// 设置容器启动时间
this.startupDate = System.currentTimeMillis();
// 容器关闭标志位
this.closed.set(false);
// 容器激活标志位
this.active.set(true);
// Initialize any placeholder property sources in the context environment.
/*
* 1. 模板方法。后期拓展。默认什么也没做
* 2. SpringMVC有些基本操作
*/
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
// 校验必要的系统属性值、环境值
getEnvironment().validateRequiredProperties();
// Store pre-refresh ApplicationListeners...
/*
* 1. 填充监听器集合
* 2. SpringBoot拓展,applicationListeners不为空
*/
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
// multicaster启动前的Event集合
this.earlyApplicationEvents = new LinkedHashSet<>();
}
1. initPropertySources()
// Initialize any placeholder property sources in the context environment.
/*
* 1. 模板方法。后期拓展。默认什么也没做
* 2. SpringMVC有些基本操作
*/
initPropertySources();
/**
* MyClassPathXmlApplicationContext
*/
public class MyCPXAC_1 extends ClassPathXmlApplicationContext {
public MyCPXAC_1(String... configLocations) {
super(configLocations);
}
@Override
protected void initPropertySources() {
System.out.println("扩展 ==> MyCPXAC_1.initPropertySource()");
// 必要Environment设置。程序检测到没user,直接阻断程序
getEnvironment().setRequiredProperties("user");
// 必要Environment校验
// getEnvironment().validateRequiredProperties();
}
}
/**
* 重写拓展方法,@Override
* <p>
* 1. initPropertySources()
* 2. customizeBeanFactory()
* 3. postProcessBeanFactory()
*/
public class T2_MyCPXAC { // MyClassPathXmlApplicationContext
public static void main(String[] args) {
MyCPXAC_1 ac = new MyCPXAC_1("x0_ooxx.xml");
System.out.println("------------------- ac.over -------------------");
ac.close();
}
}
2. validateRequiredProperties()
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
// 校验必要的系统属性值、环境值
getEnvironment().validateRequiredProperties();
3. earlyApplicationListeners
// Store pre-refresh ApplicationListeners...
/*
* 1. 填充监听器集合
* 2. SpringBoot拓展,applicationListeners不为空
*/
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners);
} else {
// Reset local application listeners to pre-refresh state.
this.applicationListeners.clear();
this.applicationListeners.addAll(this.earlyApplicationListeners);
}
4. earlyApplicationEvents
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
// multicaster启动前的Event集合
this.earlyApplicationEvents = new LinkedHashSet<>();
2. obtainFreshBeanFactory()
// Tell the subclass to refresh the internal bean factory.
/*
* 1. 创建容器对象:DefaultListableBeanFactory
* 2. 加载xml到BF => BeanDefinition
*/
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
/**
* Tell the subclass to refresh the internal bean factory.
* 1. 创建容器对象:DefaultListableBeanFactory
* 2. 加载xml到BF => BeanDefinition
*
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
/*
* 1. 删除旧BF,实例化新BF
* 2. XML文件解析、加载
*/
refreshBeanFactory();
// 返回BF
return getBeanFactory();
}
2.1. refreshBeanFactory()
public abstract class AbstractRefreshableApplicationContext extends AbstractApplicationContext {
protected final void refreshBeanFactory() throws BeansException {
// 如果存在BF,销毁BF
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
/*
* 1. AbstractAutowireCapableBeanFactory => `allowCircularReferences = true;`
* ignoreDependencyInterface()忽略Aware接口的实现类进行IOC,由invokeAwareMethod()统一处理
* 2. DefaultListableBeanFactory => `allowBeanDefinitionOverriding = true;`
*/
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 为序列化指定id,可以从id反序列化到BF对象
beanFactory.setSerializationId(getId());
/*
* 定制BF,设置相关属性
* 1. 是否允许覆盖BD`allowBeanDefinitionOverriding = true`
* 2. 是否允许循环依赖`allowCircularReferences = true`
*/
customizeBeanFactory(beanFactory);
/*
* 1. BF => 初始化BDR => 读取并解析xml
* 2. 命名空间解析,标签解析
*/
loadBeanDefinitions(beanFactory);
// debug,关注`beanDefinitionMap, beanDefinitionNames`
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());
}
}
HierarchicalBeanFactory
- Spring只有单一容器,MVC有父子容器。bean查询时,首先在当前容器查找,找不到去父容器查找
doGetBean()
=>BeanFactory parentBeanFactory = getParentBeanFactory();
ListableBeanFactory
:提供各种条件获取bean的配置清单,enumerate all their bean instances
ConfigurableBeanFactory
:提供配置Factory各种方法
1. createBeanFactory()
/*
* 1. AbstractAutowireCapableBeanFactory => `allowCircularReferences = true;`
* ignoreDependencyInterface()忽略Aware接口的实现类进行IOC,由invokeAwareMethod()统一处理
* 2. DefaultListableBeanFactory => `allowBeanDefinitionOverriding = true;`
*/
DefaultListableBeanFactory beanFactory = createBeanFactory();
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {
private boolean allowBeanDefinitionOverriding = true;
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
}
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* 默认允许循环依赖
* Whether to automatically try to resolve circular references between beans.
*/
private boolean allowCircularReferences = true;
/**
* 构造方法,忽略`BeanNameAware, BeanFactoryAware, BeanClassLoaderAware`
* <p>
* Create a new AbstractAutowireCapableBeanFactory.
*/
public AbstractAutowireCapableBeanFactory() {
super();
// 忽略进行IOC的接口现实类,由invokeAwareMethod()统一处理
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
}
2. customizeBeanFactory()
/*
* 定制BF,设置相关属性
* 1. 是否允许覆盖BD`allowBeanDefinitionOverriding = true`
* 2. 是否允许循环依赖`allowCircularReferences = true`
*/
customizeBeanFactory(beanFactory);
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
// 是否允许覆盖BD
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
// 是否允许bean循环依赖
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
public class MyCPXAC_1 extends ClassPathXmlApplicationContext {
public MyCPXAC_1(String... configLocations) {
super(configLocations);
}
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
System.out.println("扩展 ==> MyCPXAC_1.customizeBeanFactory()");
super.setAllowBeanDefinitionOverriding(false);
super.setAllowCircularReferences(false);
// super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
super.customizeBeanFactory(beanFactory);
}
}
3. loadBeanDefinitions()
*.dtd
文件、*.xsd
文件,需要从网络环境中进行相关下载工作,必须无网环境,只能mapping到本地资源文件META-INF/spring.schemas
=> (key: http_xsd, value: local_xsd)- xml => document
META-INF/spring.handles
=> (key: namespace, value: HandlerClass)- document => BD => IOC
- Document,每个Element中都包含了namespace。获取节点namespace
DefaultNamespaceHandlerResolver
类懒加载META-INF/spring.handles
文件内容到DefaultNamespaceHandlerResolver => Map<String, Object> handlerMappings
parseCustomElement()
中- namespace =>
handlerMappings
反射生成NamespaceHandler
NamespaceHandler#init()
@Override注册NamespaceHandlerSupport => Map<String, BeanDefinitionParser> parsers
NamespaceHandlerSupport#findParserForElement()
获取Parser,进而parse()
- namespace =>
/*
* 1. BF => 初始化BDR => 读取并解析xml
* 2. 命名空间解析,标签解析
*/
loadBeanDefinitions(beanFactory);
- 解析xml
- sax
- dom4j
- xml规范
dtd
:document_type_definitionxsd
:xml_schemas_definition(越来越多)
public abstract class AbstractXmlApplicationContext extends AbstractRefreshableConfigApplicationContext {
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
/*
* 1. 适配器设计模式
* 2. BF => BDR
*/
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's resource loading environment.
/*
* 1. BDR设置Environment
* 2. 自定义环境变量不要与系统环境变量冲突。username => jdbc_username
*/
beanDefinitionReader.setEnvironment(this.getEnvironment());
// 设置资源加载器
beanDefinitionReader.setResourceLoader(this);
/*
* 1. EntityResolver => org.xml.sax; => sample api for xml
* 2. EntityResolver实现类,读取本地的xsd、dtd文件,完成xml解析。不需要互联网
*/
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
// 初始化BDR,设置配置文件是否校验(适配器模式)
initBeanDefinitionReader(beanDefinitionReader);
/*
* 1. n次重载
* 2. 开始进行BD加载
*/
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
// Resource方式,获得配置文件位置(一般都为空)
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
/*
* 1. String方式,获得配置文件位置
* 2. ClassPathXmlApplicationContext.setConfigLocations()进行了值设置
*/
String[] configLocations = getConfigLocations();
if (configLocations != null) {
// 99.
reader.loadBeanDefinitions(configLocations);
}
}
}
1. XmlBeanDefinitionReader
String[] => String => Resource[] => Resource => InputStream => InputSource => Document
1. ResourceEntityResolver
- 加载
.dtd
、.xsd
配置文件 - 作用Xml => Document
XmlBeanDefinitionReader.entityResolver = ResourceEntityResolver
DelegatingEntityResolver.schemaResolver = PluggableSchemaResolver
PluggableSchemaResolver.schemaMappings
DelegatingEntityResolver(ClassLoader)
public class ResourceEntityResolver extends DelegatingEntityResolver {
private final ResourceLoader resourceLoader;
public ResourceEntityResolver(ResourceLoader resourceLoader) {
super(resourceLoader.getClassLoader());
this.resourceLoader = resourceLoader;
}
}
public class DelegatingEntityResolver implements EntityResolver {
/**
* Suffix for DTD files.
*/
public static final String DTD_SUFFIX = ".dtd";
/**
* Suffix for schema definition files.
*/
public static final String XSD_SUFFIX = ".xsd";
private final EntityResolver dtdResolver;
private final EntityResolver schemaResolver;
public DelegatingEntityResolver(@Nullable ClassLoader classLoader) {
// dtd解析器
this.dtdResolver = new BeansDtdResolver();
/*
* 1. 将spring-beans包META-INF/spring.schemas里的xsd放到schemaMappings里
* 2. idea在debug时,自动toString() => getSchemaMappings()
*/
this.schemaResolver = new PluggableSchemaResolver(classLoader); // 可插入的
}
}
spring.schemas
将xsd的网络路径映射为本地路径
public class PluggableSchemaResolver implements EntityResolver {
public static final String DEFAULT_SCHEMA_MAPPINGS_LOCATION = "META-INF/spring.schemas";
@Nullable
private volatile Map<String, String> schemaMappings;
public PluggableSchemaResolver(@Nullable ClassLoader classLoader) {
this.classLoader = classLoader;
// 1. META-INF/spring.schemas
this.schemaMappingsLocation = DEFAULT_SCHEMA_MAPPINGS_LOCATION;
}
/**
* Load the specified schema mappings lazily.
* 懒加载,指定的schema
*/
private Map<String, String> getSchemaMappings() {
Map<String, String> schemaMappings = this.schemaMappings;
if (schemaMappings == null) {
synchronized (this) {
schemaMappings = this.schemaMappings;
if (schemaMappings == null) {
try {
// 2. 加载目录org/springframework/beans/factory/xml下所有xsd
Properties mappings =
PropertiesLoaderUtils.loadAllProperties(this.schemaMappingsLocation, this.classLoader);
schemaMappings = new ConcurrentHashMap<>(mappings.size());
CollectionUtils.mergePropertiesIntoMap(mappings, schemaMappings);
this.schemaMappings = schemaMappings;
} catch (IOException ex) {
throw new IllegalStateException(
"Unable to load schema mappings from location [" + this.schemaMappingsLocation + "]", ex);
}
}
}
}
return schemaMappings;
}
/**
* 3. idea自动调用toString(),加载填充schemaMappings()
*/
@Override
public String toString() {
return "EntityResolver using schema mappings " + getSchemaMappings();
// return "EntityResolver using schema mappings " + "会打印啥呢";
}
}
2. getResources()
1. AbstractBeanDefinitionReader
PathMatchingResourcePatternResolver#getResources()
public abstract class AbstractBeanDefinitionReader implements BeanDefinitionReader, EnvironmentCapable {
@Nullable
private ResourceLoader resourceLoader;
@Override
public int loadBeanDefinitions(String... locations) throws BeanDefinitionStoreException {
Assert.notNull(locations, "Location array must not be null");
int count = 0;
for (String location : locations) {
// 1..
count += loadBeanDefinitions(location);
}
return count;
}
@Override
public int loadBeanDefinitions(String location) throws BeanDefinitionStoreException {
// 1..
return loadBeanDefinitions(location, null);
}
public int loadBeanDefinitions(String location, @Nullable Set<Resource> actualResources) throws BeanDefinitionStoreException {
// 获取ResourceLoader对象
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader == null) {
throw new BeanDefinitionStoreException(
"Cannot load bean definitions from location [" + location + "]: no ResourceLoader available");
}
// 查看类图 => `ClassPathXmlApplicationContext implements ResourcePatternResolver`
if (resourceLoader instanceof ResourcePatternResolver) {
// Resource pattern matching available.
try {
/*
* 1... AbstractApplicationContext 调用DefaultResourceLoader.getResource()完成具体的Resource定位
* 2. classpath*: => <context:property-placeholder location="classpath:*.properties"/>
*/
Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
// 3..
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;
}
}
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int count = 0;
for (Resource resource : resources) {
// 1..
count += loadBeanDefinitions(resource);
}
return count;
}
@Override
public int loadBeanDefinitions(Resource resource) throws BeanDefinitionStoreException {
// 1.. EncodedResource按照指定编码对resource进行包装
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);
}
/*
* 1. 当前thread已经加载的资源,ThreadLocal<Set<EncodedResource>>
* 2. 添加正在加载
*/
Set<EncodedResource> currentResources = this.resourcesCurrentlyBeingLoaded.get();
if (!currentResources.add(encodedResource)) {
throw new BeanDefinitionStoreException(
"Detected cyclic loading of " + encodedResource + " - check your import definitions!");
}
/*
* 1. String[] => String => Resource[] => Resource => InputStream
* 2. 读取xml => InputStream
*/
try (InputStream inputStream = encodedResource.getResource().getInputStream()) {
InputSource inputSource = new InputSource(inputStream);
if (encodedResource.getEncoding() != null) {
inputSource.setEncoding(encodedResource.getEncoding());
}
// 1... XmlBeanDefinitionReader 核心加载xml逻辑
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
} catch (IOException ex) {
throw new BeanDefinitionStoreException(
"IOException parsing XML document from " + encodedResource.getResource(), ex);
} finally {
currentResources.remove(encodedResource);
if (currentResources.isEmpty()) {
this.resourcesCurrentlyBeingLoaded.remove();
}
}
}
}
2. AbstractApplicationContext
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
public AbstractApplicationContext() {
// 创建<资源模式处理器>
this.resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver() {
// 创建一个<资源模式解析器>(用来解析xml配置文件)
return new PathMatchingResourcePatternResolver(this);
}
@Override
public Resource[] getResources(String locationPattern) throws IOException {
/*
* 1. 构造方法时,被设置
* 2. resourcePatternResolver => PathMatchingResourcePatternResolver
*/
return this.resourcePatternResolver.getResources(locationPattern);
}
}
3. doLoadBeanDefinitions()
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
private DocumentLoader documentLoader = new DefaultDocumentLoader();
@Nullable
private EntityResolver entityResolver;
protected int doLoadBeanDefinitions(InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
/*
* 1. xml文件转Document,解析由 (DefaultDocumentLoader + ResourceEntityResolver) 完成
* 2.. InputSource => Document
*/
Document doc = doLoadDocument(inputSource, resource);
/*
* 3.. Document => BeanDefinition
*/
int count = registerBeanDefinitions(doc, resource);
return count;
}
protected Document doLoadDocument(InputSource inputSource, Resource resource) throws Exception {
// 1. getEntityResolver()
return this.documentLoader.loadDocument(inputSource, getEntityResolver(), this.errorHandler,
getValidationModeForResource(resource), isNamespaceAware());
}
/**
* Return the EntityResolver to use, building a default resolver
* if none specified.
*/
protected EntityResolver getEntityResolver() {
if (this.entityResolver == null) {
// Determine default EntityResolver to use.
ResourceLoader resourceLoader = getResourceLoader();
if (resourceLoader != null) {
this.entityResolver = new ResourceEntityResolver(resourceLoader);
} else {
this.entityResolver = new DelegatingEntityResolver(getBeanClassLoader());
}
}
return this.entityResolver;
}
}
4. registerBeanDefinitions()
private Class<? extends BeanDefinitionDocumentReader> documentReaderClass = DefaultBeanDefinitionDocumentReader.class;
protected BeanDefinitionDocumentReader createBeanDefinitionDocumentReader() {
// 1.
return BeanUtils.instantiateClass(this.documentReaderClass);
}
// --------------------------------------------------------------------------------------------------------
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// 1.. Doc解析对象 => DefaultBeanDefinitionDocumentReader
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
/*
* 1. 具体xml解析
* 2. createReaderContext() namespace加载
* => DefaultNamespaceHandlerResolver(META-INF/spring.handlers)
*/
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
}
5. createReaderContext()
BDDocumentReader.readerContext = new XmlReaderContext()
XmlBeanDefinitionReader.namespaceHandlerResolver == XmlReaderContext.namespaceHandlerResolver => DefaultNamespaceHandlerResolver
DefaultNamespaceHandlerResolver.handlerMappings => spring.handlers
public class XmlBeanDefinitionReader extends AbstractBeanDefinitionReader {
private NamespaceHandlerResolver namespaceHandlerResolver;
public XmlReaderContext createReaderContext(Resource resource) {
// 1..
return new XmlReaderContext(resource, this.problemReporter, this.eventListener,
this.sourceExtractor, this, getNamespaceHandlerResolver());
}
public NamespaceHandlerResolver getNamespaceHandlerResolver() {
if (this.namespaceHandlerResolver == null) {
// 2..
this.namespaceHandlerResolver = createDefaultNamespaceHandlerResolver();
}
return this.namespaceHandlerResolver;
}
protected NamespaceHandlerResolver createDefaultNamespaceHandlerResolver() {
ClassLoader cl = (getResourceLoader() != null ? getResourceLoader().getClassLoader() : getBeanClassLoader());
// 3.
return new DefaultNamespaceHandlerResolver(cl);
}
}
1. XmlReaderContext
public class XmlReaderContext extends ReaderContext {
private final XmlBeanDefinitionReader reader;
private final NamespaceHandlerResolver namespaceHandlerResolver;
public XmlReaderContext(
Resource resource, ProblemReporter problemReporter,
ReaderEventListener eventListener, SourceExtractor sourceExtractor,
XmlBeanDefinitionReader reader, NamespaceHandlerResolver namespaceHandlerResolver) {
super(resource, problemReporter, eventListener, sourceExtractor);
this.reader = reader;
// 1.
this.namespaceHandlerResolver = namespaceHandlerResolver;
}
}
2. DftNamespaceHandlerResolver
DefaultNamespaceHandlerResolver(ClassLoader, String) => 手动idea计算
getHandlerMappings()
public class DefaultNamespaceHandlerResolver implements NamespaceHandlerResolver {
/**
* 1. The location to look for the mapping files. Can be present in multiple JAR files.
*/
public static final String DEFAULT_HANDLER_MAPPINGS_LOCATION = "META-INF/spring.handlers";
/** Resource location to search for. */
private final String handlerMappingsLocation;
/**
* Stores the mappings from namespace URI to NamespaceHandler class name / instance.
*/
@Nullable
private volatile Map<String, Object> handlerMappings;
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader) {
this(classLoader, DEFAULT_HANDLER_MAPPINGS_LOCATION); // META-INF/spring.handlers
}
public DefaultNamespaceHandlerResolver(@Nullable ClassLoader classLoader, String handlerMappingsLocation) {
this.classLoader = (classLoader != null ? classLoader : ClassUtils.getDefaultClassLoader());
this.handlerMappingsLocation = handlerMappingsLocation;
}
/**
* Load the specified NamespaceHandler mappings lazily.
*/
private Map<String, Object> getHandlerMappings() {
Map<String, Object> handlerMappings = this.handlerMappings;
// 如果没有被缓存,则开始进行缓存
if (handlerMappings == null) {
synchronized (this) {
handlerMappings = this.handlerMappings;
if (handlerMappings == null) {
// 2. this.handlerMappingsLocation在构造函数中已经被初始化为META-INF/spring.handlers
Properties mappings = PropertiesLoaderUtils.loadAllProperties(this.handlerMappingsLocation, this.classLoader);
if (logger.isTraceEnabled()) {
logger.trace("Loaded NamespaceHandler mappings: " + mappings);
}
handlerMappings = new ConcurrentHashMap<>(mappings.size());
// 将properties格式文件合并到map格式的handlerMapping中
CollectionUtils.mergePropertiesIntoMap(mappings, handlerMappings);
this.handlerMappings = handlerMappings;
}
}
}
return handlerMappings;
}
@Override
public String toString() {
// 3..
return "NamespaceHandlerResolver using mappings " + getHandlerMappings();
}
// ----------------------------------------------------------------------------------------
@Override
@Nullable
public NamespaceHandler resolve(String namespaceUri) {
// 1. 获取HandlerMappings,懒加载
Map<String, Object> handlerMappings = getHandlerMappings();
Object handlerOrClassName = handlerMappings.get(namespaceUri);
if (handlerOrClassName == null) {
return null;
}
// 2. 做过解析,直接从缓存中读取
else if (handlerOrClassName instanceof NamespaceHandler) {
return (NamespaceHandler) handlerOrClassName;
}
// 3. 没有做过解析,反射 => 类路径转化为类
else {
String className = (String) handlerOrClassName;
try {
// 4. 反射 => 类路径转化为类
Class<?> handlerClass = ClassUtils.forName(className, this.classLoader);
if (!NamespaceHandler.class.isAssignableFrom(handlerClass)) {
throw new FatalBeanException("Class [" + className + "] for namespace [" + namespaceUri +
"] does not implement the [" + NamespaceHandler.class.getName() + "] interface");
}
// 实例化类
NamespaceHandler namespaceHandler = (NamespaceHandler) BeanUtils.instantiateClass(handlerClass);
// 5... init() => @Override
namespaceHandler.init();
// 6. 结果记录缓存
handlerMappings.put(namespaceUri, namespaceHandler);
return namespaceHandler;
} catch (ClassNotFoundException ex) {
throw new FatalBeanException("Could not find NamespaceHandler class [" + className +
"] for namespace [" + namespaceUri + "]", ex);
} catch (LinkageError err) {
throw new FatalBeanException("Unresolvable class definition for NamespaceHandler class [" +
className + "] for namespace [" + namespaceUri + "]", err);
}
}
}
}
# spring-beans
http\://www.springframework.org/schema/c=org.springframework.beans.factory.xml.SimpleConstructorNamespaceHandler
http\://www.springframework.org/schema/p=org.springframework.beans.factory.xml.SimplePropertyNamespaceHandler
http\://www.springframework.org/schema/util=org.springframework.beans.factory.xml.UtilNamespaceHandler
# aop
http\://www.springframework.org/schema/aop=org.springframework.aop.config.AopNamespaceHandler
# context
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
http\://www.springframework.org/schema/jee=org.springframework.ejb.config.JeeNamespaceHandler
http\://www.springframework.org/schema/lang=org.springframework.scripting.config.LangNamespaceHandler
http\://www.springframework.org/schema/task=org.springframework.scheduling.config.TaskNamespaceHandler
http\://www.springframework.org/schema/cache=org.springframework.cache.config.CacheNamespaceHandler
# tx
http\://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler
http\://www.listao.site/schema/myTag=com.listao.myTag.MyTagNamespaceHandler
2. BDDocumentReader
- 4. registerBeanDefinitions()
DefaultBeanDefinitionDocumentReader.readerContext
public class DefaultBeanDefinitionDocumentReader implements BeanDefinitionDocumentReader {
@Nullable
private XmlReaderContext readerContext;
@Override
public void registerBeanDefinitions(Document doc, XmlReaderContext readerContext) {
this.readerContext = readerContext;
// doc.getDocumentElement() => [beans: null]
doRegisterBeanDefinitions(doc.getDocumentElement());
}
}
1. doRegisterBeanDefinitions()
BeanDefinitionParserDelegate.readerContext
@Nullable
private BeanDefinitionParserDelegate delegate;
protected void doRegisterBeanDefinitions(Element root) {
BeanDefinitionParserDelegate parent = this.delegate;
// 1.. createDelegate()
// DefaultBeanDefinitionDocumentReader.readerContext => BeanDefinitionParserDelegate.readerContext
// => XmlReaderContext => NamespaceHandlerResolver.handlerMappings => `spring.handlers`
this.delegate = createDelegate(getReaderContext(), root, parent); // 解析器
/*
* 1. 每个标签<>,都保存namespace属性
* 2. default_namespace: http://www.springframework.org/schema/beans
*/
if (this.delegate.isDefaultNamespace(root)) {
/*
* 1. profile <beans profile="">
* 2. Spring不用,SpringBoot指定
*/
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;
}
}
}
// 为空。SpringMVC拓展
preProcessXml(root);
// 3.. 核心
parseBeanDefinitions(root, this.delegate);
// 为空。SpringMVC拓展
postProcessXml(root);
this.delegate = parent;
}
protected BeanDefinitionParserDelegate createDelegate(
XmlReaderContext readerContext, Element root, @Nullable BeanDefinitionParserDelegate parentDelegate) {
// 1.
BeanDefinitionParserDelegate delegate = new BeanDefinitionParserDelegate(readerContext);
delegate.initDefaults(root, parentDelegate);
return delegate;
}
public class BeanDefinitionParserDelegate {
public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
private final XmlReaderContext readerContext;
public BeanDefinitionParserDelegate(XmlReaderContext readerContext) {
Assert.notNull(readerContext, "XmlReaderContext must not be null");
this.readerContext = readerContext;
}
}
2. parseBeanDefinitions()
- 解析default标签
- 解析自定义标签
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;
/*
* defaultNamespace: http://www.springframework.org/schema/beans
* 1... 默认命名空间包含元素`<import>, <alias>, <bean>, <beans>`
*/
if (delegate.isDefaultNamespace(ele)) {
parseDefaultElement(ele, delegate);
}
// 2... BeanDefinitionParserDelegate 自定义标签`<context>, <aop>, <tx>`
else {
delegate.parseCustomElement(ele);
}
}
}
} else {
delegate.parseCustomElement(root);
}
}
3. parseDefaultElement()
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
// <import>
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
// <alias>
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
// <bean>
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
// 1..
processBeanDefinition(ele, delegate);
}
// <beans>
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
// recurse
doRegisterBeanDefinitions(ele);
}
}
- 解析defaultElement
BeanDefinitionHolder
是BD封装类,封装了BD, beanName, aliases
,来完成向IOC容器注册
/**
* Process the given bean element, parsing the bean definition
* and registering it with the registry.
*/
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 1... BeanDefinitionParserDelegate 解析default标签
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null) {
// BD => BDH,进行某些属性值的替换工作
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
// 2. Register the final decorated instance.
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
} catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'", ele, ex);
}
// 3. Send registration event.
getReaderContext().fireComponentRegistered(new BeanComponentDefinition(bdHolder));
}
}
3. BDParserDelegate
- DefaultElement、CustomElement标签都封装为GenericBeanDefinition对象
- DefaultElement =>
GenericBeanDefinition.beanClass = beanClassName
- CustomElement =>
GenericBeanDefinition.beanClass = beanClass
- DefaultElement =>
1. parseBeanDefinitionElement()
public class BeanDefinitionParserDelegate {
public static final String BEANS_NAMESPACE_URI = "http://www.springframework.org/schema/beans";
@Nullable
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele) {
// 1..
return parseBeanDefinitionElement(ele, null);
}
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, @Nullable BeanDefinition containingBean) {
// 1. id
String id = ele.getAttribute(ID_ATTRIBUTE);
// 2. name
String nameAttr = ele.getAttribute(NAME_ATTRIBUTE);
// bean别名分割解析,<bean name="a, b, c">
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 (containingBean == null) {
// name唯一校验
checkNameUniqueness(beanName, aliases, ele);
}
// -----------------------------------------------------------------------------------------------
// 以上是对beanName、alias处理
// -----------------------------------------------------------------------------------------------
// 3.. <bean>详细解析
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
if (beanDefinition != null) {
if (!StringUtils.hasText(beanName)) {
try {
// 如果不存在beanName,那么根据Spring中提供的命名规则为当前bean生成对应beanName
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);
}
}
} catch (Exception ex) {
error(ex.getMessage(), ele);
return null;
}
}
String[] aliasesArray = StringUtils.toStringArray(aliases);
// 4.
return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray);
}
return null;
}
/** 对`<bean>`详细属性解析
* Parse the bean definition itself, without regard to name or aliases. May return
* {@code null} if problems occurred during the parsing of the bean definition.
*/
@Nullable
public AbstractBeanDefinition parseBeanDefinitionElement(
Element ele, String beanName, @Nullable BeanDefinition containingBean) {
// 元素标签状态类`解析中`
this.parseState.push(new BeanEntry(beanName));
// class属性,将<bean>存入BD,有class即可反射
String className = null;
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 {
// 1.. <bean> => GenericBeanDefinition
AbstractBeanDefinition bd = createBeanDefinition(className, parent);
// 解析bean标签的各种其他属性
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
// -------------------- 子标签 --------------------
// <description></description>
bd.setDescription(DomUtils.getChildElementValueByTagName(ele, DESCRIPTION_ELEMENT));
// <meta key="" value="">
parseMetaElements(ele, bd);
// <lookup-method>
parseLookupOverrideSubElements(ele, bd.getMethodOverrides());
// <replaced-method>
parseReplacedMethodSubElements(ele, bd.getMethodOverrides());
// <constructor-arg>
parseConstructorArgElements(ele, bd);
// <property>类似于<constructor-arg>
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;
}
protected AbstractBeanDefinition createBeanDefinition(@Nullable String className, @Nullable String parentName)
throws ClassNotFoundException {
// 1.
return BeanDefinitionReaderUtils.createBeanDefinition(
parentName, className, this.readerContext.getBeanClassLoader());
}
}
1. BeanDefinitionReaderUtils
public abstract class BeanDefinitionReaderUtils {
public static AbstractBeanDefinition createBeanDefinition(
@Nullable String parentName, @Nullable String className, @Nullable ClassLoader classLoader) throws ClassNotFoundException {
// 1.
GenericBeanDefinition bd = new GenericBeanDefinition();
bd.setParentName(parentName);
if (className != null) {
if (classLoader != null) {
// 2.
bd.setBeanClass(ClassUtils.forName(className, classLoader));
} else {
// 3.
bd.setBeanClassName(className);
}
}
return bd;
}
}
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
@Nullable
private volatile Object beanClass;
// 1. defaultElement存beanClassName
@Override
public void setBeanClassName(@Nullable String beanClassName) {
this.beanClass = beanClassName;
}
// 2. CustomElement存Class
public void setBeanClass(@Nullable Class<?> beanClass) {
this.beanClass = beanClass;
}
}
2. parseCustomElement()
public BeanDefinition parseCustomElement(Element ele, @Nullable BeanDefinition containingBd) {
/*
* 1.. 获取对应的命名空间
* http://www.springframework.org/schema/context
* http://www.springframework.org/schema/aop
*/
String namespaceUri = getNamespaceURI(ele);
/*
* 1. namespace => Spring.handles => NamespaceHandler
* 2. init() => @Override
* 3. registerBeanDefinitions(Document, Resource) => createReaderContext()
*/
NamespaceHandler handler = this.readerContext.getNamespaceHandlerResolver().resolve(namespaceUri);
/*
* 1. 自定义NamespaceHandler进行解析
* 2. ParserContext,保存解析过程中的状态、标志、属性值(不用关心)
* 3. NamespaceHandlerSupport
*/
return handler.parse(ele, new ParserContext(this.readerContext, this, containingBd));
}
@Nullable
public String getNamespaceURI(Node node) {
// 1.
return node.getNamespaceURI();
}
1. NamespaceHandler#init()
- 反射
NamespaceHandler
并缓存 - 调用
init()
将Parser缓存到父类NamespaceHandlerSupport.parsers
中 - 3. MyTag
MyTagNamespaceHandler#init()
4. NamespaceHandlerSupport
// 加载Parser
public abstract class NamespaceHandlerSupport implements NamespaceHandler {
private final Map<String, BeanDefinitionParser> parsers = new HashMap<>();
protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
this.parsers.put(elementName, parser);
}
// ------------------------------------------------------------------------------------
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 1.. 获取元素的解析器
BeanDefinitionParser parser = findParserForElement(element, parserContext);
// 2... AbstractBeanDefinitionParser
return (parser != null ? parser.parse(element, parserContext) : null);
}
private BeanDefinitionParser findParserForElement(Element element, ParserContext parserContext) {
// 1. 获取元素名称,property-placeholder
String localName = parserContext.getDelegate().getLocalName(element);
// 2. 元素名称 => 对应的解析器,PropertyPlaceholderBeanDefinitionParser
BeanDefinitionParser parser = this.parsers.get(localName);
if (parser == null) {
parserContext.getReaderContext().fatal(
"Cannot locate BeanDefinitionParser for element [" + localName + "]", element);
}
return parser;
}
}
5. BD_Parser
ConfigBeanDefinitionParser
、ComponentScanBeanDefinitionParser
直接实现parse()
1. AbstractBDParser
public abstract class AbstractBeanDefinitionParser implements BeanDefinitionParser {
@Override
@Nullable
public final BeanDefinition parse(Element element, ParserContext parserContext) {
/*
* 1... AbstractSingleBeanDefinitionParser
* ---------------------------------
* 1. GenericBeanDefinition
* 2. getBeanClass() => @Override
* 3. doParse() => @Override
*/
AbstractBeanDefinition definition = parseInternal(element, parserContext);
if (definition != null && !parserContext.isNested()) {
try {
String id = resolveId(element, definition, parserContext);
if (!StringUtils.hasText(id)) {
parserContext.getReaderContext().error(
"Id is required for element '" + parserContext.getDelegate().getLocalName(element)
+ "' when used as a top-level tag", element);
}
String[] aliases = null;
if (shouldParseNameAsAliases()) {
String name = element.getAttribute(NAME_ATTRIBUTE);
if (StringUtils.hasLength(name)) {
aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
}
}
// 2. 封装BD_Holder
BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
// 3.. registerBD
registerBeanDefinition(holder, parserContext.getRegistry());
if (shouldFireEvents()) {
// 通知监听器进行处理
BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);
postProcessComponentDefinition(componentDefinition);
parserContext.registerComponent(componentDefinition);
}
} catch (BeanDefinitionStoreException ex) {
String msg = ex.getMessage();
parserContext.getReaderContext().error((msg != null ? msg : ex.toString()), element);
return null;
}
}
return definition;
}
protected void registerBeanDefinition(BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {
// 1.
BeanDefinitionReaderUtils.registerBeanDefinition(definition, registry);
}
}
2. AbstractSingleBDParser
public abstract class AbstractSingleBeanDefinitionParser extends AbstractBeanDefinitionParser {
@Override
protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) {
// 1. GenericBeanDefinition
BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition();
String parentName = getParentName(element);
if (parentName != null) {
builder.getRawBeanDefinition().setParentName(parentName);
}
// 2... MyTagBeanDefinitionParser#getBeanClass() => @Override, 获取自定义标签中class
Class<?> beanClass = getBeanClass(element);
if (beanClass != null) {
builder.getRawBeanDefinition().setBeanClass(beanClass);
} else {
// 子类没有重写getBeanClass(),则尝试检查子类是否重写getBeanClassName()
String beanClassName = getBeanClassName(element);
if (beanClassName != null) {
builder.getRawBeanDefinition().setBeanClassName(beanClassName);
}
}
builder.getRawBeanDefinition().setSource(parserContext.extractSource(element));
BeanDefinition containingBd = parserContext.getContainingBeanDefinition();
if (containingBd != null) {
// Inner bean definition must receive same scope as containing bean.
// 若存在父类,则使用父类的scope属性
builder.setScope(containingBd.getScope());
}
if (parserContext.isDefaultLazyInit()) {
// Default-lazy-init applies to custom bean definitions as well.
// 配置延迟加载
builder.setLazyInit(true);
}
// 3... MyTagBeanDefinitionParser#doParse() => @Override, PropertyPlaceholderBeanDefinitionParser
doParse(element, parserContext, builder);
// 4.
return builder.getBeanDefinition();
}
}
3. MyTag
public class T3_MyTag {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x2_MyTag.xml");
System.out.println("------------------- ac.over -------------------");
MyTag myTag = ac.getBean("myTag", MyTag.class);
System.out.println("myTag = " + myTag);
ac.close();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!--
1. xsi:业界默认的用于XSD(XML_Schema_Definition)文件的命名空间
2. XML解析器可以根据一个XSD来解析另一个XML
3. xsi:schemaLocation = 键 值
1. 键:namespace
2. 值:XSD位置
-->
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:listao="http://www.listao.site/schema/myTag"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.listao.site/schema/myTag http://www.listao.site/schema/myTag.xsd
">
<listao:myTag id="myTag" name="ooxx" age="18"/>
</beans>
public class MyTag {
private String id;
private String name;
private Integer age;
// ...
}
http\://www.listao.site/schema/myTag.xsd=META-INF/myTag.xsd
<?xml version="1.0" encoding="UTF-8"?>
<schema xmlns="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://www.listao.site/schema/myTag"
elementFormDefault="qualified"
>
<element name="myTag">
<complexType>
<attribute name="id" type="string"/>
<attribute name="name" type="string"/>
<attribute name="age" type="integer"/>
</complexType>
</element>
</schema>
http\://www.listao.site/schema/myTag=com.listao.myTag.MyTagNamespaceHandler
1. MyTagNamespaceHandler
/**
* 1. NamespaceHandler => namespace处理类
* 2. 调用:DefaultNamespaceHandlerResolver.resolve()
* 3. 抄:class ContextNamespaceHandler extends NamespaceHandlerSupport
*/
public class MyTagNamespaceHandler extends NamespaceHandlerSupport {
/**
* 调用init()将ooxxParser缓存到NamespaceHandlerSupport.parsers中
*/
@Override
public void init() {
registerBeanDefinitionParser("myTag", new MyTagBeanDefinitionParser());
}
}
2. MyTagBeanDefinitionParser
/**
* 1. BD解析类
* 2. 调用:
* 3. 抄:PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser
*/
public class MyTagBeanDefinitionParser extends AbstractSingleBeanDefinitionParser {
@Override
protected Class<?> getBeanClass(Element element) {
return MyTag.class;
}
@Override
protected void doParse(Element element, BeanDefinitionBuilder builder) {
// 获取标签具体的属性值
String id = element.getAttribute("id");
String name = element.getAttribute("name");
String age = element.getAttribute("age");
// 将xml中的属性值 => BD
if (StringUtils.hasText(id)) {
builder.addPropertyValue("id", id);
}
if (StringUtils.hasText(name)) {
builder.addPropertyValue("name", name);
}
if (StringUtils.hasText(age)) {
builder.addPropertyValue("age", age);
}
}
}
3. prepareBeanFactory()
// Prepare the bean factory for use in this context.
// BF前戏,各种属性填充`add(), register()`
prepareBeanFactory(beanFactory);
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
/*
* 1. 设置BF表达式语言处理器。SpEL(Spring Expression Language)=> #{}
* StandardBeanExpressionResolver(处理器类)
* => SpelExpressionParser(解析器类)
* => SpelParserConfiguration(配置类)
*/
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 2. 属性编辑器 => BF.propertyEditorRegistrars
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 3. Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 4. 忽略自动装配的接口,这些接口由ACAwareProcessor处理。@Autowired注入时进行忽略
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.
/*
* 类似@Primary,在byType有多个情况,进行具体指定
* IOC初始化有多个实现,使用指定的对象注入
*/
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.
/*
* 织入三种方式,编译器织入、类加载器织入、运行期织入
* 1. 编译器织入:指在java编译器,采用特殊的编译器,将切面织入到java类中
* 2. 类加载期织入:指通过特殊的类加载器,在类字节码加载到JVM时,织入切面
* 3. 运行期织入:采用cglib和jdk进行切面的织入
* 增加对AspectJ的支持,Aspectj提供两种织入方式
* 1. 通过特殊编译器,将Aspectj语言编写的切面类织入到java类中
* 2. 类加载期织入,就是下面的load_time_weaving
*/
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { // loadTimeWeaver
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 5. Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { // environment
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { // systemProperties
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { // systemEnvironment
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
}
1. StandardBnExpressionResolver
/*
* 1. 设置BF表达式语言处理器。SpEL(Spring Expression Language)=> #{}
* StandardBeanExpressionResolver(处理器类)
* => SpelExpressionParser(解析器类)
* => SpelParserConfiguration(配置类)
*/
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
2. ResourceEditorRegistrar
// 2. 属性编辑器 => BF.propertyEditorRegistrars
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
- 属性编辑器统一注册
public class ResourceEditorRegistrar implements PropertyEditorRegistrar {
private final PropertyResolver propertyResolver;
private final ResourceLoader resourceLoader;
public ResourceEditorRegistrar(ResourceLoader resourceLoader, PropertyResolver propertyResolver) {
this.resourceLoader = resourceLoader;
this.propertyResolver = propertyResolver;
}
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
ResourceEditor baseEditor = new ResourceEditor(this.resourceLoader, this.propertyResolver);
// 1..
doRegisterEditor(registry, Resource.class, baseEditor);
doRegisterEditor(registry, ContextResource.class, baseEditor);
doRegisterEditor(registry, InputStream.class, new InputStreamEditor(baseEditor));
doRegisterEditor(registry, InputSource.class, new InputSourceEditor(baseEditor));
doRegisterEditor(registry, File.class, new FileEditor(baseEditor));
doRegisterEditor(registry, Path.class, new PathEditor(baseEditor));
doRegisterEditor(registry, Reader.class, new ReaderEditor(baseEditor));
doRegisterEditor(registry, URL.class, new URLEditor(baseEditor));
ClassLoader classLoader = this.resourceLoader.getClassLoader();
doRegisterEditor(registry, URI.class, new URIEditor(classLoader));
doRegisterEditor(registry, Class.class, new ClassEditor(classLoader));
doRegisterEditor(registry, Class[].class, new ClassArrayEditor(classLoader));
if (this.resourceLoader instanceof ResourcePatternResolver) {
doRegisterEditor(registry, Resource[].class,
new ResourceArrayPropertyEditor((ResourcePatternResolver) this.resourceLoader, this.propertyResolver));
}
}
/**
* 覆盖默认的编辑器,否则注册作为一个定制的编辑器
* <p>
* Override default editor, if possible (since that's what we really mean to do here);
* otherwise register as a custom editor.
*/
private void doRegisterEditor(PropertyEditorRegistry registry, Class<?> requiredType, PropertyEditor editor) {
if (registry instanceof PropertyEditorRegistrySupport) {
((PropertyEditorRegistrySupport) registry).overrideDefaultEditor(requiredType, editor);
} else {
registry.registerCustomEditor(requiredType, editor);
}
}
}
1. MyEditor
public class T4_MyEditor {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x3_1_MyEditor.xml");
System.out.println("------------------- ac.over -------------------");
MyEditor myEditor = ac.getBean("myEditor", MyEditor.class);
// myEditor = Customer{name='张三', address=Address{province='河北省', city='邯郸市', town='武安市'}}
System.out.println("myEditor = " + myEditor);
ac.close();
}
}
1. xml
- 向
CustomEditorConfigurer
注入属性propertyEditorRegistrars
或者customEditors
<bean id="myEditor" class="com.listao.myEditor.MyEditor">
<property name="name" value="张三"/>
<!-- private Address address; -->
<property name="address" value="河北省_邯郸市_武安市"/>
</bean>
<!-- CustomEditorConfigurer implements BeanFactoryPostProcessor, Ordered -->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="propertyEditorRegistrars">
<!-- private PropertyEditorRegistrar[] propertyEditorRegistrars; -->
<list>
<bean class="com.listao.myEditor.MyPropertyEditorRegistrar"/>
</list>
</property>
</bean>
<!-- ============================================================================ -->
<!-- CustomEditorConfigurer implements BeanFactoryPostProcessor, Ordered -->
<bean class="org.springframework.beans.factory.config.CustomEditorConfigurer">
<property name="customEditors">
<map>
<entry key="com.listao.myEditor.Address" value="com.listao.myEditor.MyPropertyEditor"/>
</map>
</property>
</bean>
2. MyPropertyEditorRegistrar
public class MyPropertyEditorRegistrar implements PropertyEditorRegistrar {
@Override
public void registerCustomEditors(PropertyEditorRegistry registry) {
registry.registerCustomEditor(Address.class, new MyPropertyEditor());
}
}
3. MyPropertyEditor
public class MyPropertyEditor extends PropertyEditorSupport {
@Override
public void setAsText(String text) throws IllegalArgumentException {
String[] s = text.split("_");
Address address = new Address();
address.setProvince(s[0]);
address.setCity(s[1]);
address.setTown(s[2]);
this.setValue(address);
}
}
2. invokeBFPP()
- 将
CustomEditorConfigurer
的propertyEditorRegistrars
、customEditors
集合 =>AbstractBeanFactory
CustomEditorConfigurer#postProcessBeanFactory()
1. CustomEditorConfigurer
public class CustomEditorConfigurer implements BeanFactoryPostProcessor, Ordered {
@Nullable
private PropertyEditorRegistrar[] propertyEditorRegistrars;
@Nullable
private Map<Class<?>, Class<? extends PropertyEditor>> customEditors;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
// 属性编辑注册器的集合 => BF
if (this.propertyEditorRegistrars != null) {
for (PropertyEditorRegistrar propertyEditorRegistrar : this.propertyEditorRegistrars) {
// 1... AbstractBeanFactory
beanFactory.addPropertyEditorRegistrar(propertyEditorRegistrar);
}
}
// 自定义编辑器集合 => BF
if (this.customEditors != null) {
// 2... AbstractBeanFactory
this.customEditors.forEach(beanFactory::registerCustomEditor);
}
}
}
2. AbstractBeanFactory
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
/**
* 1. 定制PropertyEditorRegistrars应用于此工厂的bean
* Custom PropertyEditorRegistrars to apply to the beans of this factory.
*/
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
/**
* 2. 定制PropertyEditor应用于该工厂的bean
* Custom PropertyEditors to apply to the beans of this factory.
*/
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);
@Override
public void addPropertyEditorRegistrar(PropertyEditorRegistrar registrar) {
this.propertyEditorRegistrars.add(registrar);
}
@Override
public void registerCustomEditor(Class<?> requiredType, Class<? extends PropertyEditor> propertyEditorClass) {
this.customEditors.put(requiredType, propertyEditorClass);
}
}
3. initBeanWrapper()
AbstractBeanFactory
属性propertyEditorRegistrars
、customEditors
(两个属性,合并成一个属性)传递给BeanWrapper
的customEditors
instantiateBean() => initBeanWrapper() => registerCustomEditors()
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
private final Set<PropertyEditorRegistrar> propertyEditorRegistrars = new LinkedHashSet<>(4);
private final Map<Class<?>, Class<? extends PropertyEditor>> customEditors = new HashMap<>(4);
protected void registerCustomEditors(PropertyEditorRegistry registry) {
PropertyEditorRegistrySupport registrySupport =
(registry instanceof PropertyEditorRegistrySupport ? (PropertyEditorRegistrySupport) registry : null);
if (registrySupport != null) {
registrySupport.useConfigValueEditors();
}
// 1. BF.propertyEditorRegistrars => bw.customEditors
if (!this.propertyEditorRegistrars.isEmpty()) {
for (PropertyEditorRegistrar registrar : this.propertyEditorRegistrars) {
// ResourceEditorRegistrar 默认的(ResourceEditor, InputStreamEditor ...)
// 2. MyPropertyEditorRegistrar自定义注册
registrar.registerCustomEditors(registry);
}
}
// 在SpringBoot中,customEditors默认是空的
if (!this.customEditors.isEmpty()) {
// 3. BF.customEditors => bw.customEditors
this.customEditors.forEach((requiredType, editorClass) ->
registry.registerCustomEditor(requiredType, BeanUtils.instantiateClass(editorClass)));
}
}
}
1. PropertyEditorRegistrySupport
PropertyEditorRegistrySupport#registerCustomEditor()
- 子类构造,默认调用父类构造。父类private属性子类无法继承,不过可以通过public方法使用private属性
public class PropertyEditorRegistrySupport implements PropertyEditorRegistry
// 转换服务
@Nullable
private ConversionService conversionService;
// 重写默认属性编辑器集合
@Nullable
private Map<Class<?>, PropertyEditor> overriddenDefaultEditors;
// 1. 自定义属性编辑器集合
@Nullable
private Map<Class<?>, PropertyEditor> customEditors;
@Override
public void registerCustomEditor(Class<?> requiredType, PropertyEditor propertyEditor) {
registerCustomEditor(requiredType, null, propertyEditor);
}
@Override
public void registerCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath, PropertyEditor propertyEditor) {
if (requiredType == null && propertyPath == null) {
throw new IllegalArgumentException("Either requiredType or propertyPath is required");
}
if (propertyPath != null) {
if (this.customEditorsForPath == null) {
this.customEditorsForPath = new LinkedHashMap<>(16);
}
this.customEditorsForPath.put(propertyPath, new CustomEditorHolder(propertyEditor, requiredType));
} else {
if (this.customEditors == null) {
this.customEditors = new LinkedHashMap<>(16);
}
// 99.
this.customEditors.put(requiredType, propertyEditor);
this.customEditorCache = null;
}
}
// ------------------------------------------------------------------------------------------------------
@Override
@Nullable
public PropertyEditor findCustomEditor(@Nullable Class<?> requiredType, @Nullable String propertyPath) {
Class<?> requiredTypeToUse = requiredType;
if (propertyPath != null) {
if (this.customEditorsForPath != null) {
// Check property-specific editor first.
PropertyEditor editor = getCustomEditor(propertyPath, requiredType);
if (editor == null) {
List<String> strippedPaths = new ArrayList<>();
addStrippedPropertyPaths(strippedPaths, "", propertyPath);
for (Iterator<String> it = strippedPaths.iterator(); it.hasNext() && editor == null; ) {
String strippedPath = it.next();
editor = getCustomEditor(strippedPath, requiredType);
}
}
if (editor != null) {
return editor;
}
}
if (requiredType == null) {
requiredTypeToUse = getPropertyType(propertyPath);
}
}
// 1.. No property-specific editor -> check type-specific editor.
return getCustomEditor(requiredTypeToUse);
}
@Nullable
private PropertyEditor getCustomEditor(@Nullable Class<?> requiredType) {
if (requiredType == null || this.customEditors == null) {
return null;
}
// 1. Check directly registered editor for type.
PropertyEditor editor = this.customEditors.get(requiredType);
if (editor == null) {
// Check cached editor for type, registered for superclass or interface.
if (this.customEditorCache != null) {
editor = this.customEditorCache.get(requiredType);
}
if (editor == null) {
// Find editor for superclass or interface.
for (Iterator<Class<?>> it = this.customEditors.keySet().iterator(); it.hasNext() && editor == null; ) {
Class<?> key = it.next();
if (key.isAssignableFrom(requiredType)) {
editor = this.customEditors.get(key);
// Cache editor for search type, to avoid the overhead
// of repeated assignable-from checks.
if (this.customEditorCache == null) {
this.customEditorCache = new HashMap<>();
}
this.customEditorCache.put(requiredType, editor);
}
}
}
}
return editor;
}
}
4. populateBean()
MyPropertyEditor#setAsText()
3. ACAwareProcessor
- AC_aware =>
ApplicationContextAwareProcessor#postProcessBeforeInitialization()
- BF_aware =>
invokeAwareMethods()
// Configure the bean factory with context callbacks.
// BPP => 处理AC_aware
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
class ApplicationContextAwareProcessor implements BeanPostProcessor {
private final ConfigurableApplicationContext applicationContext;
@Override
@Nullable
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (!(bean instanceof EnvironmentAware || bean instanceof EmbeddedValueResolverAware ||
bean instanceof ResourceLoaderAware || bean instanceof ApplicationEventPublisherAware ||
bean instanceof MessageSourceAware || bean instanceof ApplicationContextAware)) {
return bean;
}
// 1..
invokeAwareInterfaces(bean);
return bean;
}
/**
* 如果某个bean实现了某个aware接口,给指定的bean设置相应的属性值
*/
private void invokeAwareInterfaces(Object bean) {
if (bean instanceof EnvironmentAware) {
((EnvironmentAware) bean).setEnvironment(this.applicationContext.getEnvironment());
}
if (bean instanceof EmbeddedValueResolverAware) {
((EmbeddedValueResolverAware) bean).setEmbeddedValueResolver(this.embeddedValueResolver);
}
if (bean instanceof ResourceLoaderAware) {
((ResourceLoaderAware) bean).setResourceLoader(this.applicationContext);
}
if (bean instanceof ApplicationEventPublisherAware) {
((ApplicationEventPublisherAware) bean).setApplicationEventPublisher(this.applicationContext);
}
if (bean instanceof MessageSourceAware) {
((MessageSourceAware) bean).setMessageSource(this.applicationContext);
}
if (bean instanceof ApplicationContextAware) {
((ApplicationContextAware) bean).setApplicationContext(this.applicationContext);
}
}
}
1. invokeAwareMethods()
- 处理BF_aware
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
implements AutowireCapableBeanFactory {
/**
* 构造方法,忽略`BeanNameAware, BeanFactoryAware, BeanClassLoaderAware`
* <p>
* Create a new AbstractAutowireCapableBeanFactory.
*/
public AbstractAutowireCapableBeanFactory() {
super();
// 忽略进行IOC的接口现实类,由invokeAwareMethod()统一处理
ignoreDependencyInterface(BeanNameAware.class);
ignoreDependencyInterface(BeanFactoryAware.class);
ignoreDependencyInterface(BeanClassLoaderAware.class);
}
/**
* 1. `BeanNameAware, BeanClassLoaderAware, BeanFactoryAware`
* 2. AbstractAutowireCapableBeanFactory()构造方法,忽略这三个接口
*/
private void invokeAwareMethods(String beanName, Object bean) {
if (bean instanceof Aware) {
if (bean instanceof BeanNameAware) {
((BeanNameAware) bean).setBeanName(beanName);
}
if (bean instanceof BeanClassLoaderAware) {
// 获取此工厂的类加载器以加载Bean类(即使无法使用系统ClassLoader,也只能为null)
ClassLoader bcl = getBeanClassLoader();
if (bcl != null) {
((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
}
}
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
}
}
}
}
4. ignoreDependencyInterface()
/*
* 1. 忽略自动装配的接口,这些接口由ApplicationContextAwareProcessor处理
* 2. @Autowired注入时进行忽略
* 3. 其他忽略接口,AbstractAutowireCapableBeanFactory()
* 4. `ignoredDependencyInterfaces, ignoredDependencyTypes`
*/
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
5. environment_beans
- 注册环境bean到一级缓存
// Register default environment beans.
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { // environment
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { // systemProperties
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { // systemEnvironment
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
4. postProcessBeanFactory()
/*
* 1. 模板方法,后续拓展
* 2. 子类重写做额外的处理,查看web中的代码,有具体实现的
*/
postProcessBeanFactory(beanFactory);
- 在Spring进行任意拓展,一定是要获取并修改BF对象
- 反射在进行值处理时两种方式
- 获取该属性对象Filed,
Filed.set()
进行设置 - 获取该属性对应的
setter()
进行赋值操作
- 获取该属性对象Filed,
@Autowired
原理- 应用字段上,可以获取到Field对象,
Field.set()
- 应用
setter()
上
- 应用字段上,可以获取到Field对象,
/**
* 重写拓展方法,@Override
* <p>
* 1. initPropertySources()
* 2. customizeBeanFactory()
* 3. postProcessBeanFactory()
*/
public class T2_MyCPXAC { // MyClassPathXmlApplicationContext
public static void main(String[] args) {
MyCPXAC_1 ac = new MyCPXAC_1("x0_ooxx.xml");
System.out.println("------------------- ac.over -------------------");
ac.close();
}
}
/**
* MyClassPathXmlApplicationContext
*/
public class MyCPXAC_1 extends ClassPathXmlApplicationContext {
public MyCPXAC_1(String... configLocations) {
super(configLocations);
}
@Override
protected void initPropertySources() {
System.out.println("扩展 ==> MyCPXAC_1.initPropertySource()");
// 必要Environment设置。程序检测到没user,直接阻断程序
getEnvironment().setRequiredProperties("user");
// 必要Environment校验
// getEnvironment().validateRequiredProperties();
}
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
System.out.println("扩展 ==> MyCPXAC_1.customizeBeanFactory()");
super.setAllowBeanDefinitionOverriding(false);
super.setAllowCircularReferences(false);
// super.addBeanFactoryPostProcessor(new MyBeanFactoryPostProcessor());
super.customizeBeanFactory(beanFactory);
}
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
System.out.println("扩展 ==> MyCPXAC_1.postProcessBeanFactory()");
}
}
5. invokeBFPP()
// Invoke factory processors registered as beans in the context.
/*
* 1. 实例化 & 执行BFPP
* 2. 首次getBean()
*/
invokeBeanFactoryPostProcessors(beanFactory);
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext {
private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>();
/**
* 1. 实例化 & 调用所有注册的BFPP,遵循指明的顺序
* 2. 必须在bean实例化前完成,调用BFPP,完成修改BD
* <p>
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
/*
* 1. 获取到当前应用程序上下文的BFPP,并且实例化调用执行所有已经注册的BFPP
* 2. 默认情况下,通过getBFPP()来获取已经注册的BFPP,但是默认是空的,那么问题来了,如果你想扩展,怎么进行扩展工作?
*/
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { // loadTimeWeaver
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
}
final class PostProcessorRegistrationDelegate {
/*
* 将BFPP分类执行,@Order(1)
* 1. `implements BeanDefinitionRegistryPostProcessor`
* 1. 入参自定义BFPP
* 2. 优先级高的,PriorityOrdered.class
* 3. 排序的,Ordered.class
* 4. noOrdered
* 2. `implements BeanFactoryPostProcessor`
* 1. 入参自定义BFPP
* 2. 优先级高的,PriorityOrdered.class
* 3. 排序的,Ordered.class
* 4. noOrdered
*/
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
// 处理过的BDRPP
Set<String> processedBeans = new HashSet<>();
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
// BFPP集合
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
// BDRPP集合
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
// 处理入参BFPP(手动添加的)
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
// 执行BDRPP
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
} else {
regularPostProcessors.add(postProcessor);
}
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
// Separate between BeanDefinitionRegistryPostProcessors that implement
// PriorityOrdered, Ordered, and the rest.
// 保存本次要执行的BDRPP
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
// ----------------------- implement BeanDefinitionRegistryPostProcessors, PriorityOrdered -----------------------
// First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// implements PriorityOrdered
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
// BFPP添加,避免后续重复执行
processedBeans.add(ppName);
}
}
// 优先级排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加到BFPP集合
registryProcessors.addAll(currentRegistryProcessors);
// 执行BDRPP
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
// 清空currentRegistryProcessors
currentRegistryProcessors.clear();
// ----------------------- implement BeanDefinitionRegistryPostProcessors, Ordered -----------------------
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 检测还未执行过,且`implement Ordered`
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
// ----------------------- implement BeanDefinitionRegistryPostProcessors -----------------------
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
/*
* 1. invokeBeanDefinitionRegistryPostProcessors()可能新增BDRPP实现类,因此用while处理
* 2. 新增BDRPP,可能`implement PriorityOrdered, implement Ordered`,因此仍需sortPostProcessors()
*/
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 跳过执行过的BDRPP
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// Now, invoke the postProcessBeanFactory callback of all processors handled so far.
// 执行BDRPP.postProcessBeanFactory()
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
// 执行BFPP.postProcessBeanFactory()
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
// 直接处理入参BFPP
else {
// Invoke factory processors registered with the context instance.
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//-------------------------------------------------------------------------
// 1. 到这里为止,`implements BeanDefinitionRegistryPostProcessor`及入参BFPP。处理完
// 2. 开始处理。`implements BeanFactoryPostProcessor`
//-------------------------------------------------------------------------
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the bean factory post-processors apply to them!
/*
* 1. BFPP接口的所有实现类。`implements BeanFactoryPostProcessor`
* 2. 不需要重复调用,不会新增BFPP实现类
* 3. org.springframework.beans.factory.config.CustomEditorConfigurer#0 implements BeanFactoryPostProcessor
*/
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
// Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) { // 跳过处理的bean
// skip - already processed in first phase above
}
// `implements PriorityOrdered`
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
// `implements Ordered`
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
// nonOrdered
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
// `implement BeanFactoryPostProcessor, Ordered`
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
// Second, invoke the BeanFactoryPostProcessors that implement Ordered.
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
// Finally, invoke all other BeanFactoryPostProcessors.
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
/*
* 1. 清除元数据缓存(mergeBeanDefinitions, allBeanNamesByType, singletonBeanNameByType)
* 2. 后置处理器可能已经修改了原始元数据。eg:替换值中的占位符
*/
beanFactory.clearMetadataCache();
}
// ---------------------------------------------------------------------------------------------------------
/**
* 调用给定BeanDefinitionRegistryPostProcessor,Bean对象
* <p>
* Invoke the given BeanDefinitionRegistryPostProcessor beans.
*/
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
// 调用 postProcessor 的 postProcessBeanDefinitionRegistry以使得postProcess往registry注册BeanDefinition对象
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
/**
* 调用给定的BeanFactoryPostProcessor,Bean对象
* <p>
* Invoke the given BeanFactoryPostProcessor beans.
*/
private static void invokeBeanFactoryPostProcessors(
Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) {
for (BeanFactoryPostProcessor postProcessor : postProcessors) {
// 回调 BeanFactoryPostProcessor 的 postProcessBeanFactory 方法,使得每个postProcessor对象都可以对
// beanFactory进行调整
postProcessor.postProcessBeanFactory(beanFactory);
}
}
}
1. 注入IOC
public class MyBFPP implements BeanFactoryPostProcessor, PriorityOrdered {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("===>>> MyBFPP.postProcessBeanFactory()");
}
@Override
public int getOrder() {
return 0;
}
}
1. Spring_xml注入BFPP
<bean class="com.listao.postProcessor.bfpp.MyBFPP"/>
public class T5_BFPP {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x4_MyBFPP.xml");
System.out.println("------------------- ac.over -------------------");
ac.close();
}
}
2. ClassPathXmlAC注入BFPP
public class MyCPXAC_2 extends ClassPathXmlApplicationContext {
public MyCPXAC_4(String... configLocations) {
super(configLocations);
}
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
System.out.println("扩展 ==> MyCPXAC_2.customizeBeanFactory()");
// MyBFPP对象不归Spring管理,属性入参型
super.addBeanFactoryPostProcessor(new MyBFPP());
}
}
/*
* 1. xml注入
* 2. ClassPathXmlApplicationContext注入BFPP
*/
class T5_CustomizeBeanFactory {
public static void main(String[] args) {
MyCPXAC_2 ac = new MyCPXAC_2();
System.out.println("------------------- ac.over -------------------");
ac.close();
}
}
3. @Component
ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered
会优先invokeBFPP()
- 自定义的 BFPP 经过
ConfigurationClassPostProcessor
解析,注册到 IOC 容器中,再invokeBFPP()
2. invokeBFPP图解
/*
* 将BFPP分类执行,@Order(1)
* 1. `implements BeanDefinitionRegistryPostProcessor`
* 1. 入参自定义BFPP
* 2. 优先级高的,PriorityOrdered.class
* 3. 排序的,Ordered.class
* 4. noOrdered
* 2. `implements BeanFactoryPostProcessor`
* 1. 入参自定义BFPP
* 2. 优先级高的,PriorityOrdered.class
* 3. 排序的,Ordered.class
* 4. noOrdered
*/
public interface BeanFactoryPostProcessor {
// 1. ConfigurableListableBeanFactory对BF的CRUD。BF里包含了BD
void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;
}
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
// 2. BeanDefinitionRegistry对BD的CRUD
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
3. MyBDRPP
/*
* 1. BDRPP,多次调用以下方法
* 2. 进行invokeBDRPP()时,又可以进行了BDRPP注册
*/
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
// 处理BFPP,只一次调用以下方法,invokeBFPP()无法再注册BFPP
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
class T5_MyBDRPP {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x5_MyBDRPP.xml");
System.out.println("------------------- ac.over -------------------");
ac.close();
}
}
<bean id="myBDRPP" class="com.listao.postProcessor.bfpp.bdrpp.MyBDRPP"/>
public class MyBDRPP implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
/**
* BF中增加BD(BD为BDRPP)
*/
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("==> MyBDRPP.postProcessBeanDefinitionRegistry()");
// BF中增加BD(BD为自定义类)
registry.registerBeanDefinition("ooxx", new RootBeanDefinition(Ooxx.class));
// BF中新增BDRPP,依旧归Spring管理
BeanDefinitionBuilder builder = BeanDefinitionBuilder.rootBeanDefinition(MyBDRPP2.class);
builder.addPropertyValue("name", "ooxx");
registry.registerBeanDefinition("myBDRPP2", builder.getBeanDefinition());
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("==> MyBDRPP.postProcessBeanFactory()");
/*
* 1. 不能再新增BFPP
* 2. 不能改变BD中PropertyValue的value。value没有`setter()`
*/
BeanDefinition msb = beanFactory.getBeanDefinition("myBDRPP2");
msb.getPropertyValues().getPropertyValue("name").setConvertedValue("xxoo");
}
@Override
public int getOrder() {
return 0;
}
}
public class MyBDRPP2 implements BeanDefinitionRegistryPostProcessor, PriorityOrdered {
private String name;
public MyBDRPP2() {
System.out.println("MyBDRPP2()");
}
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
System.out.println("====> MyBDRPP2.postProcessBeanDefinitionRegistry()");
}
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("====> MyBDRPP2.postProcessBeanFactory()");
}
@Override
public int getOrder() {
return 0;
}
}
4. BFPP应用(实现类)
ConfigurationClassPostProcessor
解析@Configuration, @Bean, @Import, @Component, @ComponentScan, @ComponentScans
CustomEditorConfigurer
属性编辑处理- =>
BF.propertyEditorRegistrars
,BF.customEditors
- =>
PlaceholderConfigurerSupport
占位符处理
5. <property-placeholder>
T8_Placeholder
<context:property-placeholder location="classpath:p3_placeholder.properties"/>
<bean id="ooxx" class="com.listao.Ooxx">
<property name="id" value="${ooxx.id}"/>
<property name="name" value="${ooxx.name}"/>
</bean>
1. PropertyPlaceholderBDParser
public class ContextNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
// 1.
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
}
PropertyPlaceholderBeanDefinitionParser
执行doParse()
和getBeanClass()
生成- =>
PropertySourcesPlaceholderConfigurer
的BD => IOC
- =>
- invokeBFPP()
class PropertyPlaceholderBeanDefinitionParser extends AbstractPropertyLoadingBeanDefinitionParser {
@Override
@SuppressWarnings("deprecation")
protected Class<?> getBeanClass(Element element) {
// system-properties-mode
if (SYSTEM_PROPERTIES_MODE_DEFAULT.equals(element.getAttribute(SYSTEM_PROPERTIES_MODE_ATTRIBUTE))) {
// 1. 核心类
return PropertySourcesPlaceholderConfigurer.class;
}
// @Deprecated
return org.springframework.beans.factory.config.PropertyPlaceholderConfigurer.class;
}
@Override
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {
// 2. 父类,通用标签属性解析
super.doParse(element, parserContext, builder);
// ...
}
}
1. PropertySourcesPlaceholderCfger
public class PropertySourcesPlaceholderConfigurer extends PlaceholderConfigurerSupport implements EnvironmentAware {
public static final String LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME = "localProperties";
public static final String ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME = "environmentProperties";
private MutablePropertySources propertySources;
private Environment environment;
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
if (this.propertySources == null) {
this.propertySources = new MutablePropertySources();
if (this.environment != null) {
this.propertySources.addLast(
// 抽象类的匿名对象,重写了`getProperty()`。environmentProperties
new PropertySource<Environment>(ENVIRONMENT_PROPERTIES_PROPERTY_SOURCE_NAME, this.environment) {
@Override
@Nullable
public String getProperty(String key) {
return this.source.getProperty(key);
}
}
);
}
try {
// 1... PropertiesLoaderSupport 加载本地 `placeholder.properties`
PropertySource<?> localPropertySource = // localProperties
new PropertiesPropertySource(LOCAL_PROPERTIES_PROPERTY_SOURCE_NAME, mergeProperties());
if (this.localOverride) {
this.propertySources.addFirst(localPropertySource);
} else {
this.propertySources.addLast(localPropertySource);
}
} catch (IOException ex) {
throw new BeanInitializationException("Could not load properties", ex);
}
}
// 2.. 处理placeholder
processProperties(beanFactory, new PropertySourcesPropertyResolver(this.propertySources));
this.appliedPropertySources = this.propertySources;
}
protected void processProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
final ConfigurablePropertyResolver propertyResolver) throws BeansException {
propertyResolver.setPlaceholderPrefix(this.placeholderPrefix); // ${
propertyResolver.setPlaceholderSuffix(this.placeholderSuffix); // }
propertyResolver.setValueSeparator(this.valueSeparator); // :
StringValueResolver valueResolver = strVal -> {
String resolved = (this.ignoreUnresolvablePlaceholders ?
propertyResolver.resolvePlaceholders(strVal) :
propertyResolver.resolveRequiredPlaceholders(strVal));
if (this.trimValues) {
resolved = resolved.trim();
}
return (resolved.equals(this.nullValue) ? null : resolved);
};
// 1... PlaceholderConfigurerSupport
doProcessProperties(beanFactoryToProcess, valueResolver);
}
}
1. PropertiesLoaderSupport
- 加载自定义properties
PropertiesLoaderSupport#loadProperties()
public abstract class PropertiesLoaderSupport {
@Nullable
private Resource[] locations;
private PropertiesPersister propertiesPersister = new DefaultPropertiesPersister();
/**
* 返回一个合并的属性实例包含加载的属性和设置在factorybean中的属性
* <p>
* Return a merged Properties instance containing both the
* loaded properties and properties set on this FactoryBean.
*/
protected Properties mergeProperties() throws IOException {
Properties result = new Properties();
if (this.localOverride) {
// Load properties from file upfront, to let local properties override.
// 加载外部属性到结果对象中
loadProperties(result);
}
if (this.localProperties != null) {
// 将本地属性合并到结果对象
for (Properties localProp : this.localProperties) {
CollectionUtils.mergePropertiesIntoMap(localProp, result);
}
}
if (!this.localOverride) {
// Load properties from file afterwards, to let those properties override.
// 1.. 加载外部属性到结果对象中
loadProperties(result);
}
return result;
}
/**
* Load properties into the given instance.
*
* @param props the Properties instance to load into
* @throws IOException in case of I/O errors
* @see #setLocations
*/
protected void loadProperties(Properties props) throws IOException {
if (this.locations != null) {
for (Resource location : this.locations) {
if (logger.isTraceEnabled()) {
logger.trace("Loading properties file from " + location);
}
try {
// 1. 本地path(p3_placeholder.properties)=> Properties
PropertiesLoaderUtils.fillProperties(
props, new EncodedResource(location, this.fileEncoding), this.propertiesPersister);
} catch (FileNotFoundException | UnknownHostException | SocketException ex) {
if (this.ignoreResourceNotFound) {
if (logger.isDebugEnabled()) {
logger.debug("Properties resource not found: " + ex.getMessage());
}
} else {
throw ex;
}
}
}
}
}
}
2. PlaceholderConfigurerSupport
public abstract class PlaceholderConfigurerSupport extends PropertyResourceConfigurer
implements BeanNameAware, BeanFactoryAware {
/**
* 默认的占位符前缀
* <p>
* Default placeholder prefix: {@value}.
*/
public static final String DEFAULT_PLACEHOLDER_PREFIX = "${";
/**
* 默认的占位符后缀
* <p>
* Default placeholder suffix: {@value}.
*/
public static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";
/**
* 默认的值分隔符
* <p>
* Default value separator: {@value}.
*/
public static final String DEFAULT_VALUE_SEPARATOR = ":";
protected void doProcessProperties(ConfigurableListableBeanFactory beanFactoryToProcess,
StringValueResolver valueResolver) {
// 1.
BeanDefinitionVisitor visitor = new BeanDefinitionVisitor(valueResolver);
// 2. 遍历所有bean
String[] beanNames = beanFactoryToProcess.getBeanDefinitionNames();
for (String curName : beanNames) {
// Check that we're not parsing our own bean definition,
// to avoid failing on unresolvable placeholders in properties file locations.
if (!(curName.equals(this.beanName) && beanFactoryToProcess.equals(this.beanFactory))) {
BeanDefinition bd = beanFactoryToProcess.getBeanDefinition(curName);
try {
// 3... BeanDefinitionVisitor BD占位符解析
// bean属性值、bean构造函数参数值、双亲bean名称、bean类名、bean工厂名称、bean工厂方法名称、作用域
visitor.visitBeanDefinition(bd);
} catch (Exception ex) {
throw new BeanDefinitionStoreException(bd.getResourceDescription(), curName, ex.getMessage(), ex);
}
}
}
// New in Spring 2.5: resolve placeholders in alias target names and aliases as well.
// 4. 处理别名中的占位符
beanFactoryToProcess.resolveAliases(valueResolver);
// New in Spring 3.0: resolve placeholders in embedded values such as annotation attributes.
// 5. 设置占位符<内置值处理器>
beanFactoryToProcess.addEmbeddedValueResolver(valueResolver);
}
}
3. StringValueResolver
@FunctionalInterface
public interface StringValueResolver {
/**
* Resolve the given String value, for example parsing placeholders.
* @param strVal the original String value (never {@code null})
* @return the resolved String value (may be {@code null} when resolved to a null
* value), possibly the original String value itself (in case of no placeholders
* to resolve or when ignoring unresolvable placeholders)
* @throws IllegalArgumentException in case of an unresolvable String value
*/
@Nullable
String resolveStringValue(String strVal);
}
2. BeanDefinitionVisitor
BeanDefinitionVisitor#visitBeanDefinition()
public class BeanDefinitionVisitor {
@Nullable
private StringValueResolver valueResolver;
public BeanDefinitionVisitor(StringValueResolver valueResolver) {
Assert.notNull(valueResolver, "StringValueResolver must not be null");
this.valueResolver = valueResolver;
}
public void visitBeanDefinition(BeanDefinition beanDefinition) {
// 双亲BD名称
visitParentName(beanDefinition);
// BD类名
visitBeanClassName(beanDefinition);
// BD工厂名称
visitFactoryBeanName(beanDefinition);
// BD工厂方法名称
visitFactoryMethodName(beanDefinition);
// BD作用域
visitScope(beanDefinition);
if (beanDefinition.hasPropertyValues()) {
// 1.. BD属性值
visitPropertyValues(beanDefinition.getPropertyValues());
}
// BD构造函数参数值
if (beanDefinition.hasConstructorArgumentValues()) {
ConstructorArgumentValues cas = beanDefinition.getConstructorArgumentValues();
visitIndexedArgumentValues(cas.getIndexedArgumentValues());
visitGenericArgumentValues(cas.getGenericArgumentValues());
}
}
protected void visitPropertyValues(MutablePropertyValues pvs) {
PropertyValue[] pvArray = pvs.getPropertyValues();
for (PropertyValue pv : pvArray) {
// 1..
Object newVal = resolveValue(pv.getValue());
if (!ObjectUtils.nullSafeEquals(newVal, pv.getValue())) {
pvs.add(pv.getName(), newVal);
}
}
}
@Nullable
protected Object resolveValue(@Nullable Object value) {
if (value instanceof BeanDefinition) {
visitBeanDefinition((BeanDefinition) value);
} else if (value instanceof BeanDefinitionHolder) {
visitBeanDefinition(((BeanDefinitionHolder) value).getBeanDefinition());
} else if (value instanceof RuntimeBeanReference) {
RuntimeBeanReference ref = (RuntimeBeanReference) value;
String newBeanName = resolveStringValue(ref.getBeanName());
if (newBeanName == null) {
return null;
}
if (!newBeanName.equals(ref.getBeanName())) {
return new RuntimeBeanReference(newBeanName);
}
} else if (value instanceof RuntimeBeanNameReference) {
RuntimeBeanNameReference ref = (RuntimeBeanNameReference) value;
String newBeanName = resolveStringValue(ref.getBeanName());
if (newBeanName == null) {
return null;
}
if (!newBeanName.equals(ref.getBeanName())) {
return new RuntimeBeanNameReference(newBeanName);
}
} else if (value instanceof Object[]) {
visitArray((Object[]) value);
} else if (value instanceof List) {
visitList((List) value);
} else if (value instanceof Set) {
visitSet((Set) value);
} else if (value instanceof Map) {
visitMap((Map) value);
} else if (value instanceof TypedStringValue) {
TypedStringValue typedStringValue = (TypedStringValue) value;
String stringValue = typedStringValue.getValue();
if (stringValue != null) {
// 1..
String visitedString = resolveStringValue(stringValue);
typedStringValue.setValue(visitedString);
}
} else if (value instanceof String) {
return resolveStringValue((String) value);
}
return value;
}
@Nullable
protected String resolveStringValue(String strVal) {
if (this.valueResolver == null) {
throw new IllegalStateException("No StringValueResolver specified - pass a resolver " +
"object into the constructor or override the 'resolveStringValue' method");
}
// 1... StringValueResolver => AbstractPropertyResolver#resolvePlaceholders()
String resolvedValue = this.valueResolver.resolveStringValue(strVal);
// Return original String if not modified.
return (strVal.equals(resolvedValue) ? strVal : resolvedValue);
}
}
3. PropertySourcesPropertyResolver
PropertySourcesPlaceholderConfigurer#processProperties()
public class PropertySourcesPropertyResolver extends AbstractPropertyResolver {
@Nullable
private final PropertySources propertySources;
@Override
@Nullable
protected String getPropertyAsRawString(String key) {
// 1..
return getProperty(key, String.class, false);
}
@Nullable
protected <T> T getProperty(String key, Class<T> targetValueType, boolean resolveNestedPlaceholders) {
if (this.propertySources != null) {
for (PropertySource<?> propertySource : this.propertySources) {
if (logger.isTraceEnabled()) {
logger.trace("Searching for key '" + key + "' in PropertySource '" +
propertySource.getName() + "'");
}
// 1. 通过key => value
Object value = propertySource.getProperty(key);
if (value != null) {
if (resolveNestedPlaceholders && value instanceof String) {
value = resolveNestedPlaceholders((String) value);
}
logKeyFound(key, propertySource, value);
// 2... AbstractPropertyResolver value类型转化
return convertValueIfNecessary(value, targetValueType);
}
}
}
if (logger.isTraceEnabled()) {
logger.trace("Could not find key '" + key + "' in any property source");
}
return null;
}
}
1. AbstractPropertyResolver
public abstract class AbstractPropertyResolver implements ConfigurablePropertyResolver {
@Nullable
private volatile ConfigurableConversionService conversionService;
@Override
public String resolvePlaceholders(String text) {
if (this.nonStrictHelper == null) {
// 1..
this.nonStrictHelper = createPlaceholderHelper(true);
}
// 2..
return doResolvePlaceholders(text, this.nonStrictHelper);
}
private PropertyPlaceholderHelper createPlaceholderHelper(boolean ignoreUnresolvablePlaceholders) {
// 1.
return new PropertyPlaceholderHelper(this.placeholderPrefix, this.placeholderSuffix,
this.valueSeparator, ignoreUnresolvablePlaceholders);
}
private String doResolvePlaceholders(String text, PropertyPlaceholderHelper helper) {
// 1... PropertyPlaceholderHelper
return helper.replacePlaceholders(text, this::getPropertyAsRawString);
}
// ---------------------------------------------------------------------------------------
@Nullable
protected <T> T convertValueIfNecessary(Object value, @Nullable Class<T> targetType) {
if (targetType == null) {
return (T) value;
}
// 1.
ConversionService conversionServiceToUse = this.conversionService;
if (conversionServiceToUse == null) {
// Avoid initialization of shared DefaultConversionService if
// no standard type conversion is needed in the first place...
if (ClassUtils.isAssignableValue(targetType, value)) {
return (T) value;
}
conversionServiceToUse = DefaultConversionService.getSharedInstance();
}
// 2.
return conversionServiceToUse.convert(value, targetType);
}
}
4. PropertyPlaceholderHelper
@FunctionalInterface
- 类中直接包含函数式接口。a方法形参为该接口,实参可以为b类的任意方法,a中直接调接口方法即可
public class PropertyPlaceholderHelper {
static {
wellKnownSimplePrefixes.put("}", "{");
wellKnownSimplePrefixes.put("]", "[");
wellKnownSimplePrefixes.put(")", "(");
}
private final String placeholderPrefix;
private final String placeholderSuffix;
private final String simplePrefix;
@Nullable
private final String valueSeparator;
private final boolean ignoreUnresolvablePlaceholders;
public String replacePlaceholders(String value, PlaceholderResolver placeholderResolver) {
// 1..
return parseStringValue(value, placeholderResolver, null);
}
// 真正占位处理逻辑
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);
}
if (!visitedPlaceholders.add(originalPlaceholder)) {
throw new IllegalArgumentException(
"Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
}
// Recursive invocation, parsing placeholders contained in the placeholder key.
/*
* 1.. 递归调用:解析spring-${abc${def}}.xml => 得去key
*/
placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
// Now obtain the value for the fully resolved key...
// 2... PropertySourcesPropertyResolver#getPropertyAsRawString() 通过key => value
String propVal = placeholderResolver.resolvePlaceholder(placeholder);
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) {
// Recursive invocation, parsing placeholders contained in the
// previously resolved placeholder value.
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 + "\"");
}
visitedPlaceholders.remove(originalPlaceholder);
} else {
startIndex = -1;
}
}
return result.toString();
}
@FunctionalInterface
public interface PlaceholderResolver {
/**
* Resolve the supplied placeholder name to the replacement value.
*
* @param placeholderName the name of the placeholder to resolve
* @return the replacement value, or {@code null} if no replacement is to be made
*/
@Nullable
String resolvePlaceholder(String placeholderName);
}
}
6. registerBeanPostProcessors()
- BPP =>
BF.beanPostProcessors
// Register bean processors that intercept bean creation.
/*
* 1. 实例化前戏
* 2. 实例化 & 注册BPP。真正调用是getBean()
*/
registerBeanPostProcessors(beanFactory);
/**
* 实例化 & 注册所有BPP
* <p>
* Instantiate and register all BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
final class PostProcessorRegistrationDelegate {
/**
* 注册BPP
*/
public static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// AnnotationConfigUtils.registerAnnotationConfigProcessors()进行了注入internal类
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
/*
* 1. BPP计数
* 2. 为什么要+1呢?下面会添加一个BeanPostProcessorChecker
*/
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// 1. BeanPostProcessorChecker(用于记录信息) => BPP
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
// Spring内部的BPP
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
// implements PriorityOrdered
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
// implements Ordered
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
} else {
nonOrderedPostProcessorNames.add(ppName);
}
}
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
// 注册到BF.beanPostProcessors
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
// Next, register the BeanPostProcessors that implement Ordered.
// 注册所有实现Ordered的BPP
List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String ppName : orderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
orderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
sortPostProcessors(orderedPostProcessors, beanFactory);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
// Now, register all regular BeanPostProcessors.
List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String ppName : nonOrderedPostProcessorNames) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
nonOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
internalPostProcessors.add(pp);
}
}
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
// Finally, re-register all internal BeanPostProcessors.
sortPostProcessors(internalPostProcessors, beanFactory);
// implements MergedBeanDefinitionPostProcessor
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// Re-register => prepareBeanFactory()已经注册
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
}
// -------------------------------------------------------------------------------------------
/**
* 注册给定的BPP类型Bean对象
* <p>
* Register the given BeanPostProcessor beans.
*/
private static void registerBeanPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) {
for (BeanPostProcessor postProcessor : postProcessors) {
// 1. 应用于该工厂创建的Bean。在工厂配置期间调用
beanFactory.addBeanPostProcessor(postProcessor);
}
}
}
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
/**
* BeanPostProcessors to apply.
*/
private final List<BeanPostProcessor> beanPostProcessors = new CopyOnWriteArrayList<>();
@Override
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null");
// Remove from old position, if any
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) {
this.hasDestructionAwareBeanPostProcessors = true;
}
// 1. Add to end of list
this.beanPostProcessors.add(beanPostProcessor);
}
}
AbstractBeanFactory#addBeanPostProcessor()
// 已经进行个别bpp的添加
refresh() => prepareBeanFactory()
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
1. BPP类图
1. BeanPostProcessor
public interface BeanPostProcessor {
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
2. MergedBeanDefinitionPP
MergedBeanDefinitionPostProcessor
:合并子类和父类的BD。AbstractBeanFactory#getMergedBeanDefinition()
public interface MergedBeanDefinitionPostProcessor extends BeanPostProcessor {
/**
* Spring通过此方法找出所有需要注入的字段,同时做缓存
*/
void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName);
/**
* 用于在BeanDefinition被修改后,清除容器的缓存
*/
default void resetBeanDefinition(String beanName) {
}
}
3. DestructionAwareBPP
public interface DestructionAwareBeanPostProcessor extends BeanPostProcessor {
// 在bean被销毁前调用。`BeanFactory`的`lifecycle_interfaces`
void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException;
// 是否要进行销毁,一般情况下都需要
default boolean requiresDestruction(Object bean) {
return true;
}
}
4. InstantiationAwareBPP
public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
// 实例化前调用
@Nullable
default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
// 实例化后调用
default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
return true;
}
// 使用注解,完成属性的注入
@Nullable
default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName)
throws BeansException {
return null;
}
/**
* 属性注入后执行,在5.1版本被废弃
* @deprecated as of 5.1, in favor of {@link #postProcessProperties(PropertyValues, Object, String)}
*/
@Deprecated
@Nullable
default PropertyValues postProcessPropertyValues(
PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
return pvs;
}
}
5. SmartInstantiationAwareBPP
public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
@Nullable
default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
return null;
}
@Nullable
default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
throws BeansException {
return null;
}
default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
return bean;
}
}
2. BeanPostProcessorChecker
// BeanPostProcessorChecker(用于记录信息) => BPP
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
final class PostProcessorRegistrationDelegate {
private static final class BeanPostProcessorChecker implements BeanPostProcessor {
private static final Log logger = LogFactory.getLog(BeanPostProcessorChecker.class);
// 当前Bean工厂
private final ConfigurableListableBeanFactory beanFactory;
/*
* BD是否完全内部使用
* 1. ROLE_APPLICATION = 0(用户自定义bean)
* 2. ROLE_SUPPORT = 1(某些复杂的配置类)
* 3. ROLE_INFRASTRUCTURE = 2(Spring完全内部使用)
*/
private boolean isInfrastructureBean(@Nullable String beanName) {
if (beanName != null && this.beanFactory.containsBeanDefinition(beanName)) {
BeanDefinition bd = this.beanFactory.getBeanDefinition(beanName);
// bd的角色 == 内部使用
return (bd.getRole() == RootBeanDefinition.ROLE_INFRASTRUCTURE);
}
return false;
}
}
}
public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {
// 用户自定义bean
int ROLE_APPLICATION = 0;
// 某些复杂的配置类
int ROLE_SUPPORT = 1;
// Spring内部使用的bean
int ROLE_INFRASTRUCTURE = 2;
}
3. ApplicationListenerDetector
// Re-register post-processor for detecting inner beans as ApplicationListeners,
// moving it to the end of the processor chain (for picking up proxies etc).
// Re-register => prepareBeanFactory()已经注册
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
class ApplicationListenerDetector implements DestructionAwareBeanPostProcessor, MergedBeanDefinitionPostProcessor {
private final transient AbstractApplicationContext applicationContext;
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (bean instanceof ApplicationListener) {
// potentially not detected as a listener by getBeanNamesForType retrieval
Boolean flag = this.singletonNames.get(beanName);
if (Boolean.TRUE.equals(flag)) {
// singleton bean (top-level or inner): register on the fly
this.applicationContext.addApplicationListener((ApplicationListener<?>) bean);
}
// 非单例的,为嵌套的bean。日志,提示inner_bean只有在单例的情况下才能作为事件监听器
else if (Boolean.FALSE.equals(flag)) {
if (logger.isWarnEnabled() && !this.applicationContext.containsBean(beanName)) {
// inner bean with other scope - can't reliably process events
logger.warn("Inner bean '" + beanName + "' implements ApplicationListener interface " +
"but is not reachable for event multicasting by its containing ApplicationContext " +
"because it does not have singleton scope. Only top-level listener beans are allowed " +
"to be of non-singleton scope.");
}
this.singletonNames.remove(beanName);
}
}
return bean;
}
}
4. MyBPP
class T1_MyBPP {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x1_3_MyBPP.xml");
System.out.println("------------------- ac.over -------------------");
Ooxx ooxx = ac.getBean("ooxx", Ooxx.class);
System.out.println("ooxx = " + ooxx);
ac.close();
}
}
Ooxx()
MyBPP.postProcessBeforeInitialization()
MyBPP.postProcessAfterInitialization()
------------------- ac.over -------------------
ooxx = Ooxx{id=null, name='MyBPP ==>> 哈哈哈'}
<bean id="ooxx" class="com.listao.Ooxx"/>
<bean id="myBPP" class="com.listao.postProcessor.bpp.MyBPP"/>
public class MyBPP implements BeanPostProcessor, PriorityOrdered {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBPP.postProcessBeforeInitialization()");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("MyBPP.postProcessAfterInitialization()");
if (bean instanceof Ooxx) {
Ooxx ooxx = (Ooxx) bean;
ooxx.setName("MyBPP ==>> 哈哈哈");
return ooxx;
} else {
return bean;
}
}
@Override
public int getOrder() {
return 0;
}
}
7. initMessageSource()
// Initialize message source for this context.
/*
* 1. 国际化处理。为上下文初始化message源,即不同语言消息体
* 2. SpringMVC,国际化的代码重点讲
*/
initMessageSource();
- nginx官网 英文、俄语切换
- Spring MVC重点讲
public class DelegatingMessageSource extends MessageSourceSupport implements HierarchicalMessageSource {
}
/**
* 支持处理参数化、国际化的消息策略接口
*
* Strategy interface for resolving messages, with support for the parameterization
* and internationalization of such messages.
*/
public interface MessageSource {
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
// util包下的类。国际语言相关标识符
package java.util;
public final class Locale implements Cloneable, Serializable {
static public final Locale ENGLISH = createConstant("en", "");
static public final Locale CHINESE = createConstant("zh", "");
static public final Locale SIMPLIFIED_CHINESE = createConstant("zh", "CN");
static public final Locale TRADITIONAL_CHINESE = createConstant("zh", "TW");
static public final Locale UK = createConstant("en", "GB");
static public final Locale US = createConstant("en", "US");
}
8. initApplicationEventMulticaster()
SimpleApplicationEventMulticaster
默认多播器
// Initialize event multicaster for this context.
/*
* 1. 实例化前戏
* 2. init Multicaster(多路广播器),用于bean各阶段事件监听
*/
initApplicationEventMulticaster();
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
*
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// BF有自定义则采用,否则默认
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { // applicationEventMulticaster
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
} else {
// applicationEventMulticaster => SimpleApplicationEventMulticaster默认多播器
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
实际代码处理
- 提前准备好N多个事件
- 初始化多播器(创建多播器对象,此多播器对象中应该包含一个监听器的集合)
- 向多播器中注册监听器 10. registerListeners
- 准备事件发布,来通知多播器循环调用监听器进行相关的逻辑处理工作 12. finishRefresh
// 1. Event事件的子类
public abstract class ApplicationEvent extends EventObject {}
public class ContextRefreshedEvent extends ApplicationContextEvent {}
1. SimpleAppEventMulticaster
// 默认多播器(包含监听器集合)
public class SimpleApplicationEventMulticaster extends AbstractApplicationEventMulticaster {}
public abstract class AbstractApplicationEventMulticaster
implements ApplicationEventMulticaster, BeanClassLoaderAware, BeanFactoryAware {
// 监听器助手类,存放应用程序监听器集合。参数不是预过滤监听器
private final ListenerRetriever defaultRetriever = new ListenerRetriever(false);
private class ListenerRetriever {
// 1. 监听器集合
public final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>();
// 2. 监听器beanName集合
public final Set<String> applicationListenerBeans = new LinkedHashSet<>();
}
/**
* 3. 添加applicationListener
*/
@Override
public void addApplicationListener(ApplicationListener<?> listener) {
// ...
this.defaultRetriever.applicationListeners.add(listener);
}
}
@Override
public void addApplicationListenerBean(String listenerBeanName) {
//使用retrievalMutex加锁,保证线程安全
synchronized (this.retrievalMutex) {
// 将listenerBeanName添加到defaultRetriever的applicationListenerBeans
this.defaultRetriever.applicationListenerBeans.add(listenerBeanName);
// 清空缓存,因为listener可能支持缓存的某些事件类型和源类型,所以要刷新缓存
this.retrieverCache.clear();
}
}
}
2. Observer
- 被观察者:存储一个观察者的集合,执行不同方法时,调用观察者进行处理
- 观察者:看到被观察者不同行为,触发相应的反应
1. BadMan
public class BadMan implements Observable {
// 观察者集合
private final ArrayList<Observer> observers = new ArrayList<>();
@Override
public void addObserver(Observer observer) {
this.observers.add(observer);
}
@Override
public void delObserver(Observer observer) {
this.observers.remove(observer);
}
@Override
public void notifyObserver(String str) {
for (Observer ob : observers) {
ob.make(str);
}
}
public void run() {
System.out.println("罪犯要逃跑了");
this.notifyObserver("追击罪犯");
}
public void play() {
System.out.println("罪犯在玩");
this.notifyObserver("不动做任何事情,静观其变");
}
}
// ---------------------------------------------------------------
/**
* 被观察者
*/
interface Observable {
void addObserver(Observer observer);
void delObserver(Observer observer);
void notifyObserver(String str);
}
/**
* 观察者
*/
interface Observer {
void make(String str);
}
// ---------------------------------------------------------------
class GoodMan implements Observer {
@Override
public void make(String str) {
System.out.println("=> GoodMan开始行动");
System.out.println("=> " + str);
}
}
class GoodMan2 implements Observer {
@Override
public void make(String str) {
System.out.println("==> GoodMan2开始行动");
System.out.println("==> " + str);
}
}
// ---------------------------------------------------------------
class MyObserver {
public static void main(String[] args) {
// 被观察者
BadMan bm = new BadMan();
// 观察者
GoodMan gm = new GoodMan();
GoodMan2 gm2 = new GoodMan2();
// 被观察者添加观察者
bm.addObserver(gm);
bm.addObserver(gm2);
// 等待罪犯触发某些行为
bm.run();
}
}
2. JDK_BadMan
/**
* jdk自带的观察者
*/
public class JDK_BadMan extends Observable {
public void run(String str) {
System.out.println("JDK_BadMan.run()");
this.notifyObservers(str);
}
public static void main(String[] args) {
JDK_BadMan badMan = new JDK_BadMan();
JDK_GoodMan goodMan = new JDK_GoodMan();
badMan.addObserver(goodMan);
badMan.setChanged();
badMan.run("ooxx");
}
}
// ---------------------------------------------------------------
class JDK_GoodMan implements Observer {
@Override
public void update(Observable o, Object arg) {
System.out.println("=> JDK_GoodMan.update()");
System.out.println("=> arg = " + arg);
}
}
3. 事件驱动(解藕)
- 事件(自定义):具体要执行的动作
ApplicationEvent
=>ContextRefreshedEvent
- 监听器(观察者):可能多个,接受Event,验证匹配进行处理
ApplicationListener
=>ApplicationListenerMethodAdapter
- 多播器:注册已有的监听器,进行消息通知
- 事件源:调用、执行多播器发布具体的事件
执行过程
- 事件源来发布不同的事件
- 发布事件之后,调用多播器来进行事件广播,触发监听器
- 监听器接收到具体的事件,验证匹配与否,处理当前事件。如果匹配,直接处理;不匹配,跳过
4. MyObserver
public class MyCPXAC_3 extends ClassPathXmlApplicationContext {
public MyCPXAC_3(String... configLocations) {
super(configLocations);
}
@Override
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
System.out.println("扩展 ==> MyCPXAC_3.customizeBeanFactory()");
super.customizeBeanFactory(beanFactory);
// 3. 向Multicaster注册Listener
super.addApplicationListener(new MyListener());
}
}
public class T7_MyObserver {
public static void main(String[] args) {
MyCPXAC_3 ac = new MyCPXAC_3();
System.out.println("------------------- ac.over -------------------");
// 4. 事件源发布event
ac.publishEvent(new MyEvent("ooxx"));
ac.close();
}
}
1. MyEvent
/**
* 1. 事件
*/
public class MyEvent extends ApplicationEvent {
private static final long serialVersionUID = 7099057708183571966L;
public MyEvent(Object source) {
super(source);
System.out.println("MyEvent() => " + source);
}
}
2. MyListener
/**
* 2. 监听器
*/
public class MyListener implements ApplicationListener<ApplicationEvent> {
@Override
public void onApplicationEvent(ApplicationEvent event) {
// 可能被其他Event触发
System.out.println("============> MyListener.onApplicationEvent()");
if (event instanceof MyEvent) {
System.out.println("MyListener.onApplicationEvent() => " + event);
}
}
}
9. onRefresh()
// Initialize other special beans in specific context subclasses.
// 模板方法,后续拓展
onRefresh();
10. registerListeners()
/*
* 1. 实例化前戏
* 2. 注册监听器。bean中查找listener_bean,注册到消息广播器中
*/
registerListeners();
- 将
BF.ApplicationListeners
=> Multicaster - xml_Listener_bean => Multicaster
- 早期监听器集合 => Multicaster
- BF监听器导入 4. earlyApplicationEvents
/**
* EventMulticaster注册listener
* <p>
* 1. 将BF.ApplicationListeners => Multicaster
* 2. Listener_bean => Multicaster
* 3. 早期监听器集合 => Multicaster
* <p>
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// Register statically specified listeners first.
// 1. 将BF.ApplicationListeners => Multicaster
for (ApplicationListener<?> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let post-processors apply to them!
// 2. xml_Listener_bean => Multicaster
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
// 注册beanName
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// Publish early application events now that we finally have a multicaster...
/*
* 3. 早期监听器集合 => Multicaster
* prepareRefresh()
*/
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
/**
* Return the internal ApplicationEventMulticaster used by the context.
* @return the internal ApplicationEventMulticaster (never {@code null})
* @throws IllegalStateException if the context has not been initialized yet
*/
ApplicationEventMulticaster getApplicationEventMulticaster() throws IllegalStateException {
if (this.applicationEventMulticaster == null) {
throw new IllegalStateException("ApplicationEventMulticaster not initialized - " +
"call 'refresh' before multicasting events via the context: " + this);
}
return this.applicationEventMulticaster;
}
11. finishBFInitialization()
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
12. finishRefresh()
// Last step: publish corresponding event.
// 1. 生命周期处理器lifecycleProcessor初始化并onRefresh
// 2. 发布ContextRefreshEvent
finishRefresh();
protected void finishRefresh() {
// 1. Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 2. 默认DefaultLifecycleProcessor
initLifecycleProcessor();
// 3. Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// 4. Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
// 5. LiveBeansView: Spring用于支持JMX服务
LiveBeansView.registerApplicationContext(this);
}
1. initLifecycleProcessor()
/**
* 初始化 LifecycleProcessor。如果上下文中没有定义,则使用DefaultLifecycleProcessor
* <p>
* Initialize the LifecycleProcessor.
* Uses DefaultLifecycleProcessor if none defined in the context.
*
* @see org.springframework.context.support.DefaultLifecycleProcessor
*/
protected void initLifecycleProcessor() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 1. lifecycleProcessor => DefaultLifecycleProcessor
if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) {
this.lifecycleProcessor =
beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class);
if (logger.isTraceEnabled()) {
logger.trace("Using LifecycleProcessor [" + this.lifecycleProcessor + "]");
}
} else {
DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor();
defaultProcessor.setBeanFactory(beanFactory);
this.lifecycleProcessor = defaultProcessor;
beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor);
if (logger.isTraceEnabled()) {
logger.trace("No '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "' bean, using " +
"[" + this.lifecycleProcessor.getClass().getSimpleName() + "]");
}
}
}
13. resetCommonCaches()
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
resetCommonCaches();
protected void resetCommonCaches() {
ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
#1. <component-scan>
xmlns:context="http://www.springframework.org/schema/context"
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
<!-- 注解扫描。annotation-config="true" 默认值 -->
<context:component-scan annotation-config="true" base-package="com.listao.annotation.component"/>
http\://www.springframework.org/schema/context=org.springframework.context.config.ContextNamespaceHandler
public class ContextNamespaceHandler extends NamespaceHandlerSupport {
@Override
public void init() {
registerBeanDefinitionParser("property-placeholder", new PropertyPlaceholderBeanDefinitionParser());
registerBeanDefinitionParser("property-override", new PropertyOverrideBeanDefinitionParser());
registerBeanDefinitionParser("annotation-config", new AnnotationConfigBeanDefinitionParser());
// 1.
registerBeanDefinitionParser("component-scan", new ComponentScanBeanDefinitionParser());
registerBeanDefinitionParser("load-time-weaver", new LoadTimeWeaverBeanDefinitionParser());
registerBeanDefinitionParser("spring-configured", new SpringConfiguredBeanDefinitionParser());
registerBeanDefinitionParser("mbean-export", new MBeanExportBeanDefinitionParser());
registerBeanDefinitionParser("mbean-server", new MBeanServerBeanDefinitionParser());
}
}
1. BeanDefinition
- RootBeanDefinition:
internal对象
- ConfigurationClassBeanDefinition:
ConfigurationClass.beanMethods对象
- ConfigurationClassBeanDefinition:
- GenericBeanDefinition:
<bean>对象
- ScannedGenericBeanDefinition:
<component-scan>
扫描出的annotation对象
- AnnotatedGenericBeanDefinition:
ConfigurationClass.importedBy对象
- ScannedGenericBeanDefinition:
public class ScannedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
private final AnnotationMetadata metadata;
public ScannedGenericBeanDefinition(MetadataReader metadataReader) {
Assert.notNull(metadataReader, "MetadataReader must not be null");
this.metadata = metadataReader.getAnnotationMetadata();
setBeanClassName(this.metadata.getClassName());
setResource(metadataReader.getResource());
}
}
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
@Nullable
private volatile Object beanClass;
@Nullable
private Resource resource;
public void setBeanClass(@Nullable Class<?> beanClass) {
this.beanClass = beanClass;
}
public void setBeanClassName(@Nullable String beanClassName) {
this.beanClass = beanClassName;
}
public void setResource(@Nullable Resource resource) {
this.resource = resource;
}
}
2. ComponentScanBDParser
public class T6_ComponentScan {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x6_1_ComponentScan.xml");
System.out.println("------------------- ac.over -------------------");
ac.close();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 注解扫描。annotation-config="true" 默认值 -->
<context:component-scan annotation-config="true" base-package="com.listao.annotation.component"/>
</beans>
ComponentScanBeanDefinitionParser#parse()
public class ComponentScanBeanDefinitionParser implements BeanDefinitionParser {
/*
* <context:component-scan>处理
*/
@Override
@Nullable
public BeanDefinition parse(Element element, ParserContext parserContext) {
// 1. <context:component-scan>标签base-package属性
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
// 处理占位符
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
// base-package(允许通过`,;\t\n`中的任一符号填写多个)
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage,
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// 2.. Actually scan for bean definitions and register them.
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
// 3... ClassPathBeanDefinitionScanner 扫描basePackages包下的BD,并注册到IOC
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
/*
* 4. <component-scan>
* 组件注册(包括注册一些内部的注解后置处理器,触发注册事件)
* 1. internalConfigurationAnnotationProcessor => ConfigurationClassPostProcessor
* 2. internalAutowiredAnnotationProcessor => AutowiredAnnotationBeanPostProcessor
* 3. internalCommonAnnotationProcessor => CommonAnnotationBeanPostProcessor
* 4. internalEventListenerProcessor => EventListenerMethodProcessor
* 5. internalEventListenerFactory => DefaultEventListenerFactory
*/
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
// 解析use-default-filters属性,默认是true,用于指示是否使用默认的filter
boolean useDefaultFilters = true;
if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
useDefaultFilters = Boolean.parseBoolean(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
}
// Delegate bean definition registration to scanner class.
// 1.. 构建ClassPathBeanDefinitionScanner,将bean定义注册委托给scanner类
ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
scanner.setBeanDefinitionDefaults(parserContext.getDelegate().getBeanDefinitionDefaults());
scanner.setAutowireCandidatePatterns(parserContext.getDelegate().getAutowireCandidatePatterns());
// 解析resource-pattern属性
if (element.hasAttribute(RESOURCE_PATTERN_ATTRIBUTE)) {
scanner.setResourcePattern(element.getAttribute(RESOURCE_PATTERN_ATTRIBUTE));
}
try {
// 解析name-generator属性
parseBeanNameGenerator(element, scanner);
} catch (Exception ex) {
parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
}
try {
// 解析scope-resolver、scoped-proxy属性
parseScope(element, scanner);
} catch (Exception ex) {
parserContext.getReaderContext().error(ex.getMessage(), parserContext.extractSource(element), ex.getCause());
}
// 解析类型过滤器
parseTypeFilters(element, scanner, parserContext);
return scanner;
}
protected ClassPathBeanDefinitionScanner createScanner(XmlReaderContext readerContext, boolean useDefaultFilters) {
// 1.
return new ClassPathBeanDefinitionScanner(readerContext.getRegistry(), useDefaultFilters,
readerContext.getEnvironment(), readerContext.getResourceLoader());
}
}
1. registerComponents()
- internal类为Spring内部定义好的BFPP、BPP
AnnotationConfigUtils
AopConfigUtils
/*
* 解析<component-scan>
*/
protected void registerComponents(
XmlReaderContext readerContext, Set<BeanDefinitionHolder> beanDefinitions, Element element) {
Object source = readerContext.extractSource(element);
CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), source);
for (BeanDefinitionHolder beanDefHolder : beanDefinitions) {
compositeDef.addNestedComponent(new BeanComponentDefinition(beanDefHolder));
}
// Register annotation config processors, if necessary.
boolean annotationConfig = true;
// <context:component-scan annotation-config="true"> 默认为true
if (element.hasAttribute(ANNOTATION_CONFIG_ATTRIBUTE)) {
annotationConfig = Boolean.parseBoolean(element.getAttribute(ANNOTATION_CONFIG_ATTRIBUTE));
}
if (annotationConfig) {
Set<BeanDefinitionHolder> processorDefinitions =
/*
* 1. internalConfigurationAnnotationProcessor => ConfigurationClassPostProcessor
* 2. internalAutowiredAnnotationProcessor => AutowiredAnnotationBeanPostProcessor
* 3. internalCommonAnnotationProcessor => CommonAnnotationBeanPostProcessor
* 4. internalEventListenerProcessor => EventListenerMethodProcessor
* 5. internalEventListenerFactory => DefaultEventListenerFactory
*/
AnnotationConfigUtils.registerAnnotationConfigProcessors(readerContext.getRegistry(), source);
for (BeanDefinitionHolder processorDefinition : processorDefinitions) {
compositeDef.addNestedComponent(new BeanComponentDefinition(processorDefinition));
}
}
// 触发组件注册事件,默认实现为EmptyReaderEventListener
readerContext.fireComponentRegistered(compositeDef);
}
3. ClassPathBDScanner
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
this.registry = registry;
// 判断是否使用默认过滤器
if (useDefaultFilters) {
// 1... ClassPathScanningCandidateComponentProvider 注册默认的filter
registerDefaultFilters();
}
setEnvironment(environment);
// 2... ClassPathScanningCandidateComponentProvider 资源映射缓存
setResourceLoader(resourceLoader);
}
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
// 1... ClassPathScanningCandidateComponentProvider 扫描basePackage,将与@Component关联的BD
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
// 解析@Scope,包括scopeName、proxyMode
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
// 处理BD对象,eg:此bean是否可以自动装配到其他bean中
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 处理定义在目标类上的通用注解,包括@Lazy, @Primary, @DependsOn, @Role, @Description
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查beanName是否已经注册过,如果注册过,检查是否兼容
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
// 根据proxyMode的值,选择是否创建作用域代理
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 2.. 注册BD
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
// 1.
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
}
1. CPScanningCandidateCpntProvider
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
private final List<TypeFilter> includeFilters = new LinkedList<>();
static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
private MetadataReaderFactory metadataReaderFactory;
@Nullable
private Environment environment;
@Nullable
private ResourcePatternResolver resourcePatternResolver;
/**
* 注册默认过滤器,主要是@Component
* <p>
* Register the default filter for {@link Component @Component}.
* <p>This will implicitly register all annotations that have the
* {@link Component @Component} meta-annotation including the
* {@link Repository @Repository}, {@link Service @Service}, and
* {@link Controller @Controller} stereotype annotations.
* <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and
* JSR-330's {@link javax.inject.Named} annotations, if available.
*/
@SuppressWarnings("unchecked")
protected void registerDefaultFilters() {
// 1. @Component注解Filter => includeFilters
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
try {
// 添加@ManagedBean注解Filter到includeFilters中
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
} catch (ClassNotFoundException ex) {
// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
}
try {
// 添加@Named注解filter到includeFilters中
this.includeFilters.add(new AnnotationTypeFilter(
((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
} catch (ClassNotFoundException ex) {
// JSR-330 API not available - simply skip.
}
}
/**
* 创建了ResourcePatternResolver,用来解析URL资源,
* <p>
* Set the {@link ResourceLoader} to use for resource locations.
* This will typically be a {@link ResourcePatternResolver} implementation.
* <p>Default is a {@code PathMatchingResourcePatternResolver}, also capable of
* resource pattern resolving through the {@code ResourcePatternResolver} interface.
*
* @see org.springframework.core.io.support.ResourcePatternResolver
* @see org.springframework.core.io.support.PathMatchingResourcePatternResolver
*/
@Override
public void setResourceLoader(@Nullable ResourceLoader resourceLoader) {
// 1. resourcePatternResolver == ClassPathXmlApplicationContext
this.resourcePatternResolver = ResourcePatternUtils.getResourcePatternResolver(resourceLoader);
// 2. 进行字节码文件metadata缓存
// resourceLoader <= ClassPathXmlApplicationContext
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
// 创建CandidateComponentsIndexLoader,spring内部定义的组件,读取META-INF/spring.components下的信息
this.componentsIndex = CandidateComponentsIndexLoader.loadIndex(this.resourcePatternResolver.getClassLoader());
}
// ------------------------------------------------------------------------------------------
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
} else {
// 1..
return scanCandidateComponents(basePackage);
}
}
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
// 1... PathMatchingResourcePatternResolver AC查询packageSearchPath路径下所有.class => Resource[]
// getResourcePatternResolver() => AC.resourcePatternResolver == PathMatchingResourcePatternResolver
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
// 2... CachingMetadataReaderFactory AC加载.class文件 => SimpleMetadataReader
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
// 3.. metaData校验是否和@Component关联
if (isCandidateComponent(metadataReader)) {
// 4. MetadataReader => ScannedGenericBeanDefinition
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
} else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
} else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
} else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
private ResourcePatternResolver getResourcePatternResolver() {
if (this.resourcePatternResolver == null) {
this.resourcePatternResolver = new PathMatchingResourcePatternResolver();
}
// 1. 构造方法设置
return this.resourcePatternResolver;
}
/**
* Return the MetadataReaderFactory used by this component provider.
*/
public final MetadataReaderFactory getMetadataReaderFactory() {
if (this.metadataReaderFactory == null) {
this.metadataReaderFactory = new CachingMetadataReaderFactory();
}
return this.metadataReaderFactory;
}
}
1. registerDefaultFilters()
ClassPathScanningCandidateComponentProvider#registerDefaultFilters()
2. CachingMetadataReaderFactory
ClassPathScanningCandidateComponentProvider#setResourceLoader()
ClassPathScanningCandidateComponentProvider.metadataReaderFactory
=> CachingMetadataReaderFactoryCachingMetadataReaderFactory.metadataReaderCache
<=>DefaultResourceLoader.resourceCaches.get(MetadataReader.class)
- <=>
ClassPathXmlApplicationContext.resourceCaches.get(MetadataReader.class)
public class CachingMetadataReaderFactory extends SimpleMetadataReaderFactory {
private Map<Resource, MetadataReader> metadataReaderCache;
public CachingMetadataReaderFactory(@Nullable ResourceLoader resourceLoader) {
super(resourceLoader);
if (resourceLoader instanceof DefaultResourceLoader) {
// 1. ClassPathXmlApplicationContext
this.metadataReaderCache =
((DefaultResourceLoader) resourceLoader).getResourceCache(MetadataReader.class);
} else {
setCacheLimit(DEFAULT_CACHE_LIMIT);
}
}
// ----------------------------------------------------------------------------------
@Override
public MetadataReader getMetadataReader(Resource resource) throws IOException {
if (this.metadataReaderCache instanceof ConcurrentMap) {
// No synchronization necessary...
MetadataReader metadataReader = this.metadataReaderCache.get(resource);
if (metadataReader == null) {
// 1... SimpleMetadataReaderFactory => SimpleMetadataReader
metadataReader = super.getMetadataReader(resource);
this.metadataReaderCache.put(resource, metadataReader);
}
return metadataReader;
} else if (this.metadataReaderCache != null) {
synchronized (this.metadataReaderCache) {
MetadataReader metadataReader = this.metadataReaderCache.get(resource);
if (metadataReader == null) {
metadataReader = super.getMetadataReader(resource);
this.metadataReaderCache.put(resource, metadataReader);
}
return metadataReader;
}
} else {
return super.getMetadataReader(resource);
}
}
}
3. DefaultResourceLoader
// ClassPathXmlApplicationContext的父类
public class DefaultResourceLoader implements ResourceLoader {
// 资源映射缓存
private final Map<Class<?>, Map<Resource, ?>> resourceCaches = new ConcurrentHashMap<>(4);
public <T> Map<Resource, T> getResourceCache(Class<T> valueType) {
return (Map<Resource, T>) this.resourceCaches.computeIfAbsent(valueType, key -> new ConcurrentHashMap<>());
}
}
3.2. doScan()
1. PathMatchingResourcePatternRsv
- basePackage => Resource[]
PathMatchingResourcePatternResolver#findPathMatchingResources()
2. SimpleMetadataReaderFactory
- Resource => MetadataReader(SimpleMetadataReader)
- 2. CachingMetadataReaderFactory
// 2. AC加载.class文件 => SimpleMetadataReader
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
public class SimpleMetadataReaderFactory implements MetadataReaderFactory {
private final ResourceLoader resourceLoader;
/**
* Create a new SimpleMetadataReaderFactory for the given resource loader.
* @param resourceLoader the Spring ResourceLoader to use
* (also determines the ClassLoader to use)
*/
public SimpleMetadataReaderFactory(@Nullable ResourceLoader resourceLoader) {
this.resourceLoader = (resourceLoader != null ? resourceLoader : new DefaultResourceLoader());
}
@Override
public MetadataReader getMetadataReader(Resource resource) throws IOException {
// 1.
return new SimpleMetadataReader(resource, this.resourceLoader.getClassLoader());
}
@Override
public MetadataReader getMetadataReader(String className) throws IOException {
try {
String resourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(className) + ClassUtils.CLASS_FILE_SUFFIX;
Resource resource = this.resourceLoader.getResource(resourcePath);
// 1..
return getMetadataReader(resource);
}
catch (FileNotFoundException ex) {
// Maybe an inner class name using the dot name syntax? Need to use the dollar syntax here...
// ClassUtils.forName has an equivalent check for resolution into Class references later on.
int lastDotIndex = className.lastIndexOf('.');
if (lastDotIndex != -1) {
String innerClassName =
className.substring(0, lastDotIndex) + '$' + className.substring(lastDotIndex + 1);
String innerClassResourcePath = ResourceLoader.CLASSPATH_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(innerClassName) + ClassUtils.CLASS_FILE_SUFFIX;
Resource innerClassResource = this.resourceLoader.getResource(innerClassResourcePath);
if (innerClassResource.exists()) {
return getMetadataReader(innerClassResource);
}
}
throw ex;
}
}
}
1. getDeclaredAnnotations()
java.lang.Class#getDeclaredAnnotations()
AnnotationsScanner#getDeclaredAnnotations()
2. SimpleMetadataReader
- 2. CachingMetadataReaderFactory =>
(Resource, MetadataReader)
缓存
CachingMetadataReaderFactory#getMetadataReader()
@Configuration
@Order(2)
public class CConfiguration {
@Bean
public void bean() {
}
}
- 得到一个类对应的
SimpleMetadataReader
的具体包含
ClassPathScanningCandidateComponentProvider#scanCandidateComponents()
final class SimpleMetadataReader implements MetadataReader {
private final Resource resource;
// 1... SimpleAnnotationMetadata
private final AnnotationMetadata annotationMetadata;
}
1. SimpleAnnotationMetadata
final class SimpleAnnotationMetadata implements AnnotationMetadata {
// 1. SimpleMethodMetadata
private final MethodMetadata[] annotatedMethods;
// 2. MergedAnnotationsCollection
private final MergedAnnotations annotations;
private Set<String> annotationTypes;
@Override
public MergedAnnotations getAnnotations() {
return this.annotations;
}
@Override
public Set<MethodMetadata> getAnnotatedMethods(String annotationName) {
Set<MethodMetadata> annotatedMethods = null;
for (MethodMetadata annotatedMethod : this.annotatedMethods) {
// 1... AnnotatedTypeMetadata
if (annotatedMethod.isAnnotated(annotationName)) {
if (annotatedMethods == null) {
annotatedMethods = new LinkedHashSet<>(4);
}
annotatedMethods.add(annotatedMethod);
}
}
return annotatedMethods != null ? annotatedMethods : Collections.emptySet();
}
}
public interface AnnotationMetadata extends ClassMetadata, AnnotatedTypeMetadata {
@Nullable
default Map<String, Object> getAnnotationAttributes(String annotationName) {
// 1..
return getAnnotationAttributes(annotationName, false);
}
@Nullable
default Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
// 1... SimpleAnnotationMetadata
MergedAnnotation<Annotation> annotation = getAnnotations().get(annotationName,
null, MergedAnnotationSelectors.firstDirectlyDeclared());
// 2.
if (!annotation.isPresent()) {
return null;
}
return annotation.asAnnotationAttributes(Adapt.values(classValuesAsString, true));
}
// ----------------------------------------------------------------------------------------
default boolean hasAnnotatedMethods(String annotationName) {
// 1... SimpleAnnotationMetadata
return !getAnnotatedMethods(annotationName).isEmpty();
}
default boolean hasMetaAnnotation(String metaAnnotationName) {
// MergedAnnotationsCollection
return getAnnotations().get(metaAnnotationName,
MergedAnnotation::isMetaPresent).isPresent();
}
default boolean hasAnnotation(String annotationName) {
return getAnnotations().isDirectlyPresent(annotationName);
}
}
public interface AnnotatedTypeMetadata {
MergedAnnotations getAnnotations();
default boolean isAnnotated(String annotationName) {
// 1... MergedAnnotationsCollection
return getAnnotations().isPresent(annotationName);
}
}
2. SimpleMethodMetadata
final class SimpleMethodMetadata implements MethodMetadata {
private final String methodName;
private final int access;
private final String declaringClassName;
private final String returnTypeName;
// MergedAnnotationsCollection
private final MergedAnnotations annotations;
}
3. MergedAnnotationsCollection
基本注解封装对象
final class MergedAnnotationsCollection implements MergedAnnotations {
// 1. TypeMappedAnnotation
private final MergedAnnotation<?>[] annotations;
// 2. AnnotationTypeMappings#createMappings()
private final AnnotationTypeMappings[] mappings;
@Override
public boolean isPresent(String annotationType) {
// 1..
return isPresent(annotationType, false);
}
@Override
public boolean isDirectlyPresent(String annotationType) {
return isPresent(annotationType, true);
}
/**
* anno类型匹配。requiredType先在annotations集合匹配,再在mappings集合匹配
*/
private boolean isPresent(Object requiredType, boolean directOnly) {
for (MergedAnnotation<?> annotation : this.annotations) {
// 1... TypeMappedAnnotation
Class<? extends Annotation> type = annotation.getType();
if (type == requiredType || type.getName().equals(requiredType)) {
return true;
}
}
if (!directOnly) {
for (AnnotationTypeMappings mappings : this.mappings) {
for (int i = 1; i < mappings.size(); i++) {
AnnotationTypeMapping mapping = mappings.get(i);
// 2..
if (isMappingForType(mapping, requiredType)) {
return true;
}
}
}
}
return false;
}
// ----------------------------------------------------------------------------------------
private static boolean isMappingForType(AnnotationTypeMapping mapping, @Nullable Object requiredType) {
if (requiredType == null) {
return true;
}
// 1... AnnotationTypeMapping
Class<? extends Annotation> actualType = mapping.getAnnotationType();
return (actualType == requiredType || actualType.getName().equals(requiredType));
}
// ----------------------------------------------------------------------------------------
@Override
public <A extends Annotation> MergedAnnotation<A> get(Class<A> annotationType,
@Nullable Predicate<? super MergedAnnotation<A>> predicate,
@Nullable MergedAnnotationSelector<A> selector) {
// 1..
MergedAnnotation<A> result = find(annotationType, predicate, selector);
return (result != null ? result : MergedAnnotation.missing());
}
@Nullable
private <A extends Annotation> MergedAnnotation<A> find(Object requiredType,
@Nullable Predicate<? super MergedAnnotation<A>> predicate,
@Nullable MergedAnnotationSelector<A> selector) {
if (selector == null) {
selector = MergedAnnotationSelectors.nearest();
}
MergedAnnotation<A> result = null;
for (int i = 0; i < this.annotations.length; i++) {
MergedAnnotation<?> root = this.annotations[i];
AnnotationTypeMappings mappings = this.mappings[i];
for (int mappingIndex = 0; mappingIndex < mappings.size(); mappingIndex++) {
AnnotationTypeMapping mapping = mappings.get(mappingIndex);
// 1.. 类型匹配
if (!isMappingForType(mapping, requiredType)) {
continue;
}
MergedAnnotation<A> candidate = (mappingIndex == 0 ? (MergedAnnotation<A>) root :
TypeMappedAnnotation.createIfPossible(mapping, root, IntrospectionFailureLogger.INFO));
if (candidate != null && (predicate == null || predicate.test(candidate))) {
if (selector.isBestCandidate(candidate)) {
return candidate;
}
result = (result != null ? selector.select(result, candidate) : candidate);
}
}
}
return result;
}
}
4. TypeMappedAnnotation
MergedAnnotationsCollection.annotations
// AbstractMergedAnnotation<A extends Annotation> implements MergedAnnotation<A>
final class TypeMappedAnnotation<A extends Annotation> extends AbstractMergedAnnotation<A> {
private final AnnotationTypeMapping mapping;
private final ClassLoader classLoader;
private final Object rootAttributes;
public Class<A> getType() {
// 1... AnnotationTypeMapping
return (Class<A>) this.mapping.getAnnotationType();
}
@Override
public boolean isPresent() {
return true;
}
}
5. AnnotationTypeMapping
final class AnnotationTypeMapping {
private final AnnotationTypeMapping source;
// 99. 最后都和annotationType比较
private final Class<? extends Annotation> annotationType;
Class<? extends Annotation> getAnnotationType() {
// 1.
return this.annotationType;
}
}
6. AnnotationTypeMappings
MergedAnnotationsCollection.mappings
final class AnnotationTypeMappings {
private final List<AnnotationTypeMapping> mappings;
AnnotationTypeMapping get(int index) {
return this.mappings.get(index);
}
}
3. isCandidateComponent()
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
// `AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter`
for (TypeFilter tf : this.includeFilters) {
// 1... AbstractTypeHierarchyTraversingFilter => @Component匹配
if (tf.match(metadataReader, getMetadataReaderFactory())) {
// @Condition匹配
return isConditionMatch(metadataReader);
}
}
return false;
}
}
1. AnnotationTypeFilter
public class AnnotationTypeFilter extends AbstractTypeHierarchyTraversingFilter {
private final Class<? extends Annotation> annotationType; // Component
public AnnotationTypeFilter(Class<? extends Annotation> annotationType) {
this(annotationType, true, false);
}
public AnnotationTypeFilter(
Class<? extends Annotation> annotationType, boolean considerMetaAnnotations, boolean considerInterfaces) {
super(annotationType.isAnnotationPresent(Inherited.class), considerInterfaces);
this.annotationType = annotationType;
this.considerMetaAnnotations = considerMetaAnnotations;
}
@Override
protected boolean matchSelf(MetadataReader metadataReader) {
// SimpleAnnotationMetadata
AnnotationMetadata metadata = metadataReader.getAnnotationMetadata();
// 1.
return metadata.hasAnnotation(this.annotationType.getName()) ||
(this.considerMetaAnnotations && metadata.hasMetaAnnotation(this.annotationType.getName()));
}
}
1. AbsTypeHierarchyTraversingFilter
public abstract class AbstractTypeHierarchyTraversingFilter implements TypeFilter {
@Override
public boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
throws IOException {
// This method optimizes avoiding unnecessary creation of ClassReaders
// as well as visiting over those readers.
// 1... AnnotationTypeFilter
if (matchSelf(metadataReader)) {
return true;
}
ClassMetadata metadata = metadataReader.getClassMetadata();
if (matchClassName(metadata.getClassName())) {
return true;
}
if (this.considerInherited) {
String superClassName = metadata.getSuperClassName();
if (superClassName != null) {
// Optimization to avoid creating ClassReader for super class.
Boolean superClassMatch = matchSuperClass(superClassName);
if (superClassMatch != null) {
if (superClassMatch.booleanValue()) {
return true;
}
}
else {
// Need to read super class to determine a match...
try {
if (match(metadata.getSuperClassName(), metadataReaderFactory)) {
return true;
}
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not read super class [" + metadata.getSuperClassName() +
"] of type-filtered class [" + metadata.getClassName() + "]");
}
}
}
}
}
if (this.considerInterfaces) {
for (String ifc : metadata.getInterfaceNames()) {
// Optimization to avoid creating ClassReader for super class
Boolean interfaceMatch = matchInterface(ifc);
if (interfaceMatch != null) {
if (interfaceMatch.booleanValue()) {
return true;
}
}
else {
// Need to read interface to determine a match...
try {
if (match(ifc, metadataReaderFactory)) {
return true;
}
}
catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not read interface [" + ifc + "] for type-filtered class [" +
metadata.getClassName() + "]");
}
}
}
}
}
return false;
}
}
2. isPresent()
MergedAnnotationsCollection#isPresent()
3. isMappingForType()
.class
上注解的MetadataReader.mappings
与@Component
校验
MergedAnnotationsCollection#isMappingForType()
4. ScannedGenericBD
// 4. MetadataReader => ScannedGenericBeanDefinition
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
#2. ConfigurationClassPP
class T6_ConfigClassParser {
public static void main(String[] args) {
ClassPathXmlApplicationContext ac = new ClassPathXmlApplicationContext("x6_2_ConfigClassParser.xml");
System.out.println("------------------- ac.over -------------------");
MyPropertySources myPropertySources = ac.getBean(MyPropertySources.class);
ac.close();
}
}
<bean id="configClassPP" class="org.springframework.context.annotation.ConfigurationClassPostProcessor"/>
<bean id="myShouldSkip" class="com.listao.annotation.configClassParser.shouldSkip.MyShouldSkip"/>
<bean id="myComponent" class="com.listao.annotation.configClassParser.MyComponent"/>
<bean id="myPropertySources" class="com.listao.annotation.configClassParser.MyPropertySources"/>
<bean id="myComponentScan" class="com.listao.annotation.configClassParser.MyComponentScan"/>
<bean id="myImpt" class="com.listao.annotation.configClassParser.impt.MyImpt"/>
<bean id="myImportResource" class="com.listao.annotation.configClassParser.MyImportResource"/>
<bean id="myBean" class="com.listao.annotation.configClassParser.bean.MyBean"/>
<!-- 接口@Bean -->
<bean id="iConfig" class="com.listao.annotation.configClassParser.bean.BeanImpl"/>
<!-- superClass -->
<bean id="child" class="com.listao.annotation.configClassParser.superClass.ChildClass"/>
- 纯注解的AC
AnnotationConfigApplicationContext
- 解析
@Component
类中包含的其他注解 ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor
postProcessBeanDefinitionRegistry() => processConfigBeanDefinitions()
1. initializeBean()
- 2. CachingMetadataReaderFactory
ConfigurationClassPostProcessor.metadataReaderFactory
=> CachingMetadataReaderFactoryCachingMetadataReaderFactory.metadataReaderCache
<=>DefaultResourceLoader.resourceCaches.get(MetadataReader.class)
- <=>
ClassPathXmlApplicationContext.resourceCaches.get(MetadataReader.class)
ConfigurationClassPostProcessor#setResourceLoader()
2. invokeBFPP()
Environment
属性注入CachingMetadataReaderFactory
注入
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
private Environment environment;
private ResourceLoader resourceLoader = new DefaultResourceLoader();
private boolean setMetadataReaderFactoryCalled = false;
private MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory();
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, "ResourceLoader must not be null");
this.resourceLoader = resourceLoader;
if (!this.setMetadataReaderFactoryCalled) {
// 1. initializeBean()
this.metadataReaderFactory = new CachingMetadataReaderFactory(resourceLoader);
}
}
// 执行BDRPP
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
// registry生成hashCode,只操作一次,如果之前处理过则抛出异常
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
// 1.. 处理config_BD
processConfigBeanDefinitions(registry);
}
/**
* 1. 构建和验证一个类是否被@Configuration修饰,并做相关的解析工作
* 2. SpringBoot的自动装配原理
* 3. @Configuration, @Bean, @Import, @Component, @ComponentScan, @ComponentScans
* <p>
* Build and validate a configuration model based on the registry of
* {@link Configuration} classes.
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
// config_BD
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
// 筛选configClass
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
// configClass属性为空,意味着已经处理过,输出日志
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
/*
* 1. this.metadataReaderFactory缓存了.class的metadata信息
* ------------------------------------------------
* 1. @Configuration && (proxyBeanMethods == false) => (configurationClass = full)
* 2. @Configuration || (@Component, @ComponentScan, @Import, @ImportResource, @Bean) => (configurationClass = lite)
* 3. @Order => (order = int)
*/
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// Return immediately if no @Configuration classes were found
if (configCandidates.isEmpty()) {
return;
}
// Sort by previously determined @Order value, if applicable
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
/*
* 2. BeanNameGenerator接口
* ------------------------------------------------
* 1. DefaultBeanNameGenerator
* 2. FullyQualifiedAnnotationBeanNameGenerator
* 3. AnnotationBeanNameGenerator
*/
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
// 自定义BeanNameGenerator
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR); // internalConfigurationBeanNameGenerator
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
// environment处理
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
// 3. @Controller, @Import, @ImportResource, @ComponentScan, @ComponentScans, @Bean
parser.parse(candidates);
/*
* 解析完的ConfigClass进行校验
* 1. ConfigClass不能是final
* 2. @Bean修饰的方法必须可以重写以支持CGLIB
*/
parser.validate();
/*
* 获取所有的bean
* 1. 扫描的bean
* 2. @Import导入的bean
*/
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
// 清除已经解析处理过的ConfigClass
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 4. 核心方法,将新ConfigClass_BD => IOC
this.reader.loadBeanDefinitions(configClasses);
// 添加到已经处理的集合中
alreadyParsed.addAll(configClasses);
candidates.clear();
/*
* 1. reader.loadBeanDefinitions(configClasses)有没有向BeanDefinitionMap中添加新的BD
* 2. 实际上就是看配置类(eg: AppConfig类会向BeanDefinitionMap中添加bean)
* 3. 再次遍历BD,并判断这些bean是否已经被解析过了,如果未解析,需要重新进行解析
*/
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
// 如果有未解析的类,添加到candidates中,进入下一次while循环
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
}
1. ConfigurationClassUtils
- 获取
SimpleMetadataReader
@Configuration
处理(configurationClass = full)isConfigurationCandidate()
(configurationClass = lite)
- 2. SimpleMetadataReaderFactory
ConfigurationClass
接口必须被修饰:@Configuration
@Component, @ComponentScan, @Import, @ImportResource
@Bean
abstract class ConfigurationClassUtils {
static {
candidateIndicators.add(Component.class.getName());
candidateIndicators.add(ComponentScan.class.getName());
candidateIndicators.add(Import.class.getName());
candidateIndicators.add(ImportResource.class.getName());
}
// 定义set集合,用于存储标注配置类的注解
private static final Set<String> candidateIndicators = new HashSet<>(8);
public static boolean checkConfigurationClassCandidate(
BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) {
// bean完全限定名
String className = beanDef.getBeanClassName();
if (className == null || beanDef.getFactoryMethodName() != null) {
return false;
}
// -----------------------------------------------------------------------------------------------
// 1. BD分类,获取AnnotationMetadata(注解也有属性值)
// -----------------------------------------------------------------------------------------------
AnnotationMetadata metadata;
// 1.1. ScannedGenericBeanDefinition:`annotation对象`,BD内封装了metadata
if (beanDef instanceof AnnotatedBeanDefinition &&
className.equals(((AnnotatedBeanDefinition) beanDef).getMetadata().getClassName())) {
// Can reuse the pre-parsed metadata from the given BeanDefinition...
metadata = ((AnnotatedBeanDefinition) beanDef).getMetadata();
}
// 1.2. RootBeanDefinition:`internal对象`
else if (beanDef instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) beanDef).hasBeanClass()) {
// Check already loaded Class if present...
// since we possibly can't even load the class file for this Class.
Class<?> beanClass = ((AbstractBeanDefinition) beanDef).getBeanClass();
// 排除beanClass为下列(类的子类 || 接口的实现类)
if (BeanFactoryPostProcessor.class.isAssignableFrom(beanClass) ||
BeanPostProcessor.class.isAssignableFrom(beanClass) ||
AopInfrastructureBean.class.isAssignableFrom(beanClass) ||
EventListenerFactory.class.isAssignableFrom(beanClass)) {
return false;
}
// 给定类创建新的AnnotationMetadata实例
metadata = AnnotationMetadata.introspect(beanClass);
}
// 1.3. GenericBeanDefinition:`<bean>对象`
else {
try {
// 1.4. SimpleMetadataReader
MetadataReader metadataReader = metadataReaderFactory.getMetadataReader(className);
// 完整注解元数据,包括带注解方法的元数据。SimpleAnnotationMetadata
metadata = metadataReader.getAnnotationMetadata();
} catch (IOException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Could not find class file for introspecting configuration annotations: " +
className, ex);
}
return false;
}
}
// -----------------------------------------------------------------------------------------------
// @Configuration => @Component, @ComponentScan, @Import, @ImportResource => @Bean
// -----------------------------------------------------------------------------------------------
// 2... SimpleAnnotationMetadata <= @Configuration(优先级最高)
Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName());
// proxyBeanMethods == false(使用代理模式),configurationClass = full
if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL);
}
// 3.. @Component, @ComponentScan, @Import, @ImportResource => @Bean
// configurationClass = lite
else if (config != null || isConfigurationCandidate(metadata)) {
beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE);
} else {
return false;
}
// 4.. It's a full or lite configuration candidate... Let's determine the order value, if any.
Integer order = getOrder(metadata);
if (order != null) {
beanDef.setAttribute(ORDER_ATTRIBUTE, order); // order = int
}
return true;
}
// ----------------------------------------------------------------------------------------
/**
* 1. 非接口
* 2. @Component, @ComponentScan, @Import, @ImportResource
* 3. @Bean
* <p>
* Check the given metadata for a configuration class candidate
* (or nested component class declared within a configuration/component class).
*
* @param metadata the metadata of the annotated class
* @return {@code true} if the given class is to be registered for
* configuration class processing; {@code false} otherwise
*/
public static boolean isConfigurationCandidate(AnnotationMetadata metadata) {
// Do not consider an interface or an annotation...
// 1. 不考虑接口
if (metadata.isInterface()) {
return false;
}
// Any of the typical annotations found?
// 2. @Component, @ComponentScan, @Import, @ImportResource修饰
for (String indicator : candidateIndicators) {
if (metadata.isAnnotated(indicator)) {
return true;
}
}
// Finally, let's look for @Bean methods...
try {
// 3. @Bean修饰
return metadata.hasAnnotatedMethods(Bean.class.getName());
} catch (Throwable ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to introspect @Bean methods on class [" + metadata.getClassName() + "]: " + ex);
}
return false;
}
}
// ----------------------------------------------------------------------------------------
@Nullable
public static Integer getOrder(AnnotationMetadata metadata) {
// 1.
Map<String, Object> orderAttributes = metadata.getAnnotationAttributes(Order.class.getName());
return (orderAttributes != null ? ((Integer) orderAttributes.get(AnnotationUtils.VALUE)) : null);
}
}
2. BeanNameGenerator
- 类名
#0, #1
#2.1. ConfigurationClassParser
// Parse each @Configuration class
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
// 3. @Controller, @Import, @ImportResource, @ComponentScan, @ComponentScans, @Bean
parser.parse(candidates);
class ConfigurationClassParser {
private final ConditionEvaluator conditionEvaluator;
/**
* Create a new {@link ConfigurationClassParser} instance that will be used
* to populate the set of configuration classes.
*/
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader,
BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry) {
this.metadataReaderFactory = metadataReaderFactory;
this.problemReporter = problemReporter;
this.environment = environment;
this.resourceLoader = resourceLoader;
this.registry = registry;
this.componentScanParser = new ComponentScanAnnotationParser(
environment, resourceLoader, componentScanBeanNameGenerator, registry);
// 1.
this.conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);
}
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
// 1.. ScannedGenericBeanDefinition => annotation对象
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
// 2.. RootBeanDefinition => internal对象
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
// 3.. GenericBeanDefinition => <bean>对象
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
} catch (BeanDefinitionStoreException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
/* 4...
* 执行找到的DeferredImportSelector
* DeferredImportSelector是ImportSelector的一个子类
* ImportSelector被设计成和@Import注解同样的效果,但是实现了ImportSelector的类可以条件性的决定导入某些配置
* DeferredImportSelector的设计都是在所有其他的配置类被处理后才进行处理
*/
this.deferredImportSelectorHandler.process();
}
// ------------------------------------------------------------------------------------------------
// 根据注解元数据和beanName解析配置文件,有注解元数据
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
// 1..
processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER);
}
// 根据Class和beanName解析配置文件,有Class对象
protected final void parse(Class<?> clazz, String beanName) throws IOException {
// 1..
processConfigurationClass(new ConfigurationClass(clazz, beanName), DEFAULT_EXCLUSION_FILTER);
}
// 根据className和beanName解析配置文件,读取元数据
protected final void parse(@Nullable String className, String beanName) throws IOException {
Assert.notNull(className, "No bean class name for configuration class bean definition");
MetadataReader reader = this.metadataReaderFactory.getMetadataReader(className);
// 1..
processConfigurationClass(new ConfigurationClass(reader, beanName), DEFAULT_EXCLUSION_FILTER);
}
// ------------------------------------------------------------------------------------------------
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException {
// 1... ConditionEvaluator @Conditional({WindowsCondition.class}) 条件注解
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
// 2. ConfigClass重复Imported处理
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
// ConfigClass被处理两次,都属于被import的。合并导入类
if (configClass.isImported()) {
if (existingClass.isImported()) {
// 合并两者的importBy属性
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
// ConfigClass不是被导入的,移除旧的使用新的配置类
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// Recursively process the configuration class and its superclass hierarchy.
/*
* 0. 不懂直接路过,不影响源码阅读
* 1. ConfigClass可能存在父类(若父类的全类名是以java开头的,eg:java.lang.Object)
* 需要将ConfigClass变成SourceClass解析,返回SourceClass的父类
* 2. 父类为空,则不会进行while循环去解析;如果父类不为空,则会循环的去解析父类
* 3. SourceClass意义: 包装类,以统一的方式去处理带有注解的类,不管这些类是如何加载的
*/
SourceClass sourceClass = asSourceClass(configClass, filter);
do {
// 3. 核心:解析注解
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 4. ConfigClass全部加入configurationClasses_map
this.configurationClasses.put(configClass, configClass);
}
}
1. ConfigurationClass
final class ConfigurationClass {
// 配置类的注解元数据
private final AnnotationMetadata metadata;
// 配置类的资源对象
private final Resource resource;
// bean名称
@Nullable
private String beanName;
// 普通类的Bean方法对象
private final Set<BeanMethod> beanMethods = new LinkedHashSet<>();
// @Component的InnerClass, @Import修饰的类,
// 包括ImportSelector选择器类中引入的候选类、DeferredImportSelector选择器中引入的候选类
private final Set<ConfigurationClass> importedBy = new LinkedHashSet<>(1);
public ConfigurationClass(MetadataReader metadataReader, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = metadataReader.getAnnotationMetadata();
this.resource = metadataReader.getResource();
this.beanName = beanName;
}
public ConfigurationClass(Class<?> clazz, String beanName) {
Assert.notNull(beanName, "Bean name must not be null");
this.metadata = AnnotationMetadata.introspect(clazz);
this.resource = new DescriptiveResource(clazz.getName());
this.beanName = beanName;
}
public ConfigurationClass(MetadataReader metadataReader, @Nullable ConfigurationClass importedBy) {
this.metadata = metadataReader.getAnnotationMetadata();
this.resource = metadataReader.getResource();
this.importedBy.add(importedBy);
}
}
2. ConditionEvaluator
class ConditionEvaluator {
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
// 1. metadata为空 || 不存在@Conditional
if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
return false;
}
if (phase == null) {
if (metadata instanceof AnnotationMetadata &&
ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION); // parse_configuration
}
return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN); // register_bean
}
List<Condition> conditions = new ArrayList<>();
// 2..
for (String[] conditionClasses : getConditionClasses(metadata)) {
for (String conditionClass : conditionClasses) {
// 3.. 反射@Conditional的value类
Condition condition = getCondition(conditionClass, this.context.getClassLoader());
conditions.add(condition);
}
}
// 排序
AnnotationAwareOrderComparator.sort(conditions);
for (Condition condition : conditions) {
ConfigurationPhase requiredPhase = null;
if (condition instanceof ConfigurationCondition) {
requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
}
// 4... condition.matches()条件匹配执行
if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
/*
* 1. requiredPhase不是ConfigurationCondition的实例
* 2. phase == requiredPhase,从上述的递归可知:phase可为ConfigurationPhase.PARSE_CONFIGURATION || ConfigurationPhase.REGISTER_BEAN
* 3. condition.matches(this.context, metadata)返回false
* 如(1,2 || 1,3)成立,则在此函数的上层将阻断bean注入Spring容器
*/
return true;
}
}
return false;
}
@SuppressWarnings("unchecked")
private List<String[]> getConditionClasses(AnnotatedTypeMetadata metadata) {
// 1.
MultiValueMap<String, Object> attributes = metadata.getAllAnnotationAttributes(Conditional.class.getName(), true);
Object values = (attributes != null ? attributes.get("value") : null);
return (List<String[]>) (values != null ? values : Collections.emptyList());
}
private Condition getCondition(String conditionClassName, @Nullable ClassLoader classloader) {
// 1.
Class<?> conditionClass = ClassUtils.resolveClassName(conditionClassName, classloader);
return (Condition) BeanUtils.instantiateClass(conditionClass);
}
}
1. MyShouldSkip
@Component
@Conditional({ConditionWindows.class})
@Order(1)
public class MyShouldSkip {
}
public class ConditionWindows implements Condition {
/**
* @param conditionContext 条件上下文
* @param annotatedTypeMetadata SimpleAnnotationMetadata
*/
@Override
public boolean matches(ConditionContext conditionContext, AnnotatedTypeMetadata annotatedTypeMetadata) {
// 获取IOC使用的BF
ConfigurableListableBeanFactory bf = conditionContext.getBeanFactory();
// 获取类加载器
ClassLoader classLoader = conditionContext.getClassLoader();
// 获取当前环境信息
Environment environment = conditionContext.getEnvironment();
// 获取bean定义的注册类
BeanDefinitionRegistry registry = conditionContext.getRegistry();
// 获得当前系统名
String property = environment.getProperty("os.name");
// 包含Windows则说明是windows系统,返回true
// return property != null && property.contains("Windows");
return property != null && property.contains("Mac OS X");
}
}
3. doProcessConfigurationClass()
// 1. @Component:递归MemberClasses
// 2. @PropertySource:解析加载properties,并将属性添加到Spring上下文中
// 3. @ComponentScan
// 4. @Import
// 5. @ImportResource:加载Spring配置文件
// 6. @Bean:将@Bean方法转化为BeanMethod对象,保存集合中
// 7. interface_@Bean:jdk8后,接口中方法可以有默认实现
// 8. superclass:被解析configClass继承了某个类,configClass父类也会被进行解析
class ConfigurationClassParser {
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader,
BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry) {
this.metadataReaderFactory = metadataReaderFactory;
this.problemReporter = problemReporter;
this.environment = environment;
this.resourceLoader = resourceLoader;
this.registry = registry;
// 1. 扫描包及子包下.class,将其解析成BD
this.componentScanParser = new ComponentScanAnnotationParser(
environment, resourceLoader, componentScanBeanNameGenerator, registry);
this.conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);
}
@Nullable
protected final SourceClass doProcessConfigurationClass(
ConfigurationClass configClass, SourceClass sourceClass, Predicate<String> filter)
throws IOException {
// 1. @Component,递归MemberClasses。@Configuration包含@Component
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
// Process any @PropertySource annotations
// 2. @PropertySource,解析加载properties,并将属性添加到Spring上下文中
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
// 查看类图
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
} else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
/*
* 3. @ComponentScan
* ComponentScanAnnotationParser扫描路径下的bean => BD,并注册到IOC
* 新BD => super_recursive
*/
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 1. 扫描包及子包下.class,将其解析成BD
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 是否是ConfigClass
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 2. super_recursive
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
/*
* 4. @Import,导入额外配置类 recursive
* getImports() => collectImports()(递归获取所有要导入类)
* processImports()(递归解析要导入类)
*/
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
// Process any @ImportResource annotations
// 5. @ImportResource,加载Spring配置文件
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
// 增加ImportedResource标识
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// Process individual @Bean methods
// 6. @Bean。@Bean方法转化为BeanMethod对象 => configClass
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
// 7. interface_@Bean,jdk8后,接口中方法可以有默认实现
processInterfaces(configClass, sourceClass);
// Process superclass, if any
// 8. ConfigClass的SuperClass的注解也会被解析
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// No superclass -> processing is complete
return null;
}
}
0. AnnotationConfigUtils
public abstract class AnnotationConfigUtils {
static Set<AnnotationAttributes> attributesForRepeatable(AnnotationMetadata metadata,
Class<?> containerClass, Class<?> annotationClass) {
// 1..
return attributesForRepeatable(metadata, containerClass.getName(), annotationClass.getName());
}
@SuppressWarnings("unchecked")
static Set<AnnotationAttributes> attributesForRepeatable(
AnnotationMetadata metadata, String containerClassName, String annotationClassName) {
Set<AnnotationAttributes> result = new LinkedHashSet<>();
// 1.. Direct annotation present?
addAttributesIfNotNull(result, metadata.getAnnotationAttributes(annotationClassName, false));
// Container annotation present?
Map<String, Object> container = metadata.getAnnotationAttributes(containerClassName, false);
if (container != null && container.containsKey("value")) {
for (Map<String, Object> containedAttributes : (Map<String, Object>[]) container.get("value")) {
// 2..
addAttributesIfNotNull(result, containedAttributes);
}
}
// Return merged result
return Collections.unmodifiableSet(result);
}
private static void addAttributesIfNotNull(
Set<AnnotationAttributes> result, @Nullable Map<String, Object> attributes) {
if (attributes != null) {
// 1... AnnotationAttributes
result.add(AnnotationAttributes.fromMap(attributes));
}
}
// ---------------------------------------------------------------------------------------------------
@Nullable
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class<?> annotationClass) {
// 1.
return attributesFor(metadata, annotationClass.getName());
}
@Nullable
static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) {
// 1... AnnotationAttributes
return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false));
}
}
public class AnnotationAttributes extends LinkedHashMap<String, Object> {
private static final String UNKNOWN = "unknown";
@Nullable
private final Class<? extends Annotation> annotationType;
final String displayName;
boolean validated = false;
public AnnotationAttributes(Map<String, Object> map) {
super(map);
this.annotationType = null;
this.displayName = UNKNOWN;
}
@Nullable
public static AnnotationAttributes fromMap(@Nullable Map<String, Object> map) {
if (map == null) {
return null;
}
if (map instanceof AnnotationAttributes) {
return (AnnotationAttributes) map;
}
// 1.
return new AnnotationAttributes(map);
}
}
1. @Component
processMemberClasses()
处理内部类,进行Super_recursiveasConfigClass()
生成ConfigurationClass
// 1. @Component,递归MemberClasses。@Configuration包含@Component
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass, filter);
}
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass,
Predicate<String> filter) throws IOException {
// 循环判断内部类是不是配置类
Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
if (!memberClasses.isEmpty()) {
List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
for (SourceClass memberClass : memberClasses) {
// 1. 配置类
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
candidates.add(memberClass);
}
}
OrderComparator.sort(candidates);
for (SourceClass candidate : candidates) {
if (this.importStack.contains(configClass)) {
// 循环导入,则直接报错
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
} else {
this.importStack.push(configClass);
try {
// 2. super_recursive,解析内部类
processConfigurationClass(candidate.asConfigClass(configClass), filter);
} finally {
this.importStack.pop();
}
}
}
}
}
private class SourceClass implements Ordered {
private final Object source; // Class or MetadataReader
private final AnnotationMetadata metadata; // SimpleAnnotationMetadata
public ConfigurationClass asConfigClass(ConfigurationClass importedBy) {
if (this.source instanceof Class) {
return new ConfigurationClass((Class<?>) this.source, importedBy);
}
// 1.
return new ConfigurationClass((MetadataReader) this.source, importedBy);
}
}
@Component
@Order(1)
public class MyComponent {
@Component
static class InnerClass {
}
}
2. @PropertySource
@PropertySources
目前不好使
// Process any @PropertySource annotations
// @PropertySource,解析加载properties,并将属性添加到Spring上下文中
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
// 查看类图
if (this.environment instanceof ConfigurableEnvironment) {
// 1..
processPropertySource(propertySource);
} else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
@Component
// @PropertySources({
// @PropertySource({"classpath:p2_propertySource.properties"})
// })
@PropertySource({"classpath:p2_propertySource.properties"})
@Order(2)
public class MyPropertySource {
// 任意Spring_bean都可以获取@Value
@Value("${p1.name}")
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "MyPropertySources{" +
"name='" + name + '\'' +
'}';
}
}
MutablePropertySources#addLast()
class ConfigurationClassParser {
private final Environment environment;
private static final PropertySourceFactory DEFAULT_PROPERTY_SOURCE_FACTORY = new DefaultPropertySourceFactory();
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
// 1.1. name属性
String name = propertySource.getString("name");
if (!StringUtils.hasLength(name)) {
name = null;
}
// 1.2. encoding属性
String encoding = propertySource.getString("encoding");
if (!StringUtils.hasLength(encoding)) {
encoding = null;
}
// 1.3. value属性
String[] locations = propertySource.getStringArray("value");
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));
for (String location : locations) {
try {
// 2.1. 处理文件名占位符
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
// 2.2. 指定位置文件 => ClassPathXmlApplicationContext.getResource()
Resource resource = this.resourceLoader.getResource(resolvedLocation);
// 2.3.. 添加resource对象为属性资源
addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
} catch (IllegalArgumentException | FileNotFoundException | UnknownHostException | SocketException ex) {
// Placeholders not resolvable or resource not found when trying to open it
if (ignoreResourceNotFound) {
if (logger.isInfoEnabled()) {
logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
}
} else {
throw ex;
}
}
}
}
// ------------------------------------------------------------------------------------------
private void addPropertySource(PropertySource<?> propertySource) {
String name = propertySource.getName();
// 1. environment.propertySources
MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
if (this.propertySourceNames.contains(name)) {
// We've already added a version, we need to extend it
PropertySource<?> existing = propertySources.get(name);
if (existing != null) {
PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
((ResourcePropertySource) propertySource).withResourceName() : propertySource);
if (existing instanceof CompositePropertySource) {
((CompositePropertySource) existing).addFirstPropertySource(newSource);
} else {
if (existing instanceof ResourcePropertySource) {
existing = ((ResourcePropertySource) existing).withResourceName();
}
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(newSource);
composite.addPropertySource(existing);
propertySources.replace(name, composite);
}
return;
}
}
if (this.propertySourceNames.isEmpty()) {
// 2. debug StandardEnvironment.customizePropertySources()
propertySources.addLast(propertySource);
} else {
String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
propertySources.addBefore(firstProcessed, propertySource);
}
this.propertySourceNames.add(name);
}
}
public class DefaultPropertySourceFactory implements PropertySourceFactory {
@Override
public PropertySource<?> createPropertySource(@Nullable String name, EncodedResource resource) throws IOException {
return (name != null ? new ResourcePropertySource(name, resource) : new ResourcePropertySource(resource));
}
}
1. MutablePropertySources
public class MutablePropertySources implements PropertySources {
private final List<PropertySource<?>> propertySourceList = new CopyOnWriteArrayList<>();
/**
* Add the given property source object with lowest precedence.
*/
public void addLast(PropertySource<?> propertySource) {
synchronized (this.propertySourceList) {
removeIfPresent(propertySource);
this.propertySourceList.add(propertySource);
}
}
}
3. @ComponentScan
- xml =>
<context:component-scan>
,解析类为ComponentScanBeanDefinitionParser
- class =>
@ComponentScan
,解析类为ComponentScanAnnotationParser
- 用的扫描类都是
ClassPathBeanDefinitionScanner
public ConfigurationClassParser(MetadataReaderFactory metadataReaderFactory,
ProblemReporter problemReporter, Environment environment, ResourceLoader resourceLoader,
BeanNameGenerator componentScanBeanNameGenerator, BeanDefinitionRegistry registry) {
this.metadataReaderFactory = metadataReaderFactory;
this.problemReporter = problemReporter;
this.environment = environment;
this.resourceLoader = resourceLoader;
this.registry = registry;
// 1. 扫描包及子包下.class,将其解析成BD
this.componentScanParser = new ComponentScanAnnotationParser(
environment, resourceLoader, componentScanBeanNameGenerator, registry);
this.conditionEvaluator = new ConditionEvaluator(registry, environment, resourceLoader);
}
// ComponentScanAnnotationParser
private final ComponentScanAnnotationParser componentScanParser;
// Process any @ComponentScan annotations
/*
* 3. @ComponentScan
* ComponentScanAnnotationParser扫描包及子包下@Compnent修饰.class,将其解析成BD
* 新BD => super_recursive
*/
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
// 1. ComponentScanAnnotationParser扫描包及子包下@Compnent修饰.class,将其解析成BD
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
// 是否是ConfigClass
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
// 2. super_recursive
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
@ComponentScan(
value = "com.listao.annotation.component",
includeFilters = @ComponentScan.Filter(Service.class),
excludeFilters = {@ComponentScan.Filter(Configuration.class)}
)
@Order(3)
public class MyComponentScan {
}
1. ComponentScanAnnoParser
- ClassPathBeanDefinitionScanner
- 对应 xml 解析的
ClassPathBeanDefinitionScanner
,底层都是ClassPathBeanDefinitionScanner
进一步处理
class ComponentScanAnnotationParser {
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
// 1. 创建扫描类
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
// 获取@ComponentScan参数,并进行参数设置
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
// 获取scopedProxy属性
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
} else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
// 获取resourcePattern属性
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
// 2. includeFilters属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
// 3. excludeFilters属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
// 获取lazyInit属性
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
Set<String> basePackages = new LinkedHashSet<>();
// 获取basePackages属性
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
// 获取basePackageClasses属性
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
// 4. doScan
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
}
4. @Import
// Process any @Import annotations
/*
* 4. @Import,导入额外配置类 recursive
*
* 1. getImports() => collectImports()(递归获取所有要导入类)
* 2. processImports()(递归解析要导入类)
*/
processImports(configClass, sourceClass, getImports(sourceClass), filter, true);
@Import(ImptBD.class) // `implements ImportBeanDefinitionRegistrar`
@Impt
public class MyImpt {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Indexed
@Import(Tmp.class)
public @interface Impt {
/**
* The value may indicate a suggestion for a logical component name,
* to be turned into a Spring bean in case of an autodetected component.
* @return the suggested component name, if any (or empty String otherwise)
*/
String value() default "";
}
public class ImptBD implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry
, BeanNameGenerator importBeanNameGenerator) {
System.out.println("====>>>> ImptBD.registerBeanDefinitions()");
}
}
1. getImports()
/**
* Returns {@code @Import} class, considering all meta-annotations.
*/
private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
// @Import注解的类。SpringBoot_debug imports中包含三个重要类
Set<SourceClass> imports = new LinkedHashSet<>();
// 实现递归调用
Set<SourceClass> visited = new LinkedHashSet<>();
collectImports(sourceClass, imports, visited);
// SpringBoot_debug
return imports;
}
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)
throws IOException {
if (visited.add(sourceClass)) {
for (SourceClass annotation : sourceClass.getAnnotations()) {
String annName = annotation.getMetadata().getClassName();
// 1. 不包含@Import继续recursive
if (!annName.equals(Import.class.getName())) {
collectImports(annotation, imports, visited);
}
}
// 2. 获取sourceClass上@Import注解的值
imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
}
}
2. processImports()
ImportSelector
instanceof DeferredImportSelector
延后处理processImports()
正常处理
implements ImportBeanDefinitionRegistrar
- 存入
configClass.importBeanDefinitionRegistrars
- 存入
- 作为
ConfigClass
,继续处理 => IOC
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, Predicate<String> exclusionFilter,
boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
// 通过一个栈(importStack)解决循环引入
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
} else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
// 1.1. `TransactionManagementConfigurationSelector implements ImportSelector`
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
// 1.2. 反射生成ImportSelect
ImportSelector selector = ParserStrategyUtils.instantiateClass(candidateClass, ImportSelector.class,
this.environment, this.resourceLoader, this.registry);
Predicate<String> selectorFilter = selector.getExclusionFilter();
if (selectorFilter != null) {
exclusionFilter = exclusionFilter.or(selectorFilter);
}
// 延迟处理,所有configClass加载完毕后加载
if (selector instanceof DeferredImportSelector) {
// 1.3. 将选择器缓存到deferredImportSelectorHandler,所有configClass加载完成后统一处理
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
} else {
// 1.4. @EnableTransactionManagement处理 => 调用@Import的类的`selectImports()`方法,得到再次import的全路径名
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames, exclusionFilter);
// 1.5. 递归处理
processImports(configClass, currentSourceClass, importSourceClasses, exclusionFilter, false);
}
}
// 2.1. `implements ImportBeanDefinitionRegistrar`的BD
// 2.2. @EnableAspectJAutoProxy
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
ParserStrategyUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class,
this.environment, this.resourceLoader, this.registry);
// 2.3. 存入configClass.importBeanDefinitionRegistrars
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
// 3.1. 作为ConfigClass,继续处理
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
// process it as an @Configuration class
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
// 3.2. jar里的@Configuration,递归处理
processConfigurationClass(candidate.asConfigClass(configClass), exclusionFilter);
}
}
} catch (BeanDefinitionStoreException ex) {
throw ex;
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
} finally {
this.importStack.pop();
}
}
}
1. @SpringBootApplication
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan(excludeFilters = { @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
@Filter(type = FilterType.CUSTOM, classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
}
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@AutoConfigurationPackage
@Import(AutoConfigurationImportSelector.class)
public @interface EnableAutoConfiguration {
String ENABLED_OVERRIDE_PROPERTY = "spring.boot.enableautoconfiguration";
}
public class AutoConfigurationImportSelector implements DeferredImportSelector, BeanClassLoaderAware,
ResourceLoaderAware, BeanFactoryAware, EnvironmentAware, Ordered {
private static final AutoConfigurationEntry EMPTY_ENTRY = new AutoConfigurationEntry();
private static final String[] NO_IMPORTS = {};
private static final Log logger = LogFactory.getLog(AutoConfigurationImportSelector.class);
private static final String PROPERTY_NAME_AUTOCONFIGURE_EXCLUDE = "spring.autoconfigure.exclude";
private ConfigurableListableBeanFactory beanFactory;
private Environment environment;
private ClassLoader beanClassLoader;
private ResourceLoader resourceLoader;
@Override
public String[] selectImports(AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return NO_IMPORTS;
}
// 1. `autoconfigure-metadata.properties`
AutoConfigurationMetadata autoConfigurationMetadata = AutoConfigurationMetadataLoader.loadMetadata(this.beanClassLoader);
// 2..
AutoConfigurationEntry autoConfigurationEntry = getAutoConfigurationEntry(autoConfigurationMetadata, annotationMetadata);
return StringUtils.toStringArray(autoConfigurationEntry.getConfigurations());
}
/**
* Return the {@link AutoConfigurationEntry} based on the {@link AnnotationMetadata}
* of the importing {@link Configuration @Configuration} class.
* @param autoConfigurationMetadata the auto-configuration metadata
* @param annotationMetadata the annotation metadata of the configuration class
* @return the auto-configurations that should be imported
*/
protected AutoConfigurationEntry getAutoConfigurationEntry(AutoConfigurationMetadata autoConfigurationMetadata,
AnnotationMetadata annotationMetadata) {
if (!isEnabled(annotationMetadata)) {
return EMPTY_ENTRY;
}
AnnotationAttributes attributes = getAttributes(annotationMetadata);
// 1. `spring.factory`
List<String> configurations = getCandidateConfigurations(annotationMetadata, attributes);
configurations = removeDuplicates(configurations);
Set<String> exclusions = getExclusions(annotationMetadata, attributes);
checkExcludedClasses(configurations, exclusions);
configurations.removeAll(exclusions);
// 2. SpringBoot自动装配过滤
configurations = filter(configurations, autoConfigurationMetadata);
fireAutoConfigurationImportEvents(configurations, exclusions);
return new AutoConfigurationEntry(configurations, exclusions);
}
}
2. @EnableTrxManagement
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {
}
public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
/**
* Returns {@link ProxyTransactionManagementConfiguration} or
* {@code AspectJ(Jta)TransactionManagementConfiguration} for {@code PROXY}
* and {@code ASPECTJ} values of {@link EnableTransactionManagement#mode()},
* respectively.
*/
@Override
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),
ProxyTransactionManagementConfiguration.class.getName()};
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
}
5. @ImportResource
// Process any @ImportResource annotations
// @ImportResource,加载Spring配置文件
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
// 1. this.importedResources标识
configClass.addImportedResource(resolvedResource, readerClass);
}
}
- 加载
Spring_bean.xml
配置文件
@ImportResource(locations = {"classpath:x0_ooxx.xml"})
public class MyImportResource {
}
6. @Bean
// Process individual @Bean methods
// @Bean。@Bean方法转化为BeanMethod对象 => configClass
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
// 1.
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
- 获取类的方法上的
AnnotationMetadata
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
// 1. SimpleAnnotationMetadata
AnnotationMetadata original = sourceClass.getMetadata();
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
// 2. skip
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
// Try reading the class file via ASM for deterministic declaration order...
// Unfortunately, the JVM's standard reflection returns methods in arbitrary
// order, even between different runs of the same application on the same JVM.
try {
AnnotationMetadata asm =
this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
for (MethodMetadata beanMethod : beanMethods) {
if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
selectedMethods.add(beanMethod);
break;
}
}
}
if (selectedMethods.size() == beanMethods.size()) {
// All reflection-detected methods found in ASM method set -> proceed
beanMethods = selectedMethods;
}
}
} catch (IOException ex) {
logger.debug("Failed to read class file via ASM for determining @Bean method order", ex);
// No worries, let's continue with the reflection metadata we started with...
}
}
return beanMethods;
}
@Conditional({ConditionWindows.class})
public class MyBean {
@Bean(name = "bill")
public Ooxx bill() {
return new Ooxx(1, "bill");
}
@Conditional({ConditionLinux.class})
@Bean("linus")
public Ooxx linus() {
return new Ooxx(2, "linux");
}
}
1. BeanMethod
final class BeanMethod extends ConfigurationMethod {
public BeanMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {
super(metadata, configurationClass);
}
}
abstract class ConfigurationMethod {
protected final MethodMetadata metadata;
protected final ConfigurationClass configurationClass;
public ConfigurationMethod(MethodMetadata metadata, ConfigurationClass configurationClass) {
this.metadata = metadata;
this.configurationClass = configurationClass;
}
}
7. Interfaces
// Process default methods on interfaces
// 7. interface_@Bean,jdk8后,接口中方法可以有默认实现
processInterfaces(configClass, sourceClass);
/**
* Register default methods on interfaces implemented by the configuration class.
*/
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
// 1. 获取类的接口,getInterfaces()
for (SourceClass ifc : sourceClass.getInterfaces()) {
// 2. 获取@Bean注解的default方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
for (MethodMetadata methodMetadata : beanMethods) {
if (!methodMetadata.isAbstract()) {
// 3. A default method or other concrete method on a Java 8+ interface...
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
}
// 4. 递归处理父接口
processInterfaces(configClass, ifc);
}
}
@Component
public class BeanImpl implements IBean {
}
public interface IBean {
@Bean
@Order(4)
default String show(){
return "ooxx";
}
}
8. superClass
ConfigClass
的SuperClass
也作为ConfigClass
进行Super_recursive- 直接return,进行递归
// Process superclass, if any
// 8. ConfigClass的SuperClass的注解也会被解析
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
@Component
public class ChildClass extends SuperClass {
}
public class SuperClass {
@Bean(value = "superClass")
public String superClass() {
return "superClass";
}
}
4. do_while
do_while
进行recursive。将configClass存入ConfigurationClassParser.configurationClasses
private final Map<ConfigurationClass, ConfigurationClass> configurationClasses = new LinkedHashMap<>();
do {
// 3. 核心:解析注解
sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter);
}
while (sourceClass != null);
// 4. ConfigClass全部加入configurationClasses_map
this.configurationClasses.put(configClass, configClass);
#2.2. ConfigurationClassBDReader
/*
* 1. IOC中原始的ConfigurationClasses
* 2. @Import导入的bean
* 3. @Component的InnerClass
*/
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
// 清除已经解析处理过的ConfigClass
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 4... 核心方法,将新ConfigClass_BD => IOC
this.reader.loadBeanDefinitions(configClasses);
class ConfigurationClassBeanDefinitionReader {
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
// 1.. 遍历处理 ConfigClass
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
// 1.. @Import导入类, @Component_InnerClass
if (configClass.isImported()) {
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
// 2.. @Bean方法,添加到BD_Map
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
// 3.. @ImportedResources => 调用BeanDefinitionReader处理
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
// 4.. configClass类 `implements ImportBeanDefinitionRegistrar` 执行registerBeanDefinitions()
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
}
1. importedBy
@Import
导入类,@Component_InnerClassAnnotatedGenericBeanDefinition
=> IOC
/**
* Register the {@link Configuration} class itself as a bean definition.
*/
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
AnnotationMetadata metadata = configClass.getMetadata();
// 1. AnnotatedGenericBeanDefinition
AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
configBeanDef.setScope(scopeMetadata.getScopeName());
String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
// 2. 封装BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
// 3. => IOC
this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
configClass.setBeanName(configBeanName);
if (logger.isTraceEnabled()) {
logger.trace("Registered bean definition for imported class '" + configBeanName + "'");
}
}
@SuppressWarnings("serial")
public class AnnotatedGenericBeanDefinition extends GenericBeanDefinition implements AnnotatedBeanDefinition {
// 注解元数据
private final AnnotationMetadata metadata;
public AnnotatedGenericBeanDefinition(AnnotationMetadata metadata) {
Assert.notNull(metadata, "AnnotationMetadata must not be null");
if (metadata instanceof StandardAnnotationMetadata) {
setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
} else {
setBeanClassName(metadata.getClassName());
}
this.metadata = metadata;
}
}
2. beanMethods
ConfigurationClassBeanDefinition
=> IOC@Bean(name = "bill")
自定义bean_name@Bean
,用methodName
- factoryBeanName
- factoryMethodName
- 注入IOC
// 2. @Bean方法,添加到BD_Map
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
/**
* 将bean注解的方法元数据取出来分析,分析@Bean注解,有没有别名,有没有跟xml配置冲突,封装成一个configurationClassBD
* 然后设置工厂方法名,获取bean注解的属性,设置初始化方法,销毁方法,是否自动装配,是否需要代理等
* <p>
* Read the given {@link BeanMethod}, registering bean definitions
* with the BeanDefinitionRegistry based on its contents.
*/
@SuppressWarnings("deprecation") // for RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
// 1.
ConfigurationClass configClass = beanMethod.getConfigurationClass();
MethodMetadata metadata = beanMethod.getMetadata();
String methodName = metadata.getMethodName();
// Do we need to mark the bean as skipped by its condition?
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
configClass.skippedBeanMethods.add(methodName);
return;
}
if (configClass.skippedBeanMethods.contains(methodName)) {
return;
}
// 2.
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
Assert.state(bean != null, "No @Bean annotation attributes");
// 3. Consider name and any aliases
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
// Register aliases even when overridden
for (String alias : names) {
// 注册剩下别名
this.registry.registerAlias(beanName, alias);
}
// Has this effectively been overridden before (e.g. via XML)?
// beanName相同
if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
"' clashes with bean name for containing configuration class; please make those names unique!");
}
return;
}
// 4. 封装ConfigurationClassBD
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata, beanName);
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
// 5. static @Bean_method
if (metadata.isStatic()) {
if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
} else {
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
}
beanDef.setUniqueFactoryMethodName(methodName);
}
// 6.1. instance @Bean_method
else {
// 6.2. factoryBeanName
beanDef.setFactoryBeanName(configClass.getBeanName());
// 6.3. **factoryMethodName**
beanDef.setUniqueFactoryMethodName(methodName);
}
// @Bean_method对象
if (metadata instanceof StandardMethodMetadata) {
beanDef.setResolvedFactoryMethod(((StandardMethodMetadata) metadata).getIntrospectedMethod());
}
// 设置自定义装配模式,默认是构造器
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
// 设置略过属性检查 (skipRequiredCheck, true)
beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
// 处理通用注解,注解里可能还有自动装配注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
// 自动装配设置
Autowire autowire = bean.getEnum("autowire");
if (autowire.isAutowire()) {
// BY_NAME, BY_TYPE
beanDef.setAutowireMode(autowire.value());
}
// 自动装配候选,默认true
boolean autowireCandidate = bean.getBoolean("autowireCandidate");
if (!autowireCandidate) {
beanDef.setAutowireCandidate(false);
}
// 初始化方法。@PostConstruct InitializingBean接口
String initMethodName = bean.getString("initMethod");
if (StringUtils.hasText(initMethodName)) {
beanDef.setInitMethodName(initMethodName);
}
// 销毁方法。@PreDestroy, DisposableBean接口
String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName);
// Consider scoping
ScopedProxyMode proxyMode = ScopedProxyMode.NO;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
if (attributes != null) {
beanDef.setScope(attributes.getString("value"));
proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = ScopedProxyMode.NO;
}
}
// Replace the original bean definition with the target one, if necessary
BeanDefinition beanDefToRegister = beanDef;
// 作用域不是no, 使用代理
if (proxyMode != ScopedProxyMode.NO) {
BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
new BeanDefinitionHolder(beanDef, beanName), this.registry,
proxyMode == ScopedProxyMode.TARGET_CLASS);
beanDefToRegister = new ConfigurationClassBeanDefinition(
(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata, beanName);
}
if (logger.isTraceEnabled()) {
logger.trace(String.format("Registering bean definition for @Bean method %s.%s()",
configClass.getMetadata().getClassName(), beanName));
}
// 7. 注入IOC
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
1. ConfigurationClassBD
class ConfigurationClassBeanDefinitionReader {
private static class ConfigurationClassBeanDefinition extends RootBeanDefinition implements AnnotatedBeanDefinition {
private final AnnotationMetadata annotationMetadata;
private final MethodMetadata factoryMethodMetadata;
private final String derivedBeanName;
public ConfigurationClassBeanDefinition(
ConfigurationClass configClass, MethodMetadata beanMethodMetadata, String derivedBeanName) {
this.annotationMetadata = configClass.getMetadata();
this.factoryMethodMetadata = beanMethodMetadata;
this.derivedBeanName = derivedBeanName;
setResource(configClass.getResource());
setLenientConstructorResolution(false);
}
}
}
public class RootBeanDefinition extends AbstractBeanDefinition {
boolean isFactoryMethodUnique = false;
/**
* Specify a factory method name that refers to a non-overloaded method.
*/
public void setUniqueFactoryMethodName(String name) {
Assert.hasText(name, "Factory method name must not be empty");
setFactoryMethodName(name);
this.isFactoryMethodUnique = true;
}
}
public abstract class AbstractBeanDefinition extends BeanMetadataAttributeAccessor
implements BeanDefinition, Cloneable {
@Nullable
private String factoryMethodName;
@Override
public void setFactoryMethodName(@Nullable String factoryMethodName) {
this.factoryMethodName = factoryMethodName;
}
}
2. instantiateUsingFactoryMtd()
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
}
MyBean#bill()
3. @ImportResource
// 3. @ImportedResources => 调用BeanDefinitionReader处理
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
XmlBeanDefinitionReader#loadBeanDefinitions()
private void loadBeanDefinitionsFromImportedResources(
Map<String, Class<? extends BeanDefinitionReader>> importedResources) {
Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<>();
importedResources.forEach((resource, readerClass) -> {
// Default reader selection necessary?
if (BeanDefinitionReader.class == readerClass) {
if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) {
// When clearly asking for Groovy, that's what they'll get...
readerClass = GroovyBeanDefinitionReader.class;
} else {
// 1. Primarily ".xml" files but for any other extension as well
readerClass = XmlBeanDefinitionReader.class;
}
}
BeanDefinitionReader reader = readerInstanceCache.get(readerClass);
if (reader == null) {
try {
// 2. Instantiate the specified BeanDefinitionReader
reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);
// Delegate the current ResourceLoader to it if possible
if (reader instanceof AbstractBeanDefinitionReader) {
AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader);
abdr.setResourceLoader(this.resourceLoader);
abdr.setEnvironment(this.environment);
}
readerInstanceCache.put(readerClass, reader);
} catch (Throwable ex) {
throw new IllegalStateException(
"Could not instantiate BeanDefinitionReader class [" + readerClass.getName() + "]");
}
}
// 3. XmlBeanDefinitionReader
// TODO SPR-6310: qualify relative path locations as done in AbstractContextLoader.modifyLocations
reader.loadBeanDefinitions(resource);
});
}
4. importBDRegistrars
// 4. configClass类 `implements ImportBeanDefinitionRegistrar` 执行registerBeanDefinitions()
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
private void loadBeanDefinitionsFromRegistrars(Map<ImportBeanDefinitionRegistrar, AnnotationMetadata> registrars) {
registrars.forEach((registrar, metadata) ->
registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
}
1. ImptBD
- 必须为
@Import
的类,该类不是ConfigurationClass,不进行IOC - 4. @Import
public class ImptBD implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry
, BeanNameGenerator importBeanNameGenerator) {
System.out.println("====>>>> ImptBD.registerBeanDefinitions()");
}
}
2. @EnableAspectJAutoProxy
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(AspectJAutoProxyRegistrar.class)
public @interface EnableAspectJAutoProxy {
}
class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
@Override
public void registerBeanDefinitions(
AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
// 1. 注册internal类
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
AnnotationAttributes enableAspectJAutoProxy =
AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
if (enableAspectJAutoProxy != null) {
if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
}
if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
}
}
}
}