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了
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· Blazor Hybrid适配到HarmonyOS系统
· Obsidian + DeepSeek:免费 AI 助力你的知识管理,让你的笔记飞起来!
· 分享4款.NET开源、免费、实用的商城系统
· 解决跨域问题的这6种方案,真香!
· 一套基于 Material Design 规范实现的 Blazor 和 Razor 通用组件库