Spring源码分析之IOC 容器

Spring启动方式:

  启动spring容器有两种方式,分别是通过配置文件的读取启动,通过JavaConfig配置类启动。

  在使用配置文件启动的时候,我们就需要使用ClassPathXmlApplicationContext("xx.xml")来构建容器,并初始化bean。

1 public class Test1 {
2     public static void main(String[] args) {
3         ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
4         IndexService service = (IndexService) context.getBean("service");
5         service.query();
6     }
7 }

  在使用JavaConfig配置类启动的时候,我们需要使用AnnotationConfigApplicationContext("xx.class")来构建容器,并初始化bean。

1 public class Test {
2     public static void main(String[] args) {
3         //把spring所有的前提环境准备好了,包括spring容器还有类的实例化都完成了。
4         AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyAnnotation.class);
5         IndexService service = (IndexService)context.getBean("service");
6         service.query();
7     }
8 }

  进入AnnotationConfigApplicationContext类中,查看构造方法。

 1 /**
 2      * 这个构造方法需要传入一个被Javaconfig注解过的配置类
 3      * 然后会把这个被注解了的配置类通过注解读取器读取后进行解析
 4      * @param annotatedClasses
 5      */
 6     public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
 7         //这里由于它有父类,故而会先调用父类的构造方法,然后才会调用自己的构造方法,
 8         //在自己的构造方法中初始化一个读取器和扫描器
 9         this();
10         //注册单个bean给容器,比如有新加的类可以使用这个方法
11         //但是注册之后需要手动调用refresh()方法去触发容器解析注解
12         register(annotatedClasses);
13         refresh();
14     }

  进入this()方法,查看自己的构造方法

 1 public AnnotationConfigApplicationContext() {
 2         /**
 3          * 创建一个读取注解的Bean定义读取器
 4          * 什么是Bean定义?BeanDefinition
 5          * BeanDefinition这个类是描述springBean对象的类。
 6          */
 7         this.reader = new AnnotatedBeanDefinitionReader(this);
 8         /**
 9          * 创建一个扫描器,扫描所有加了注解的类
10          */
11         this.scanner = new ClassPathBeanDefinitionScanner(this);
12     }

  进入register()方法,忽略掉封装方法,直接进入AnnotatedBeanDefinitionReader类中的doRegisterBean()方法:

 1 <T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
 2             @Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
 3 
 4         AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
 5         if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
 6             return;
 7         }
 8 
 9         abd.setInstanceSupplier(instanceSupplier);
