本文主要分析spring的初实话流程:
先介绍下beandefinition关系图
这里简单介绍:
BeanDefinition简称:bd
RootBeanDefinition这种类型的一般是spring自己开发设置的类型;
ScannedGenericBeanDefinition这种事通过注解扫描出来的,一般为程序员开发的类;
AnnotatedGenericBeanDefinition这种一般是调用register(class)方法里注册bd产生的类型;
这三种,后续讲的当中都会标记一下;
开始进入正题:
分析spring初始化过程跟踪下去:
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
本篇文章主要分析this()方法:
首先会执行父类的构造方法:
public GenericApplicationContext() {
this.beanFactory = new DefaultListableBeanFactory();
}
给父类初始化了beaFactory.
接着回到子类的this方法:
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
第一行this.reader = new AnnotatedBeanDefinitionReader(this);实例化
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
this(registry, getOrCreateEnvironment(registry));
}
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.为自己的this.registry=registry;
这里的registry=AnnotationConfigApplicationContext;
2. this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
用来处理@Conditionalditional注解;
3.AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
往AnnotationConfigApplicationContext的
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
这个map中设置5个BeanDefinition,这五个都是RootBeanDefinition的子类
作用:
ConfigurationClassPostProcessor是一个工厂后置处理器,这个后置处理器非常重要,基本上类上面的注解都在这里面判断并解析,spring的包扫描也在里面完成;
AutowiredAnnotationBeanPostProcessor处理@Autowired的,它是一个bean的后置处理器,在bean的属性注入的时候会用到;
CommonAnnotationBeanPostProcessor处理一些公共注解的,它是一个bean的后置处理器,可以处理@PostConstruct和@PreDestroy还有@Resource等;
DefaultEventListenerFactory,EventListenerMethodProcessor这两个其中:
EventListenerMethodProcessor中会调用DefaultEventListenerFactory的方法,注册的具体实现是由DefaultEventListenerFactory处理;(作用后续补上)
其他都说有6个为什么这里只有五个呢?
PersistenceAnnotationBeanPostProcessor这个处理器是否加载看你是否引入了所以需要引入spring-orm的包,对jpa的处理,本例子中未引入依赖所以只加载五个;
接下来分析:
this.scanner = new ClassPathBeanDefinitionScanner(this);
跟踪下去到如下方法:
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
Environment environment, @Nullable ResourceLoader resourceLoader) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
this.registry = registry;
if (useDefaultFilters) {
registerDefaultFilters();
}
setEnvironment(environment);
setResourceLoader(resourceLoader);
}
这里的registry,resourceLoader都是AnnotationConfigApplicationContext这个类的实例;
上面完成了:
1,初始化registry;
private final List<TypeFilter> includeFilters = new LinkedList<>();
2.往其父类ClassPathScanningCandidateComponentProvider的
includeFilters 加入元注解@Component,需要注意的是@Repository、@Service、@Controller里面都标注了@Component。很好理解,扫描的时候用includeFilters 去过滤时,会找到并处理这4个含有@Component注解的类。
3,设置父类ClassPathScanningCandidateComponentProvider的environment属性该对象实例是
this.environment = new StandardEnvironment();
4,设置resourceLoader属性对象就是AnnotationConfigApplicationContext的实例;
到这里就结束了整个this()方法;
总结:
通过this()方法后AnnotationConfigApplicationContext的实例里有几个重要对象:
1. this.beanFactory = new DefaultListableBeanFactory();
这个对象目前我们知道有个beanDefinitionMap属性用来存储beanDefinitio对象,目前有5个对象;
2. this.reader = new AnnotatedBeanDefinitionReader(this);
这个reader对象可以认为是把java对象转成BeanDefinition对象然后将其存到beanFactory 的beanDefinitionMap中;
3, this.scanner = new ClassPathBeanDefinitionScanner(this);
这个sacnner对象,顾名思义是用来扫描包路径下的所有的文件转成
BeanDefinition对象(根据includeFilters 这个集合里的过滤是否可以转为BeanDefinition,如之前讲的加了个@Componet注解的Filter,所以如果扫描的包下的class文件有这个注解就会转成BeanDefinition);如我们开发中常用@ComponentScan的注解;其实就是交给这个类来处理.想了解可以看ClassPathBeanDefinitionScanner的scan()方法;