先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7
深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
如果你需要这些资料,可以添加V获取:vip1024b (备注Java)
正文
/**
-
Create a new ClassPathXmlApplicationContext with the given parent,
-
loading the definitions from the given XML files.
-
@param configLocations array of resource locations
-
@param refresh whether to automatically refresh the context,
-
loading all bean definitions and creating all singletons.
-
Alternatively, call refresh manually after further configuring the context.
-
@param parent the parent context
-
@throws BeansException if context creation failed
-
@see #refresh()
*/
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
//调用父类的构造器
super(parent);
//设置位置文件地址
setConfigLocations(configLocations);
if (refresh) {
//刷新容器【重点】
refresh();
}
}
在ClasspathXmlApplication的构造器中做了如下事情:
-
调用了父容器的构造器方法,目的是加载设置Bean的资源加载器
ResourcePatternResolver
-
然后通过
setConfigLocations
方法保存好配置文件地址, -
最后调用
refresh()
刷新容器
ResourcePatternResolver是Bean的资源加载器 ,通过父容器 AbstractApplicationContext 中的构造方法创建:
public abstract class AbstractApplicationContext extends DefaultResourceLoader
implements ConfigurableApplicationContext
public AbstractApplicationContext(@Nullable ApplicationContext parent) {
//加载 resourcePatternResolver
this();
//
setParent(parent);
}
/**
- Create a new AbstractApplicationContext with no parent.
*/
//创建一个AbstractApplicationContext容器工厂,并构建一个ResourcePatternResolver
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
//获取 PathMatchingResourcePatternResolver
protected ResourcePatternResolver getResourcePatternResolver() {
return new PathMatchingResourcePatternResolver(this);
}
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {
Assert.notNull(resourceLoader, “ResourceLoader must not be null”);
//资源加载器
this.resourceLoader = resourceLoader;
}
父容器AbstractApplicationContext 继承了 DefaultResourceLoader ,拥有资源加载的能力,在构造器中中创建了ResourcePatternResolver,使用的是PathMatchingResourcePatternResolver
作为实现,它能够将指定的资源位置路径解析为一个或多个匹配的资源。
下面是ResourceLoader 源码:
public interface ResourceLoader {
//默认从classpath中加载资源文件
/** Pseudo URL prefix for loading from the class path: “classpath:”. */
String CLASSPATH_URL_PREFIX = ResourceUtils.CLASSPATH_URL_PREFIX;
//把资源文件转换成Resource
Resource getResource(String location);
ClassLoader getClassLoader();
}
public interface ResourcePatternResolver extends ResourceLoader {
//从classpath加载资源
String CLASSPATH_ALL_URL_PREFIX = “classpath*:”;
//把文件转换成Resource[] ,对ResourceLoader做了扩展
Resource[] getResources(String locationPattern) throws IOException;
}
然后就是保存配置地址 ,从源码可以看出,我们是可以传入多个配置文件给容器的。
public abstract class AbstractRefreshableConfigApplicationContext extends AbstractRefreshableApplicationContext
implements BeanNameAware, InitializingBean {
//地址保存到这里
@Nullable
private String[] configLocations;
/**
-
Set the config locations for this application context.
-
If not set, the implementation may use a default as appropriate.
*/
//可以传入多个配置
public void setConfigLocations(@Nullable String… locations) {
if (locations != null) {
Assert.noNullElements(locations, “Config locations must not be null”);
this.configLocations = new String[locations.length];
for (int i = 0; i < locations.length; i++) {
this.configLocations[i] = resolvePath(locations[i]).trim();
}
}
else {
this.configLocations = null;
}
}
ClasspathXmlApplication调用 AbstractApplicationContext#refresh 方法刷新容器,该方法中实现了IOC容器的整个初始化过程。
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//准备刷新工作 ,记录开始时间,初始化属性,校验配置文件,准备事件的存储Set
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
//告诉子类,刷新Bean工厂,销毁旧beanFactory,创建新beanFactory,默认DefaultListableBeanFactory
//从子容器的refreshBeanFactory方法中载入Bean的资源文件
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//准备工厂,配置工厂的下文特性, 例如上下文的 ClassLoader 和后处理器。Bean表达式解析器,
//BeanPostProcessor和 Aware类的自动装配等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//BeanFactory初始化完成的后置工作,这是一个空方法,留给三方框架或者自己配置,作用是允许对beanFoctory进行扩展处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//调用BeanFactory的后置处理器BeanFactoryPostProcessor,在 bean定义注册之后bean实例化之前调用
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//注册Bean的后置处理器BeanPostProcessor,在Bean初始化前,后执行
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//初始化信息源,国际化相关
initMessageSource();
// Initialize event multicaster for this context.
//初始化容器事件传播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//空方法,该方法子类实现,在容器刷新的时候可以自定义逻辑;如创建Tomcat,Jetty等WEB服务器
onRefresh();
// Check for listener beans and register them.
//注册事件监听器,注册实现了ApplicationListener接口的监听器bean,
//这些监听器是注册到ApplicationEventMulticaster中的
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//实例化所有剩余的(非延迟初始化)单例的Bean
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//完成context的刷新。主要是调用LifecycleProcessor的onRefresh()方法,并且发布事件(ContextRefreshedEvent)
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。
destroyBeans();
// Reset ‘active’ flag.
//取消容器刷新
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();
}
}
}
refresh()方法主要是通过子类 refreshBeanFactory()
方法加载Bean信息,然后就是一些列的容器生命周期事件。这里其实是用到了模板设计模式
,在refresh()方法中指定容器刷新流程,很多的细节步骤由子类去实现。
==========================================================================================
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//刷新工厂,有子类实现
refreshBeanFactory();
//通过子类返回工厂,默认 DefaultListableBeanFactory
return getBeanFactory();
}
这里只是定义了抽象方法,refreshBeanFactory由子类实现,见:AbstractRefreshableApplicationContext#refreshBeanFactory
AbstractRefreshableApplicationContext#refreshBeanFactory
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
//如果已经有BeanFactory,销毁Bean,关闭容器
destroyBeans();
closeBeanFactory();
}
try {
//创建IOC容器
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
//定制BeanFactory,如设置启动参数,开启注解的自动装配等
customizeBeanFactory(beanFactory);
//载入Bean,由子类实现
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
该方法中先判断如果已经存在BeanFactory就销毁掉重新创建,默认使用的是DefaultListableBeanFactory
作为BeanFactory,并loadBeanDefinitions方法加载Bean,方法由子类 AbstractXmlApplicationContext#loadBeanDefinitions
实现。
加载Bean:AbstractXmlApplicationContext#loadBeanDefinitions
======================================================================================================================
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
//创建 XmlBeanDefinitionReader ,用来从XML中读取Bean
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context’s
// resource loading environment.
//把Environment 和 ResourceLoader 设置给beanDefinitionReader
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
//设置Sax解析器
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// then proceed with actually loading the bean definitions.
//初始化Bean的读取器,启用 Xml 的校验机制 , 允许子类自定义初始化读取器
initBeanDefinitionReader(beanDefinitionReader);
//加载Bean, XmlBeanDefinitionReader真正实现加载逻辑
loadBeanDefinitions(beanDefinitionReader);
最后
整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
其实面试这一块早在第一个说的25大面试专题就全都有的。以上提及的这些全部的面试+学习的各种笔记资料,我这差不多来回搞了三个多月,收集整理真的很不容易,其中还有很多自己的一些知识总结。正是因为很麻烦,所以对以上这些学习复习资料感兴趣
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!
eader真正实现加载逻辑
loadBeanDefinitions(beanDefinitionReader);
最后
整理的这些资料希望对Java开发的朋友们有所参考以及少走弯路,本文的重点是你有没有收获与成长,其余的都不重要,希望读者们能谨记这一点。
[外链图片转存中…(img-Lq4b382u-1713654705929)]
[外链图片转存中…(img-mn5yjDqv-1713654705929)]
其实面试这一块早在第一个说的25大面试专题就全都有的。以上提及的这些全部的面试+学习的各种笔记资料,我这差不多来回搞了三个多月,收集整理真的很不容易,其中还有很多自己的一些知识总结。正是因为很麻烦,所以对以上这些学习复习资料感兴趣
网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。
需要这份系统化的资料的朋友,可以添加V获取:vip1024b (备注Java)
[外链图片转存中…(img-omVSaM2A-1713654705930)]
一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!