① 定位:定位资源文件(定位配置文件或扫描相关注解)
② 加载:解析配置信息
③ 注册:将Bean的信息表示解析成BeanDefinition注册到BeanDefinitionMap
ClassPathXmlApplicationContext:
初始化资源加载器:AbstractApplicationContext()
public AbstractApplicationContext () {
this .resourcePatternResolver = getResourcePatternResolver();
}
protected ResourcePatternResolver getResourcePatternResolver () {
return new PathMatchingResourcePatternResolver (this );
}
设置资源路径:setConfigLocations(configLocations);
容器初始化AbstractApplicationContext#refresh()
:
public ClassPathXmlApplicationContext (
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
super (parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}}
刷新bean factory:AbstractRefreshableApplicationContext#refreshBeanFactory()
+ View Code
AbstractApplicationContext#refresh():
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
AbstractApplicationContext#obtainFreshBeanFactory():
refreshBeanFactory();
@Override
protected final void refreshBeanFactory () throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
synchronized (this .beanFactoryMonitor) {
this .beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException ("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
加载BeanDefinitions(子类实现):AbstractXmlApplicationContext#loadBeanDefinitions()
+ View Code
protected void loadBeanDefinitions (DefaultListableBeanFactory beanFactory)
throws BeansException, IOException {
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader (beanFactory);
beanDefinitionReader.setEnvironment(this .getEnvironment());
beanDefinitionReader.setResourceLoader(this );
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver (this ));
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
protected void loadBeanDefinitions (XmlBeanDefinitionReader reader)
throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null ) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null ) {
reader.loadBeanDefinitions(configLocations);
}
}
AbstractBeanDefinitionReader#loadBeanDefinitions():
counter += loadBeanDefinitions(location);
public int loadBeanDefinitions (EncodedResource encodedResource)
throws BeanDefinitionStoreException {
try {
InputStream inputStream = encodedResource.getResource().getInputStream();
try {
InputSource inputSource = new InputSource (inputStream);
if (encodedResource.getEncoding() != null ) {
inputSource.setEncoding(encodedResource.getEncoding());
}
return doLoadBeanDefinitions(inputSource, encodedResource.getResource());
}
finally {
inputStream.close();
}
}
}
解析资源文件,并注册到BeanDefinitionMap:XmlBeanDefinitionReader#doLoadBeanDefinitions()
+ View Code
protected int doLoadBeanDefinitions (InputSource inputSource, Resource resource)
throws BeanDefinitionStoreException {
try {
Document doc = doLoadDocument(inputSource, resource);
return registerBeanDefinitions(doc, resource);
}catch (Exception ex){
}
}
public int registerBeanDefinitions (Document doc, Resource resource)
throws BeanDefinitionStoreException {
BeanDefinitionDocumentReader documentReader = createBeanDefinitionDocumentReader();
int countBefore = getRegistry().getBeanDefinitionCount();
documentReader.registerBeanDefinitions(doc, createReaderContext(resource));
return getRegistry().getBeanDefinitionCount() - countBefore;
}
DefaultBeanDefinitionDocumentReader#registerBeanDefinitions():
doRegisterBeanDefinitions(root);
DefaultBeanDefinitionDocumentReader#doRegisterBeanDefinitions():
parseBeanDefinitions(root, this .delegate);
DefaultBeanDefinitionDocumentReader#parseBeanDefinitions():
parseDefaultElement(ele, delegate);
DefaultBeanDefinitionDocumentReader#parseDefaultElement():
else if (delegate.nodeNameEquals(ele, BEAN_ELEMENT)) {
processBeanDefinition(ele, delegate);}
protected void processBeanDefinition (Element ele, BeanDefinitionParserDelegate delegate) {
BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele);
if (bdHolder != null ) {
bdHolder = delegate.decorateBeanDefinitionIfRequired(ele, bdHolder);
try {
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry());
}
catch (BeanDefinitionStoreException ex) {
getReaderContext().error("Failed to register bean definition with name '" +
bdHolder.getBeanName() + "'" , ele, ex);
}
getReaderContext().fireComponentRegistered(new BeanComponentDefinition (bdHolder));
}
}
AnnotationConfigApplicationContext
初始化注解Bean读取器和包路径扫描器:AnnotationConfigApplicationContext()
+ View Code
public AnnotationConfigApplicationContext () {
this .reader = new AnnotatedBeanDefinitionReader (this );
this .scanner = new ClassPathBeanDefinitionScanner (this );
}
public AnnotationConfigApplicationContext (Class<?>... annotatedClasses) {
this ();
register(annotatedClasses);
refresh();
}
public AnnotationConfigApplicationContext (String... basePackages) {
this ();
scan(basePackages);
refresh();
}
直接注册:register(Class<?>... annotatedClasses)
public void register (Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified" ); this .reader.register(annotatedClasses);
}
设置扫描路径:scan(String... basePackages)
public void scan (String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified" ); this .scanner.scan(basePackages);
}
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步