spring源码解析
提示:这里可以添加系列文章的所有文章的目录,目录需要自己手动添加
第一章 spring源码解析【一】spring整体流程
提示:写完文章后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
提示:这里可以添加本文要记录的大概内容:
本文主要讲述spring整体的流程,细节将在该系列后续文章讲述。
提示:以下是本篇文章正文内容,下面案例可供参考
一、spring是什么?
spring其实就是一个开源应用框架,主要用来降低应用开发的复杂度。它可以集成其他框架,如Spring MVC、Hibernate、MyBatis等。是一个轻量级的Ioc和aop的容器框架。
二、整体流程
1.容器的创建
我们经常使用的容器创建有两种:ClassPathXmlApplicationContext和AnnotationConfigApplicationContext。ClassPathXmlApplicationContext是根据类加载路径的配置文件创建容器的,AnnotationConfigApplicationContext是根据注解创建容器的。首先我们看下ClassPathXmlApplicationContext的依赖图。
1.1ClassPathXmlApplicationContext创建容器的过程:
1.创建一个ClassPathXmlApplicationContext实例,参数选择类加载路径下配置文件。
2.在resources下创建配置文件spring_config.xml,里面使用bean标签注册bean。
3.使用容器的getBean()方法获取bean对象。
1.2ClassPathXmlApplicationContext源码解析
1.根据构造容器创建ClassPathXmlApplicationContext实例。
2.走到核心方法refresh()。该方法是阅读源码最好的入口,它能够帮助Spring完成beanFactory的创建和记载、bean的加载、以及后置处理器的注册等功能。这个方法包括了整个Spring的执行流程和bean的完整生命周期。refresh源码如下:
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 初始化前的准备工作,主要是一些系统属性、环境变量的校验,比如Spring启动需要某些环境变量,可以在这个地方进行设置和校验
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 获取bean工厂,ConfigurableListableBeanFactory是默认的容器,在这一步会完成工厂的创建以及beanDefinition的读取
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 进入prepareBeanFactory前spring以及完成了对配置的解析,Spring的拓展从这里开始
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 留给子类覆盖做拓展,这里一般不做任何处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用所有的BeanFactoryPostProcessors,将结果存入参数beanFactory中
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册BeanPostProcessors,这里只是注册,真正的调用是在doGetBean中
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化消息原,比如国际化
initMessageSource();
// Initialize event multicaster for this context.
// 初始化消息广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 留给子类类初始化其他的bean
onRefresh();
// Check for listener beans and register them.
// 注册监听器
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化剩下的单例bean,在这里才开始真正的对bean进行实例化和初始化
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 完成刷新,通知生命周期处理器刷新过程。
finishRefresh();
}
}
}
1.这里挑些主要的逻辑说说,首先是obtainFreshBeanFactory方法,这方法完成bean工厂的创建,beanDefinition的读取,所以读取spring_config.xml文件就在这个方法里。主要的代码是在refreshBeanFactory中,在refreshBeanFactory方法中Spring会new一个DefaultListableBeanFactory 对象,DefaultListableBeanFactory 是Spring中默认的BeanFactory,接着对这个beanFactory进行定制化处理,调用XmlBeanDefinition的loadBeanDefinitions方法从xml文件中加载所有的beanDefinition并加载到这个DefaultListableBeanFactory 中。而这个this.beanFactory = beanFactory则是将该DefaultListableBeanFactory 设置为全局变量,变成整个Spring容器默认的beanFactory。
2.prepareBeanFactory方法。
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
// 设置SPEL表达式解析器,用来支持Spring的SPEL表达式
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
// 添加属性编辑注册器。例如一个字符串类型的地址需要转换为一个Address对象,可以使用该功能.
// 可参考示例:spring-source-study模块下的com.wb.spring.propertyeditor包下的示例程序
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加bean的后置处理器。此处添加的是Spring自己的后置处理器,用来回调bean所实现的aware接口中的方法.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 下面的ignoreDependencyInterface是用来设置bean工厂中需要忽略的接口
// 可以通过实现EnvironmentAware接口来获取到当前的环境信息Environment。
/**
* 如果将EnvironmentAware接口添加到ignoreDependencyInterface中,则在使用的地方通过@Autowired将会无法正常注入
* 而是需要通过setEnvironment方法进行注入,下面的其他接口都类似.
*/
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
// 可以通过实现EmbeddedValueResolverAware接口来获取String类型值的解析器
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
// 资源加载器,例如使用:@Autowired ResourceLoaderAware aware; 将不会被注入
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
// 事件发布器
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
// 消息资源
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
// 应用的上下文信息
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 注册一些可以自动装配的接口。 当类型为dependencyType时, 注入autowiredValue。为了解决一个类型有多个子类实现时,优先注入那个子类实现的问题。
// 例如下面第一个,当注入类型为BeanFactory时,注入的值为beanFactory,默认为DefaultListableBeanFactory
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
// 当注入类型为ResourceLoader时,注入的值为ApplicationContext
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
// 当注入类型为ApplicationEventPublisher时,注入的值为ApplicationContext
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
// 当注入的类型为ApplicationContext时,注入的值为ApplicationContext.
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
// 增加一个bean的后置处理器,ApplicationListenerDetector
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 如果bean工厂中存在着名称为loadTimeWeaver的bean定义,则给bean工厂中加入LoaderTimeWeaverAwareProcessor后置处理器
// 补充:1、增加对AspectJ的支持,在Java中织入分为3种:(1) 编译期织入; (2) 类加载期织入; (3) 运行期织入。编译期织入指的是在java编译期,
// 采用特殊的编译器,将切面织入到java类中;类加载期织入则指的是通过特殊的类加载器,在字节码加载到JVM时,织入切面;运行期织入则是
// 通过采用cglib或者jdk进行切面的织入。
// 2、aspectJ中提供了两种方式:
// (1) 通过特殊编译器,在编译期,将aspectJ语言编写的切面类织入到java类中;
// (2) 类加载期织入,就是通过下面的LoadTimeWeaving
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 给容器中注册一些与运行环境相关的单实例Bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
// beanName: environment,直接将new出来的Spring内部对象放入到Spring的单实例缓存池中.
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
// beanName: systemProperties 方法:System.getProperties();
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
// beanName: systemEnvironment, 方法:System.getEnv();
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
3.invokeBeanFactoryPostProcessors方法。
在这个方法中主要做三件事:
(1)加载入参的beanFactoryPostProcessors
优先加载BeanDefinitionRegistryPostProcessor类型的,并且会直接调用一次registryProcessor.postProcessBeanDefinitionRegistry(registry)方法,然后分别将BeanDefinitionRegistryPostProcessor类型的和BeanFactoryPostProcessor放入不同类型的容器中。
(2)加载上下文的BeanDefinitionRegistryPostProcessor。
(3)加载上下文的BeanFactoryPostProcessor
和第二步顺序一样也是按照PriorityOrdered、Ordered、和其他的BeanFactoryPostProcessor的顺序加载。
4.finishBeanFactoryInitialization方法
这个方法也是重点,Spring就是在这里完成非懒加载的单例bean的加载的。其中bean的加载和初始化就是在preInstantiateSingletons中,如果getBean的结果为null,Spring就会通过beanName在工厂中拿到对应的beaDefinition,开始加载bean。
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
// 获取所有的beanName
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
// 遍历BeanName
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 如果BeanDefinition符合单例、非懒加载、非抽象的类,就开始加载bean
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 获取bean
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
// FactoryBean是特殊的bean,需要特殊处理。FactoryBean是通过getObject方法获取真正的对象
if (bean instanceof FactoryBean) {
FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged(
(PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
// 获取bean
getBean(beanName);
}
}
}
// Trigger post-initialization callback for all applicable beans...
// 触发所有bean的回调
for (String beanName : beanNames) {
Object singletonInstance = getSingleton(beanName);
if (singletonInstance instanceof SmartInitializingSingleton) {
SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
1.3 AnnotationConfigApplicationContext创建容器过程
1.创建AnnotationConfigApplicationContext实例。
2.AppConfig配置类加扫描路径注解。
3.User类加注解变成bean对象。
1.4 AnnotationConfigApplicationContext源码解析
1.继承关系图
2.构造方法。
3.this方法中创建两个对象,一个reader,一个scanner。
scanner,主要是为了方便在创建完AnnotationConfigApplicationContext对象时手动进行scan。
reader是重点。
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
这个方法注册了6个BeanDefinition,分别会处理不同的注解。这里最重要的是ConfigurationClassPostProcessor这个增强器,因为它会解析@ComponentScan注解,将扫描该注解下的所有@Component等注册注册bean定义。
重点:何时回调后置处理器解析beanDefination。
在refresh方法中的invokeBeanFactoryPostProcessors方法,然后调用postProcessBeanDefinitionRegistry方法,紧接着调用processConfigBeanDefinitions,然后重点关注parser.parse方法,然后是processConfigurationClass,然后是doProcessConfigurationClass,然后是this.componentScanParser.parse,然后是scanner.doScan,该方法就是扫描@ComponentScan指定包下面的注解。
这里就是扫描后生成的BeanDefinitions。
3.refresh方法解析同上。
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。