• Spring源码分析--IOC流程


    代码地址:https://github.com/LoveWK/mySpring/tree/master/myIocDemo

    1.创建MyAnnotation类

    1 @Configuration//java配置类注解
    2 @ComponentScan("com.wk")//设置扫描包的路径
    3 public class MyAnnotation {
    4 }

    2.创建Test类

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

    3.点击进入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     }

      3.1先进入this()查看此类的构造方法:

     1 public AnnotationConfigApplicationContext() {
     2         /**
     3          * 创建一个读取注解的Bean定义读取器
     4          * 什么是Bean定义?BeanDefinition
     5          * BeanDefinition这个类是描述springBean对象的类。
     6          */
     7         this.reader = new AnnotatedBeanDefinitionReader(this);
     8         /**
     9          * 创建一个扫描器,扫描所有加了注解的类
    10          * 可以用来扫描包或者类,继而转成BeanDefinition
    11          * 但是我们在自己项目中使用自动扫描注解的时候,扫描包的工作不是在这个scanner对象中完成的
    12          * 这里的scanner对象仅仅是为了程序员能够在外部调用AnnotationConfigApplicationContext对象的scan方法
    13          */
    14         this.scanner = new ClassPathBeanDefinitionScanner(this);
    15     }

      其中this.reader = new AnnotatedBeanDefinitionReader(this);方法是比较重要的,它注册了spring中的6个BeanDefinition类,其中最重要的是ConfigurationClassPostProcessor类。

      AnnotatedBeanDefinitionReader(this)-->AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry)-->

    this(registry, getOrCreateEnvironment(registry))-->AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment)-->AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry)-->

    registerAnnotationConfigProcessors(BeanDefinitionRegistry registry)-->registerAnnotationConfigProcessors(registry, null)-->

     1 public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
     2             BeanDefinitionRegistry registry, @Nullable Object source) {
     3 
     4         DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
     5         if (beanFactory != null) {
     6             if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
     7                 beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
     8             }
     9             if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
    10                 beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
    11             }
    12         }
    13 
    14         Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    15 
    16         if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    17             RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
    18             def.setSource(source);
    19             beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    20         }
    21 
    22         if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    23             RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
    24             def.setSource(source);
    25             beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    26         }
    27 
    28         // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
    29         if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    30             RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
    31             def.setSource(source);
    32             beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    33         }
    34 
    35         // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
    36         if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    37             RootBeanDefinition def = new RootBeanDefinition();
    38             try {
    39                 def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
    40                         AnnotationConfigUtils.class.getClassLoader()));
    41             }
    42             catch (ClassNotFoundException ex) {
    43                 throw new IllegalStateException(
    44                         "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
    45             }
    46             def.setSource(source);
    47             beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    48         }
    49 
    50         if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
    51             RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
    52             def.setSource(source);
    53             beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    54         }
    55 
    56         if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
    57             RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
    58             def.setSource(source);
    59             beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    60         }
    61 
    62         return beanDefs;
    63     }

    4.调用register()方法

    5.进入refresh()方法,这里才是最重要的:这个方法的实现在AbstractApplicationContext类中。

     1 public void refresh() throws BeansException, IllegalStateException {
     2         synchronized (this.startupShutdownMonitor) {
     3             // Prepare this context for refreshing.
     4             // 准备工作,包括设置启动时间,是否激活标识位,
     5             // 初始化属性源(property source)设置
     6             prepareRefresh();
     7 
     8             // Tell the subclass to refresh the internal bean factory.
     9             // 通过子类来获取之前注册了bean的容器工厂beanFactory
    10             // 这里我们是获得DefaultListableBeanFactory这个工厂类
    11             ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    12 
    13             // Prepare the bean factory for use in this context.
    14             // 准备工厂
    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                 // 在spring的环境中去执行已经被注册的factory processors
    23                 // 设置执行自定义的ProcessorsBeanFactory和spring内部自己定义的
    24                 // 其实就是执行spring内部的ConfigurationClassPostProcessor这个类
    25                 invokeBeanFactoryPostProcessors(beanFactory);
    26 
    27                 // Register bean processors that intercept bean creation.
    28                 registerBeanPostProcessors(beanFactory);
    29 
    30                 // Initialize message source for this context.
    31                 initMessageSource();
    32 
    33                 // Initialize event multicaster for this context.
    34                 initApplicationEventMulticaster();
    35 
    36                 // Initialize other special beans in specific context subclasses.
    37                 onRefresh();
    38 
    39                 // Check for listener beans and register them.
    40                 registerListeners();
    41 
    42                 // Instantiate all remaining (non-lazy-init) singletons.
    43                 finishBeanFactoryInitialization(beanFactory);
    44 
    45                 // Last step: publish corresponding event.
    46                 finishRefresh();
    47             }
    48 
    49             catch (BeansException ex) {
    50                 if (logger.isWarnEnabled()) {
    51                     logger.warn("Exception encountered during context initialization - " +
    52                             "cancelling refresh attempt: " + ex);
    53                 }
    54 
    55                 // Destroy already created singletons to avoid dangling resources.
    56                 destroyBeans();
    57 
    58                 // Reset 'active' flag.
    59                 cancelRefresh(ex);
    60 
    61                 // Propagate exception to caller.
    62                 throw ex;
    63             }
    64 
    65             finally {
    66                 // Reset common introspection caches in Spring's core, since we
    67                 // might not ever need metadata for singleton beans anymore...
    68                 resetCommonCaches();
    69             }
    70         }
    71     }

      5.1点击prepareBeanFactory()方法

        这个方法中比较重要的是addBeanPostProcessor()方法,添加一个后置管理器。

     1 /**
     2      * 配置其标准特征,比如上下文的加载器,ClassLoader和post-processors回调
     3      * @param beanFactory
     4      */
     5     protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
     6         // Tell the internal bean factory to use the context's class loader etc.
     7         beanFactory.setBeanClassLoader(getClassLoader());
     8         // bean的表达式解析
     9         beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
    10         // 注册属性编辑器,对象与string类型的转换
    11         beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
    12 
    13         // Configure the bean factory with context callbacks.
    14         // 添加一个后置管理器
    15         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
    16         // 忽略一些接口的实现,不自动注入
    17         beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
    18         beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
    19         beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
    20         beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
    21         beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
    22         beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
    23 
    24         // BeanFactory interface not registered as resolvable type in a plain factory.
    25         // MessageSource registered (and found for autowiring) as a bean.
    26         beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
    27         beanFactory.registerResolvableDependency(ResourceLoader.class, this);
    28         beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
    29         beanFactory.registerResolvableDependency(ApplicationContext.class, this);
    30 
    31         // Register early post-processor for detecting inner beans as ApplicationListeners.
    32         beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
    33 
    34         // Detect a LoadTimeWeaver and prepare for weaving, if found.
    35         if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
    36             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    37             // Set a temporary ClassLoader for type matching.
    38             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    39         }
    40 
    41         // Register default environment beans.
    42         // 意思是如果自定义的Bean中没有名为"systermProperties"和"systermEnvironment"的bean
    43         // 则注册两个bean,key为"systermProperties"和"systermEnvironment",value为Map
    44         // 这两个bean就是一些系统配置和系统环境信息
    45         if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
    46             beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
    47         }
    48         if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
    49             beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
    50         }
    51         if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
    52             beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
    53         }
    54     }

      5.2点击invokeBeanFactoryPostProcessors()方法,进入

     1 protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
     2         // 这个地方需要注意getBeanFactoryPostProcessors()是获取自己继承BeanFactoryPostProcessors接口实现的类
     3         // 需要我们在AnnotationConfigApplicationContext实例对象中通过context.addBeanFactoryPostProcessor()来添加自己定义的类
     4         PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
     5 
     6         // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
     7         // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
     8         if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
     9             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
    10             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
    11         }
    12     }

        5.2.1点击invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());方法进入

      1 public static void invokeBeanFactoryPostProcessors(
      2             ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
      3 
      4         // Invoke BeanDefinitionRegistryPostProcessors first, if any.
      5         Set<String> processedBeans = new HashSet<>();
      6 
      7         if (beanFactory instanceof BeanDefinitionRegistry) {
      8             BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
      9             List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
     10             List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
     11             //  自定义的BeanFactoryPostProcessors
     12             for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
     13                 if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
     14                     BeanDefinitionRegistryPostProcessor registryProcessor =
     15                             (BeanDefinitionRegistryPostProcessor) postProcessor;
     16                     registryProcessor.postProcessBeanDefinitionRegistry(registry);
     17                     registryProcessors.add(registryProcessor);
     18                 }
     19                 else {
     20                     regularPostProcessors.add(postProcessor);
     21                 }
     22             }
     23 
     24             // Do not initialize FactoryBeans here: We need to leave all regular beans
     25             // uninitialized to let the bean factory post-processors apply to them!
     26             // Separate between BeanDefinitionRegistryPostProcessors that implement
     27             // PriorityOrdered, Ordered, and the rest.
     28             // 这个currentRegistryProcessors放的是spring内部自己实现了的BeanDefinitionRegistryPostProcessor
     29             List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
     30 
     31             // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered.
     32             // getBeanNamesForType根据类的类型获取类的名字。
     33             String[] postProcessorNames =
     34                     beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
     35             for (String ppName : postProcessorNames) {
     36                 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
     37                     currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
     38                     processedBeans.add(ppName);
     39                 }
     40             }
     41             // 进行排序
     42             sortPostProcessors(currentRegistryProcessors, beanFactory);
     43             // 合并list(为什么要合并,因为还有自己写的)
     44             registryProcessors.addAll(currentRegistryProcessors);
     45             // 这里很重要
     46             // currentRegistryProcessors 这个集合中只有ConfigurationClassPostProcessor这一个类
     47          invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
     48 
     49             // 这个list是一个临时变量,故而要删除
     50             currentRegistryProcessors.clear();
     51 
     52             // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
     53             postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
     54             for (String ppName : postProcessorNames) {
     55                 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
     56                     currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
     57                     processedBeans.add(ppName);
     58                 }
     59             }
     60             sortPostProcessors(currentRegistryProcessors, beanFactory);
     61             registryProcessors.addAll(currentRegistryProcessors);
     62             invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
     63             currentRegistryProcessors.clear();
     64 
     65             // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
     66             boolean reiterate = true;
     67             while (reiterate) {
     68                 reiterate = false;
     69                 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
     70                 for (String ppName : postProcessorNames) {
     71                     if (!processedBeans.contains(ppName)) {
     72                         currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
     73                         processedBeans.add(ppName);
     74                         reiterate = true;
     75                     }
     76                 }
     77                 sortPostProcessors(currentRegistryProcessors, beanFactory);
     78                 registryProcessors.addAll(currentRegistryProcessors);
     79                 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
     80                 currentRegistryProcessors.clear();
     81             }
     82 
     83             // Now, invoke the postProcessBeanFactory callback of all processors handled so far.
     84             invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
     85             invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
     86         }
     87 
     88         else {
     89             // Invoke factory processors registered with the context instance.
     90             invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
     91         }
     92 
     93         // Do not initialize FactoryBeans here: We need to leave all regular beans
     94         // uninitialized to let the bean factory post-processors apply to them!
     95         String[] postProcessorNames =
     96                 beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
     97 
     98         // Separate between BeanFactoryPostProcessors that implement PriorityOrdered,
     99         // Ordered, and the rest.
    100         List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
    101         List<String> orderedPostProcessorNames = new ArrayList<>();
    102         List<String> nonOrderedPostProcessorNames = new ArrayList<>();
    103         for (String ppName : postProcessorNames) {
    104             if (processedBeans.contains(ppName)) {
    105                 // skip - already processed in first phase above
    106             }
    107             else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
    108                 priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
    109             }
    110             else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
    111                 orderedPostProcessorNames.add(ppName);
    112             }
    113             else {
    114                 nonOrderedPostProcessorNames.add(ppName);
    115             }
    116         }
    117 
    118         // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered.
    119         sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
    120         invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
    121 
    122         // Next, invoke the BeanFactoryPostProcessors that implement Ordered.
    123         List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
    124         for (String postProcessorName : orderedPostProcessorNames) {
    125             orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    126         }
    127         sortPostProcessors(orderedPostProcessors, beanFactory);
    128         invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
    129 
    130         // Finally, invoke all other BeanFactoryPostProcessors.
    131         List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
    132         for (String postProcessorName : nonOrderedPostProcessorNames) {
    133             nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
    134         }
    135         invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
    136 
    137         // Clear cached merged bean definitions since the post-processors might have
    138         // modified the original metadata, e.g. replacing placeholders in values...
    139         beanFactory.clearMetadataCache();
    140     }

        5.2.1.1点击invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);方法进入

    1 private static void invokeBeanDefinitionRegistryPostProcessors(
    2             Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
    3         // 因为只有一条数据,所以实现的就是ConfigurationClassPostProcessor这个类中的postProcessBeanDefinitionRegistry方法
    4         for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
    5             postProcessor.postProcessBeanDefinitionRegistry(registry);
    6         }
    7     }

        5.2.1.1.1进入ConfigurationClassPostProcessor实现的postProcessBeanDefinitionRegistry(registry);方法

     1 public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
     2         int registryId = System.identityHashCode(registry);
     3         if (this.registriesPostProcessed.contains(registryId)) {
     4             throw new IllegalStateException(
     5                     "postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
     6         }
     7         if (this.factoriesPostProcessed.contains(registryId)) {
     8             throw new IllegalStateException(
     9                     "postProcessBeanFactory already called on this post-processor against " + registry);
    10         }
    11         this.registriesPostProcessed.add(registryId);
    12 
    13         processConfigBeanDefinitions(registry);
    14     }

        继续点击processConfigBeanDefinitions(registry);方法查看具体实现:

      1 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
      2         // app 提供的bean也就是我们程序内提供的bean
      3         List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
      4         // 获取容器中注册的所有bean的名字
      5         String[] candidateNames = registry.getBeanDefinitionNames();
      6 
      7         for (String beanName : candidateNames) {
      8             BeanDefinition beanDef = registry.getBeanDefinition(beanName);
      9             if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
     10                 if (logger.isDebugEnabled()) {
     11                     logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
     12                 }
     13             }
     14             else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
     15                 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
     16             }
     17         }
     18 
     19         // Return immediately if no @Configuration classes were found
     20         if (configCandidates.isEmpty()) {
     21             return;
     22         }
     23 
     24         // Sort by previously determined @Order value, if applicable
     25         configCandidates.sort((bd1, bd2) -> {
     26             int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
     27             int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
     28             return Integer.compare(i1, i2);
     29         });
     30 
     31         // Detect any custom bean name generation strategy supplied through the enclosing application context
     32         SingletonBeanRegistry sbr = null;
     33         if (registry instanceof SingletonBeanRegistry) {
     34             sbr = (SingletonBeanRegistry) registry;
     35             if (!this.localBeanNameGeneratorSet) {
     36                 BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
     37                         AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
     38                 if (generator != null) {
     39                     this.componentScanBeanNameGenerator = generator;
     40                     this.importBeanNameGenerator = generator;
     41                 }
     42             }
     43         }
     44 
     45         if (this.environment == null) {
     46             this.environment = new StandardEnvironment();
     47         }
     48 
     49         // Parse each @Configuration class
     50         ConfigurationClassParser parser = new ConfigurationClassParser(
     51                 this.metadataReaderFactory, this.problemReporter, this.environment,
     52                 this.resourceLoader, this.componentScanBeanNameGenerator, registry);
     53 
     54         Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
     55         Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
     56         do {
     57             parser.parse(candidates);
     58             parser.validate();
     59 
     60             Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
     61             configClasses.removeAll(alreadyParsed);
     62 
     63             // Read the model and create bean definitions based on its content
     64             if (this.reader == null) {
     65                 this.reader = new ConfigurationClassBeanDefinitionReader(
     66                         registry, this.sourceExtractor, this.resourceLoader, this.environment,
     67                         this.importBeanNameGenerator, parser.getImportRegistry());
     68             }
     69             this.reader.loadBeanDefinitions(configClasses);
     70             alreadyParsed.addAll(configClasses);
     71 
     72             candidates.clear();
     73             if (registry.getBeanDefinitionCount() > candidateNames.length) {
     74                 String[] newCandidateNames = registry.getBeanDefinitionNames();
     75                 Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
     76                 Set<String> alreadyParsedClasses = new HashSet<>();
     77                 for (ConfigurationClass configurationClass : alreadyParsed) {
     78                     alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
     79                 }
     80                 for (String candidateName : newCandidateNames) {
     81                     if (!oldCandidateNames.contains(candidateName)) {
     82                         BeanDefinition bd = registry.getBeanDefinition(candidateName);
     83                         if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
     84                                 !alreadyParsedClasses.contains(bd.getBeanClassName())) {
     85                             candidates.add(new BeanDefinitionHolder(bd, candidateName));
     86                         }
     87                     }
     88                 }
     89                 candidateNames = newCandidateNames;
     90             }
     91         }
     92         while (!candidates.isEmpty());
     93 
     94         // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
     95         if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
     96             sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
     97         }
     98 
     99         if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
    100             // Clear cache in externally provided MetadataReaderFactory; this is a no-op
    101             // for a shared cache since it'll be cleared by the ApplicationContext.
    102             ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
    103         }
    104     }

     6.使用ImportBeanDefinitionRegistrar接口的方法,动态使用bean的map对象。

      bean的map对象存入数据的几种方法:

          1.通过ApplicationContext的register()方法来往map中put得到的bean对象

          2.通过scan来扫描要注入的bean对象

          3.通过ImportBeanDefinitionRegistrar接口提供的方法

     
     1 public interface ImportBeanDefinitionRegistrar {
     2 
     3     /**
     4      * Register bean definitions as necessary based on the given annotation metadata of
     5      * the importing {@code @Configuration} class.
     6      * <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
     7      * registered here, due to lifecycle constraints related to {@code @Configuration}
     8      * class processing.
     9      * <p>The default implementation delegates to
    10      * {@link #registerBeanDefinitions(AnnotationMetadata, BeanDefinitionRegistry)}.
    11      * @param importingClassMetadata annotation metadata of the importing class
    12      * @param registry current bean definition registry
    13      * @param importBeanNameGenerator the configuration-level bean name generator
    14      * strategy for imported beans
    15      * @since 5.2
    16      */
    17     default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry,
    18             BeanNameGenerator importBeanNameGenerator) {
    19 
    20         registerBeanDefinitions(importingClassMetadata, registry);
    21     }
    22 
    23     /**
    24      * Register bean definitions as necessary based on the given annotation metadata of
    25      * the importing {@code @Configuration} class.
    26      * <p>Note that {@link BeanDefinitionRegistryPostProcessor} types may <em>not</em> be
    27      * registered here, due to lifecycle constraints related to {@code @Configuration}
    28      * class processing.
    29      * <p>The default implementation is empty.
    30      * @param importingClassMetadata annotation metadata of the importing class
    31      * @param registry current bean definition registry
    32      */
    33     default void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    34     }
    35 
    36 }

    下面使用ImportBeanDefinitionRegistrar来进行bean的注册。

      创建一个没有注册的接口IndexUCC;

    1 public interface IndexUCC {
    2     void query();
    3 }

      创建一个MyFactoryBean来实现FactoryBean接口,同时实现InvocationHandler接口来实现代理功能

     1 @SuppressWarnings("rawtypes")//jdk8如果不使用这个注解会导致报rawtypes类型错误
     2 public class MyFactoryBean implements FactoryBean, InvocationHandler {
     3     // 创建构造方法,方便动态传入接口类
     4     Class clazz;
     5     public MyFactoryBean(Class clazz){
     6         this.clazz = clazz;
     7     }
     8     // 这里利用了FactoryBean的getObject返回的是自己定义的代理对象的特性来实现接口的实现类的创建
     9     // 实现了FactoryBean的类,在使用MyFactoryBean.class的时候获取的是getObject()返回的类
    10     @Override
    11     public Object getObject() throws Exception {
    12         Class[] classes = new Class[]{clazz};
    13         Object proxy = Proxy.newProxyInstance(this.getClass().getClassLoader(), classes ,this);
    14         return proxy;
    15     }
    16 
    17     @Override
    18     public Class<?> getObjectType() {
    19         return clazz;
    20     }
    21 
    22     @Override
    23     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    24         System.out.println("myInvocationHandler....");
    25         //可以在这里通过method进行自己的逻辑处理
    26         Method[] methods = proxy.getClass().getInterfaces()[0].getMethods();
    27         for (Method method1 : methods){
    28             System.out.println("method1:"+method1);
    29         }
    30         System.out.println("method:"+method.getName());
    31         return null;
    32     }
    33 }

      创建一个MyImportBeanDefinitionRegister类来实现ImportBeanDefinitionRegistrar接口,就可以动态自己注入bean对象到map中了

     1 @Component
     2 public class MyImportBeanDefinitionRegister implements ImportBeanDefinitionRegistrar {
     3     @Override
     4     public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry, BeanNameGenerator importBeanNameGenerator) {
     5         /**
     6          * 1.得到BeanDefinition
     7          *
     8          * 通过BeanDefinitionBuilder的静态方法获得
     9          * IndexDao可以动态获取,这里先写死
    10          */
    11         BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(IndexUCC.class);
    12         //得到标准的BeanDefinition
    13         GenericBeanDefinition beanDefinition = (GenericBeanDefinition) builder.getBeanDefinition();
    14         System.out.println(beanDefinition.getBeanClassName());
    15         // 设置构造方法,因为MyFactoryBean不是使用的默认构造方法,如果使用的无参构造方法,spring比较容易创建对象实例,
    16         // 但是如果是我们自己的构造方法,那么spring就没有办法自动帮我们创建对象了,
    17         // 所以我们要手动设置自己的构造方法,来实例化对象
    18         beanDefinition.getConstructorArgumentValues().addGenericArgumentValue("com.wk.ucc.IndexUCC");
    19         //通过factoryBean的特性,拿出代理对象
    20         beanDefinition.setBeanClass(MyFactoryBean.class);
    21         //注册到registry中,
    22         registry.registerBeanDefinition("indexUcc",beanDefinition);
    23     }
    24 }

      这时候我们就可以在我们的代码中注入自己注册的bean了

    
    
  • 相关阅读:
    在vue项目中使用stylus来实现移动端的1px
    Promise对象和回调函数,解决异步数据传递问题
    axios在实际项目中的使用介绍
    关于React.PropTypes的废除,以及新版本下的react的验证方式
    javascript之日期对象
    js Date 日期格式化(转)
    jquery无缝隙连续滚动代码
    8款惊艳的HTML5粒子动画特效
    web前端设计师们常用的jQuery特效插件汇总
    js/jQuery实现类似百度搜索功能
  • 原文地址:https://www.cnblogs.com/wk-missQ1/p/12528033.html
Copyright © 2020-2023  润新知