Spring源码解析(一)AnnotationConfigApplicationContext实例化,注册方法

编程入门 行业动态 更新时间:2024-10-25 08:17:32

Spring<a href=https://www.elefans.com/category/jswz/34/1770099.html style=源码解析(一)AnnotationConfigApplicationContext实例化,注册方法"/>

Spring源码解析(一)AnnotationConfigApplicationContext实例化,注册方法

解析Spring源码,首先从第一行代码看起
Config.java配置类

@Configuration
@ComponentScan("com.spring")
public class Config {
}

Test.java

public class Test {public static void main(String[] args) {AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(Config.class);}
}

要先从spring环境AnnotationConfigApplicationContext说起,首先看构造方法

	public AnnotationConfigApplicationContext(Class<?>... componentClasses) {//无参构造方法this();//注册方法register(componentClasses);//初始化环境方法,后面讲refresh();}

看到无参构造方法:
由于AnnotationConfigApplicationContext继承了GenericApplicationContext,所以应该先看GenericApplicationContext的无参构造方法:

	private final DefaultListableBeanFactory beanFactory;public GenericApplicationContext() {this.beanFactory = new DefaultListableBeanFactory();}

可以看出GenericApplicationContext有beanFactory的属性,这里实例化了DefaultListableBeanFactory实现类。DefaultListableBeanFactory就是我们平时说的bean工厂,里面包含许多属性,这里可以用一张图说明:

GenericApplicationContext的父类只是处理类加载器等等,这里先不详解。

	private final AnnotatedBeanDefinitionReader reader;private final ClassPathBeanDefinitionScanner scanner;public AnnotationConfigApplicationContext() {//实例化AnnotatedBeanDefinitionReaderthis.reader = new AnnotatedBeanDefinitionReader(this);//这个scanner主要为了在外部使用到scanner(供程序员使用),// 真正包的扫描不是用的这个,后面会证实this.scanner = new ClassPathBeanDefinitionScanner(this);}

可以看到创建了一个AnnotatedBeanDefinitionReader,这里详细说明一下这个reader,主要作用是一个BeanDefinition读取器。BeanDefinition也会在后面详细说明,是Spring中用来描述Bean的类。对比一下,java中用来描述一个类用Class类,而Spring中描述一个bean用BeanDefinition,后面简称bd。
AnnotatedBeanDefinitionReader的主要作用是转换一个Class为bd,但是这个对象只能读取加了注解的类。用图表示大概如下:

然后看new AnnotatedBeanDefinitionReader(this);方法,this即AnnotationConfigApplicationContext

	public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {this(registry, getOrCreateEnvironment(registry));}

由此可以看出,AnnotationConfigApplicationContext也是BeanDefinitionRegistry,BeanDefinitionRegistry 顾名思义就是一个bd的注册器,就是将bd注册到工厂中的组件
继续分析AnnotatedBeanDefinitionReader的构造方法:

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {//这里主要判断registry和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);//进行Spring初始bean的注入AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);}

进入registerAnnotationConfigProcessors方法,这个方法比较长,不过作用比较单一,就是将一些初始的类,主要是后置处理器的类放入到beanFactory中。ConfigurationClassPostProcessor,AutowiredAnnotationBeanPostProcessor等等

	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;}

所以程序走到这一步,可以看下我们环境中一共有几个bean

特殊标注的这个后置处理器也是我们将要大篇幅讲的类,也是Spring中一个非常牛逼的类。
到这里,AnnotationConfigApplicationContext的主要组件就实例化好了,并且在beanFactory中已经有了几个bean。

下面来介绍一下registry方法:

@Overridepublic void register(Class<?>... componentClasses) {//判断传入的类是不是空Assert.notEmpty(componentClasses, "At least one component class must be specified");//调用regsiter方法this.reader.register(componentClasses);}

直接进入方法:

public void register(Class<?>... componentClasses) {//componentClasses可以是多个for (Class<?> componentClass : componentClasses) {registerBean(componentClass);}}

一直跟进,发现到了org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean这个方法,

<T> void doRegisterBean(Class<T> beanClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {//BeanDefinition的实现类AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {return;}abd.setInstanceSupplier(instanceSupplier);//通过解析器得到bd的元数据ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);//得到scope生命周期abd.setScope(scopeMetadata.getScopeName());//得到beannameString beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));//用来设置其他属性,@Lazy,@DependsOn,@Role,@DescriptionAnnotationConfigUtils.processCommonDefinitionAnnotations(abd);//根据注解得到这些属性if (qualifiers != null) {for (Class<? extends Annotation> qualifier : qualifiers) {if (Primary.class == qualifier) {abd.setPrimary(true);}else if (Lazy.class == qualifier) {abd.setLazyInit(true);}else {abd.addQualifier(new AutowireCandidateQualifier(qualifier));}}}//不知道,不重要for (BeanDefinitionCustomizer customizer : definitionCustomizers) {customizer.customize(abd);}//BeanDefinitionHolder是对bd和beanName的封装,方便传参BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);//设置生命周期definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);//进行注册BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);}
public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)throws BeanDefinitionStoreException {// Register bean definition under primary name.//得到beanNameString beanName = definitionHolder.getBeanName();//注册方法registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());// Register aliases for bean name, if any.//注册这个bean别名String[] aliases = definitionHolder.getAliases();if (aliases != null) {for (String alias : aliases) {registry.registerAlias(beanName, alias);}}}

最终进入org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition

if (hasBeanCreationStarted()) {// Cannot modify startup-time collection elements anymore (for stable iteration)//处理并发,用synchronizedsynchronized (this.beanDefinitionMap) {this.beanDefinitionMap.put(beanName, beanDefinition);List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);//更新操作updatedDefinitions.addAll(this.beanDefinitionNames);updatedDefinitions.add(beanName);this.beanDefinitionNames = updatedDefinitions;removeManualSingletonName(beanName);}}else {// Still in startup registration phase//没被创建好,这里进行注册,将beanName,beanDefinition放入到map中,将beanName放入到listthis.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);removeManualSingletonName(beanName);}

其实注册的过程非常简单,只需要更新map和list。这一篇主要讲了AnnotationConfigApplicationContext的实例化过程和向beanFactory注册bean的registry方法,下面一篇开始介绍初始化环境的过程。

更多推荐

Spring源码解析(一)AnnotationConfigApplicationContext实例化,注册方法

本文发布于:2024-03-12 22:51:23,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1732596.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:源码   实例   方法   Spring   AnnotationConfigApplicationContext

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!