10         ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
11         abd.setScope(scopeMetadata.getScopeName());
12         String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
13 
14         AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
15         /**
16          * 对属性进行判断
17          */
18         if (qualifiers != null) {
19             for (Class<? extends Annotation> qualifier : qualifiers) {
20                 if (Primary.class == qualifier) {
21                     abd.setPrimary(true);
22                 }
23                 else if (Lazy.class == qualifier) {
24                     abd.setLazyInit(true);
25                 }
26                 else {
27                     abd.addQualifier(new AutowireCandidateQualifier(qualifier));
28                 }
29             }
30         }
31         for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
32             customizer.customize(abd);
33         }
34 
35         BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
36         definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
37         /**
38          * 把处理后的bean当做参数,进行注册
39          */
40         BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
41     }

  进入BeanDefinitionReaderUtils类中的registerBeanDefinition()方法:

 1 /**
 2      * 向给定的bean工厂注册给定的bean定义
 3      * @param definitionHolder
 4      * @param registry
 5      * @throws BeanDefinitionStoreException
 6      */
 7     public static void registerBeanDefinition(
 8             BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
 9             throws BeanDefinitionStoreException {
10 
11         // Register bean definition under primary name.
12         // 把beanName作为主名,在bean工厂中注册
13         String beanName = definitionHolder.getBeanName();
14         //通过DefaultListableBeanFactory工厂进行注册
15         registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
16 
17         // Register aliases for bean name, if any.
18         // 对别名进行处理
19         String[] aliases = definitionHolder.getAliases();
20         if (aliases != null) {
21             for (String alias : aliases) {
22                 registry.registerAlias(beanName, alias);
23             }
24         }
25     }

  进入DefaultListableBeanFactory类的registerBeanDefinition()方法进行注册。

    /** Map of bean definition objects, keyed by bean name. */

    private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);

    /** List of bean definition names, in registration order. */

    private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

 1 @Override
 2     public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
 3             throws BeanDefinitionStoreException {
 4 
 5         Assert.hasText(beanName, "Bean name must not be empty");
 6         Assert.notNull(beanDefinition, "BeanDefinition must not be null");
 7 
 8         if (beanDefinition instanceof AbstractBeanDefinition) {
 9             try {
10                 ((AbstractBeanDefinition) beanDefinition).validate();
11             }
12             catch (BeanDefinitionValidationException ex) {
13                 throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
14                         "Validation of bean definition failed", ex);
15             }
16         }
17 
18         BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
19         if (existingDefinition != null) {
20             if (!isAllowBeanDefinitionOverriding()) {
21                 throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
22             }
23             else if (existingDefinition.getRole() < beanDefinition.getRole()) {
24                 // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
25                 if (logger.isInfoEnabled()) {
26                     logger.info("Overriding user-defined bean definition for bean '" + beanName +
27                             "' with a framework-generated bean definition: replacing [" +
28                             existingDefinition + "] with [" + beanDefinition + "]");
29                 }
30             }
31             else if (!beanDefinition.equals(existingDefinition)) {
32                 if (logger.isDebugEnabled()) {
33                     logger.debug("Overriding bean definition for bean '" + beanName +
34                             "' with a different definition: replacing [" + existingDefinition +
35                             "] with [" + beanDefinition + "]");
36                 }
37             }
38             else {
39                 if (logger.isTraceEnabled()) {
40                     logger.trace("Overriding bean definition for bean '" + beanName +
41                             "' with an equivalent definition: replacing [" + existingDefinition +
42                             "] with [" + beanDefinition + "]");
43                 }
44             }
45             this.beanDefinitionMap.put(beanName, beanDefinition);
46         }
47         else {
48             if (hasBeanCreationStarted()) {
49                 // Cannot modify startup-time collection elements anymore (for stable iteration)
50                 synchronized (this.beanDefinitionMap) {
51                     this.beanDefinitionMap.put(beanName, beanDefinition);
52                     List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
53                     updatedDefinitions.addAll(this.beanDefinitionNames);
54                     updatedDefinitions.add(beanName);
55                     this.beanDefinitionNames = updatedDefinitions;
56                     if (this.manualSingletonNames.contains(beanName)) {
57                         Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
58                         updatedSingletons.remove(beanName);
59                         this.manualSingletonNames = updatedSingletons;
60                     }
61                 }
62             }
63             else {
64                 // Still in startup registration phase
65                 this.beanDefinitionMap.put(beanName, beanDefinition);
66                 this.beanDefinitionNames.add(beanName);
67                 this.manualSingletonNames.remove(beanName);
68             }
69             this.frozenBeanDefinitionNames = null;
70         }
71 
72         if (existingDefinition != null || containsSingleton(beanName)) {
73             resetBeanDefinition(beanName);
74         }
75     }

  到这里,bean注册完成了,然后调用refresh()方法进行实例化。

 1 @Override
 2     public void refresh() throws BeansException, IllegalStateException {
 3         synchronized (this.startupShutdownMonitor) {
 4             // Prepare this context for refreshing.
 5             // 准备工作,包括设置启动时间,是否激活标识位,
 6             // 初始化属性源(property source)设置
 7             prepareRefresh();
 8 
 9             // Tell the subclass to refresh the internal bean factory.
10             // 通过子类来获取之前注册了bean的容器工厂beanFactory
11             // 这里我们是获得DefaultListableBeanFactory这个工厂类
12             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
13 
14             // Prepare the bean factory for use in this context.
15             prepareBeanFactory(beanFactory);
16 
17             try {
18                 // Allows post-processing of the bean factory in context subclasses.
19                 postProcessBeanFactory(beanFactory);
20 
21                 // Invoke factory processors registered as beans in the context.
22                 invokeBeanFactoryPostProcessors(beanFactory);
23 
24                 // Register bean processors that intercept bean creation.
25                 registerBeanPostProcessors(beanFactory);
26 
27                 // Initialize message source for this context.
28                 initMessageSource();
29 
30                 // Initialize event multicaster for this context.
31                 initApplicationEventMulticaster();
32 
33                 // Initialize other special beans in specific context subclasses.
34                 onRefresh();
35 
36                 // Check for listener beans and register them.
37                 registerListeners();
38 
39                 // Instantiate all remaining (non-lazy-init) singletons.
40                 finishBeanFactoryInitialization(beanFactory);
41 
42                 // Last step: publish corresponding event.
43                 finishRefresh();
44             }
45 
46             catch (BeansException ex) {
47                 if (logger.isWarnEnabled()) {
48                     logger.warn("Exception encountered during context initialization - " +
49                             "cancelling refresh attempt: " + ex);
50                 }
51 
52                 // Destroy already created singletons to avoid dangling resources.
53                 destroyBeans();
54 
55                 // Reset 'active' flag.
56                 cancelRefresh(ex);
57 
58                 // Propagate exception to caller.
59                 throw ex;
60             }
61 
62             finally {
63                 // Reset common introspection caches in Spring's core, since we
64                 // might not ever need metadata for singleton beans anymore...
65                 resetCommonCaches();
66             }
67         }
68     }
原文地址:https://www.cnblogs.com/wk-missQ1/p/12443177.html