Spring 源码之获取Bean
Spring源码解读之获取Bean
上一篇文章我们搭建了源码环境,并使用了Spring方法获取了Bean,我们下边来回顾下代码
package com.pv3;
import com.pv3.config.AnnotationConfig;
import com.pv3.utils.TestUtil;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class Test {
public static void main(String[] args) {
//启动Spring
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AnnotationConfig.class);
TestUtil bean = annotationConfigApplicationContext.getBean(TestUtil.class);
bean.hello();
}
}
Spring初始化做了什么?
AnnotationConfigApplicationContext annotationConfigApplicationContext = new AnnotationConfigApplicationContext(AnnotationConfig.class);
1、AnnotationConfigApplicationContext
实例化做了如下事情:
1、执行AnnotationConfigApplicationContext
父类org.springframework.context.support.GenericApplicationContext#GenericApplicationContext()
的构造函数
public GenericApplicationContext() {
// 暂且实例化下啥也没有干
this.beanFactory = new DefaultListableBeanFactory();
}
2、执行GenericApplicationContext
父类构造函数org.springframework.context.support.AbstractApplicationContext#AbstractApplicationContext()
public AbstractApplicationContext() {
this.resourcePatternResolver = getResourcePatternResolver();
}
3、执行GenericApplicationContext
父类org.springframework.context.support.AbstractApplicationContext#getResourcePatternResolver
protected ResourcePatternResolver getResourcePatternResolver() {
// 这里啥也没有返回默认Null
return new PathMatchingResourcePatternResolver(this);
}
4、执行AbstractApplicationContext
父类org.springframework.core.io.DefaultResourceLoader#DefaultResourceLoader()
构造函数
public DefaultResourceLoader() {
// 这个是一个线程安全的加载类,AppClassLoader应用类加载器,又称为系统类加载器,负责在JVM启动时,加载来自在命令java中的classpath或者java.class.path系统属性或者CLASSPATH操作系统属性所指定的JAR类包和类路径.实际使用的是System.getSecurityManager();获取的默认加载器。
this.classLoader = ClassUtils.getDefaultClassLoader();
}
5、初始化了一堆变量,有几个原子类,和日志类,还有定义了几个类名加变量。
6、通过类加载器加载JSR-*330*加载失败就返回一个空,但是这个是Spring一类必须的!
7、执行org.springframework.context.annotation.AnnotatedBeanDefinitionReader
构造函数
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);
}
备注:
1、registry
是之前调用构造函数传进来的org.springframework.context.annotation.AnnotationConfigApplicationContext
2、environment
是getOrCreateEnvironment()
返回的StandardEnvironment
实例
3、初始化了AnnotationConfigApplicationContext的工厂DefaultListableBeanFactory
4、使用了前边说的默认资源加载器。
5、AnnotationConfigApplicationContext
资源加载。
6、加载检查一堆注解!检查类解析器的bean,AutoWired注解解析器,注册解析@Required 注解的处理器, 解析JSR250规范的注解,检查是否支持jpa,@EventListener的注解。
new ClassPathBeanDefinitionScanner(this);
创建类路径下的bean定义扫描器
自此Bean注册获取也就讲完!AnnotationConfigApplicationContext就是干这个用的!