1. Bean 类型
1.1 Spring bean VS Java bean
- Spring bean 有一个初始化的过程,经历过完整 Spring 生命周期,放在spring 容器里
- Java bean 是 new 出来的对象
1.2 回调注入
- Aware 接口
- ApplicationContextAware
ApplicationContextAware
2. Spring bean 的生命周期
- Spring 会将 class 信息封装成 BeanDefinition,然后再放进 DefaultListableBeanFactory 的beanDefinitionMap中
2.1 BeanDefinition
- BeanDefinition 是一种配置元信息,它描述了 Bean 的定义信息
interface BeanDefinition extends AttributeAccessor, BeanMetadataElement
- AbstractBeanDefinition 的三个子类
- GenericBeanDefinition
- RootBeanDefinition
- ChildBeanDefinition
源码分析
- 入口
obtainFreshBeanFactory()
- refreshBeanFactory()
- loadBeanDefinitions(beanFactory);
- loadBeanDefinitions(beanDefinitionReader);
- doLoadBeanDefinitions(inputSource, encodedResource.getResource());
- registerBeanDefinitions(doc, resource);
- doRegisterBeanDefinitions(doc.getDocumentElement());
- parseBeanDefinitions(root, this.delegate);
- parseDefaultElement(ele, delegate);
- processBeanDefinition(ele, delegate);
- delegate.parseBeanDefinitionElement(ele);
- registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())
- 扫描生成 BeanDefinition
ClassPathBeanDefinitionScanner.doScan
2.1 registerBeanDefinitions()
public int registerBeanDefinitions(Document doc, Resource resource) throws BeanDefinitionStoreException {
// 委托模式,委托 BeanDefinitionDocumentReader 进行 document 解析
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
// 具体解析过程
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
2.2 parseBeanDefinitions()
// DefaultBeanDefinitionDocumentReader#parseBeanDefinitions
if (node instanceof Element) {
Element ele = (Element) node;
if (delegate.isDefaultNamespace(ele)) {
// 3.1 默认标签解析
parseDefaultElement(ele, delegate);
} else {
// 3.2 自定义标签解析
delegate.parseCustomElement(ele);
}
}
3.1 默认标签解析
<bean id="" class="" />
- DefaultBeanDefinitionDocumentReader#parseDefaultElement
private void parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate) {
if (delegate.nodeNameEquals(ele, IMPORT_ELEMENT)) {
importBeanDefinitionResource(ele);
}
else if (delegate.nodeNameEquals(ele, ALIAS_ELEMENT)) {
processAliasRegistration(ele);
}
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);
}
else if (delegate.nodeNameEquals(ele, NESTED_BEANS_ELEMENT)) {
doRegisterBeanDefinitions(ele);
}
}
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) {
// 4.1
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
// 4.2
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
// Bean 属性解析
AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);
ele.hasAttribute(CLASS_ATTRIBUTE)
ele.hasAttribute(PARENT_ATTRIBUTE)
parseBeanDefinitionAttributes(ele, beanName, containingBean, bd);
ele.hasAttribute(SINGLETON_ATTRIBUTE)
ele.hasAttribute(SCOPE_ATTRIBUTE)
ele.hasAttribute(INIT_METHOD_ATTRIBUTE)
// BeanDefinitionReaderUtils.registerBeanDefinition()
// DefaultListableBeanFactory 待定...
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
3.2 自定义标签解析
<context:component-scan base-package="com..." use-default-filters="true" />
- 扫描包中的带有 @Component 的类
- ContextNamespaceHandler#parse (父类 NamespaceHandlerSupport)
- ComponentScanBeanDefinitionParser#parse
public BeanDefinition parse(Element element, ParserContext parserContext) {
// base-package
String basePackage = element.getAttribute(BASE_PACKAGE_ATTRIBUTE);
basePackage = parserContext.getReaderContext().getEnvironment().resolvePlaceholders(basePackage);
String[] basePackages = StringUtils.tokenizeToStringArray(basePackage, ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
// 5.1 注解扫描器
ClassPathBeanDefinitionScanner scanner = configureScanner(parserContext, element);
// 5.2 扫描并把类封装成 BeanDefinition 对象
Set<BeanDefinitionHolder> beanDefinitions = scanner.doScan(basePackages);
// 5.3
registerComponents(parserContext.getReaderContext(), beanDefinitions, element);
return null;
}
5.1 configureScanner()
protected ClassPathBeanDefinitionScanner configureScanner(ParserContext parserContext, Element element) {
boolean useDefaultFilters = true;
if (element.hasAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE)) {
useDefaultFilters = Boolean.parseBoolean(element.getAttribute(USE_DEFAULT_FILTERS_ATTRIBUTE));
}
ClassPathBeanDefinitionScanner scanner = createScanner(parserContext.getReaderContext(), useDefaultFilters);
}
// 注解类型的过滤
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
if (useDefaultFilters) {
registerDefaultFilters();
}
}
private final List<TypeFilter> includeFilters = new ArrayList<>();
this.includeFilters.add(new AnnotationTypeFilter(Component.class));
5.2 doScan()
- 扫描基本包的路径,找
.class
文件
- 递归找
.class
文件
- 判断 .class 文件里是否有注解,includeFilter 里的@Component
- 变成 BeanDefinition 对象
网友评论