zoukankan      html  css  js  c++  java
  • 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了

    
    
  • 相关阅读:
    解析大型.NET ERP系统 权限模块设计与实现
    Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架
    解析大型.NET ERP系统 单据编码功能实现
    解析大型.NET ERP系统 单据标准(新增,修改,删除,复制,打印)功能程序设计
    Windows 10 部署Enterprise Solution 5.5
    解析大型.NET ERP系统 设计异常处理模块
    解析大型.NET ERP系统 业务逻辑设计与实现
    解析大型.NET ERP系统 多国语言实现
    Enterprise Solution 管理软件开发框架流程实战
    解析大型.NET ERP系统 数据审计功能
  • 原文地址:https://www.cnblogs.com/wk-missQ1/p/12528033.html
Copyright © 2011-2022 走看看