spring注解版构造函数的流程解析
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
this();
register(componentClasses);
refresh();
}
今天要讲的就是this这个方法
一。this构造函数解析
public AnnotationConfigApplicationContext() {
//TODO 每一个类的构造函数都会调用父类的构造函数,可能不会写super()显示调用,但是都会调用,这里使没有显示调用,隐式调用父类的方法
/**
* 调用父类以及父类的父类的构造器,目前主要是创建一个DefaultListableBeanFactory 的bean工厂,还有就是获取类加载器(默认当前线程的类加载器)
*/
super();
/**
* beanDefinitionReader接口,读取配置文件,转换成beanDefinition,这里是将标有@Service,@Component,等等注解的类的一些信息转换成beanDefinition类
* 该类记录了指定JavaBean的一些信息,它存储了 bean 对象的所有特征信息,如是否单例,是否懒加载,factoryBeanName 等
* 那么就需要一个注解配置读取器,来读取这些信息
*/
this.reader = new AnnotatedBeanDefinitionReader(this);
/**
* 如果我想对用户指定的包目录进行扫描查找 bean 对象,那么还需要一个路径扫描器BeanDefinitionScanner
* 专门用来扫描标有@Service,@Component 等等注解的JavaBean,然后通过AnnotatedBeanDefinitionReader来读取信息
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
- 这里首先声明一下,在Java中调用子类的构造方法时,也会显式或者隐式父类的构造方法
- 由于spring里面层级结构非常复杂,一个类有很多层的父类,就是父类有父类,父类的父类还有父类,等等,这时候如果想查看一个类的构造方法到底进行了那些操作,就必须一层一层的查看父类的构造函数(可能父类没有构造函数,父类还有父类,这时候编辑器会自动添加一个无参构造器,这个无参构造器也会调用父类的构造器,不要忘了,不然,有时候有些变量的值你都不知道什么时候出现赋值的)
- 所以我们一个一个的看父类的构造函数
1.1 GenericApplicationContext类构造函数
public GenericApplicationContext() {
//todo,隐式调用父类的构造方法,去看看
super();
/**
* AnnotationConfigApplicationContext类首先通过调用父类构造器创建一个beanFactory工厂,专门用来生成bean对象
*/
this.beanFactory = new DefaultListableBeanFactory();
}
这个构造函数主要式生成一个默认的bean工厂,用于生产bean,以及一些初始化属性
哎呀,算了,直接看看类关系图,其实这个this方法主要是进行一些初始化,比如资源加载器初始化,beanfactory初始化
AnnotationConfigApplicationContext的父类的父类关系
DefaultListableBeanFactory的父类构造函数关系
总之到this构造函数结束的时候,创建了一个beanfactory(默认的)以及资源加载器,还有更细节的暂时用不到,还有就是 AnnotationConfigApplicationContext 和bean工厂的一些属性的初始化操作
1.2 AnnotatedBeanDefinitionReader 读取JavaBean 的读取器的初始化操作
调用一个参数的构造方法
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
/**
* getOrCreateEnvironment(registry) 主要是创建环境变量对象,Environment,该变量包含一个spring项目所在的系统的信息以及属性
* 下面就是调用其他构造方法,进行构造,最主要的是给beanfactory创建6 个后置处理器
*/
this(registry, getOrCreateEnvironment(registry));
}
getOrCreateEnvironment(registry)
这个方法主要是创建一个Environment 环境变量对象,默认创建一个StandardEnvironment对象,该对象最主要的是获取系统的环境变量,就是将
System.getProperties()
System.getenv()
这两个属性设置在StandardEnvironment对象中
再调用两个参数的构造函数
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);
/**
* 注册6个后置处理器
*/
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
上面这一步最主要的就是最后一步,向spring的beanfactory注册6个后置处理器
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//todo
/**
* 获取beanfactory
*/
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());
}
}
/**
* 设置BeanDefinitionHolder,主要是记录 beandefinition的别名,名字和JavaBean,这里主要是后置处理器
*/
Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
/**
* org.springframework.context.annotation.internalConfigurationAnnotationProcessor
* 向beanfactory注册org.springframework.context.annotation.ConfigurationClassPostProcessor类
* 顺便设置该类的处理类BeanDefinitionHolder
*/
/**
* @Configuration 注解的解析器,即BeanFactoryPostProcessor,专门 用于处理@Configuration注解的工厂的后置处理器
* https://www.cnblogs.com/jiaoqq/p/7678037.html
*/
//todo
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));
}
/**
* 注册org.springframework.context.annotation.internalAutowiredAnnotationProcessor
* 对应的类org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor
*/
/**
* 注册BeanPostProcessor 后置处理器,在JavaBean初始化前后调用,主要是处理@Autowired注解
* https://www.cnblogs.com/lzeffort/p/7748611.html
*/
//todo
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));
}
/**
* org.springframework.context.annotation.internalCommonAnnotationProcessor
* org.springframework.context.annotation.CommonAnnotationBeanPostProcessor
*/
/**
* 注册BeanPostProcessor,处理@EJB,@WebServiceRef,@Resource,@PreDestroy,@PostConstruct 注解的处理
* https://blog.csdn.net/shenchaohao12321/article/details/81235571
*/
//todo
// 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));
}
/**
* org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor
*
*/
// 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));
}
/**
* org.springframework.context.event.internalEventListenerProcessor
* org.springframework.context.event.EventListenerMethodProcessor
*/
/**
* 对于@EventListener 注解的处理,BeanFactoryPostProcessor
* https://www.cnblogs.com/elvinle/p/13298007.html
*/
//todo
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));
}
/**
* org.springframework.context.event.internalEventListenerFactory
* org.springframework.context.event.DefaultEventListenerFactory
*/
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;
}
执行完上面这一步,spring容器中的beanDefinitionMap就会出现 5 个beanDefinition。
beanDefinition 只是记录某个JavaBean的信息,并没有实例化,所以现在单例池中还没有对象
1.3 ClassPathBeanDefinitionScanner 扫描
/**
* 如果我想对用户指定的包目录进行扫描查找 bean 对象,那么还需要一个路径扫描器BeanDefinitionScanner
* 专门用来扫描标有@Service,@Component 等等注解的JavaBean,然后通过AnnotatedBeanDefinitionReader来读取信息
*/
//todo
/**
* 这里只是创建一个扫描器,主要是扫描@component,注解的类
*/
/**
* 主要是添加默认的要扫描的标有指定注解的类,@component,和 @javax.annotation.ManagedBean(JSR-250)
* @javax.inject.Named(JSR-330),当然@service都是继承@component注解,所以不需要加@service等等
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
是扫描@component,注解的类
/
/*
* 主要是添加默认的要扫描的标有指定注解的类,@component,和 @javax.annotation.ManagedBean(JSR-250)
* @javax.inject.Named(JSR-330),当然@service都是继承@component注解,所以不需要加@service等等
*/
this.scanner = new ClassPathBeanDefinitionScanner(this);
这一步其实没什么只是创建一个bean扫描器,扫描指定注解的类
主要需要扫描 三个注解,@component
,@javax.inject.Named,@javax.annotation.ManagedBean
主要是向org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#includeFilters这个集合中添加这三个注解的Class,供后面解析扫描,然后放到spring容器中,**当然自己也可以自定义注解,然后放到这个集合中**