这里分类和汇总了欣宸的全部原创(含配套源码):
https://github.com/zq2599/blog_demos
- public void parse(Set<BeanDefinitionHolder> configCandidates) {
- this.deferredImportSelectors = new LinkedList<DeferredImportSelectorHolder>();
- //检查每个bean的定义
- for (BeanDefinitionHolder holder : configCandidates) {
- BeanDefinition bd = holder.getBeanDefinition();
- try {
- if (bd instanceof AnnotatedBeanDefinition) {
- //对于每个有注解的类,都执行方法parse(AnnotationMetadata metadata, String beanName)
- parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
- }
- else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
- parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
- }
- else {
- parse(bd.getBeanClassName(), holder.getBeanName());
- }
- }
- catch (BeanDefinitionStoreException ex) {
- throw ex;
- }
- catch (Exception ex) {
- throw new BeanDefinitionStoreException(
- "Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
- }
- }
-
- //最后再处理DeferredImportSelector的实现类
- processDeferredImportSelectors();
- }
-
复制代码
- protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
- //为了聚焦Import相关处理,此处略去部分不相关代码,不在这里展示了
- ...
- ...
- // 处理@Import注解
- processImports(configClass, sourceClass, getImports(sourceClass), true);
-
-
- // 处理@ImportResource注解
- if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) {
- AnnotationAttributes importResource = AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
- String[] resources = importResource.getStringArray("value");
- Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
- for (String resource : resources) {
- String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
- configClass.addImportedResource(resolvedResource, readerClass);
- }
- }
-
-
- // 处理@Bean注解,注意是处理注解,不是执行@Bean修饰的方法
- Set<MethodMetadata> beanMethods = sourceClass.getMetadata().getAnnotatedMethods(Bean.class.getName());
- for (MethodMetadata methodMetadata : beanMethods) {
- configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
- }
-
-
- // 处理Configuration类的父类,外面在调用doProcessConfigurationClass方法的时有迭代处理,确保所有父类的注解都会被处理
- if (sourceClass.getMetadata().hasSuperClass()) {
- String superclass = sourceClass.getMetadata().getSuperClassName();
- if (!superclass.startsWith("java") && !this.knownSuperclasses.containsKey(superclass)) {
- this.knownSuperclasses.put(superclass, configClass);
- // Superclass found, return its annotation metadata and recurse
- return sourceClass.getSuperClass();
- }
- }
-
-
- // 再也没有父类了,返回null表示当前Configuration处理完毕
- return null;
- }
-
复制代码
- private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
- Collection<SourceClass> importCandidates, boolean checkForCircularImports) throws IOException {
-
-
- if (importCandidates.isEmpty()) {
- return;
- }
-
-
- if (checkForCircularImports && this.importStack.contains(configClass)) {
- this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
- }
- else {
- this.importStack.push(configClass);
- try {
- for (SourceClass candidate : importCandidates) {
- //如果是ImportSelector接口的实现类,就在此处理
- if (candidate.isAssignable(ImportSelector.class)) {
- // Candidate class is an ImportSelector -> delegate to it to determine imports
- Class<?> candidateClass = candidate.loadClass();
- //实例化这些ImportSelector的实现类
- ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
- //如果这实现类还实现了BeanFactoryAware、EnvironmentAware这些接口,就要先执行这些接口中声明的方法
- invokeAwareMethods(selector);
- //如果这个实现类也实现了DeferredImportSelector接口,就被加入到集合deferredImportSelectors中
- if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
- this.deferredImportSelectors.add(
- new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
- }
- else {
- //注意,这一行是关键代码!!!执行实现类的selectImports方法
- String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
- Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
- processImports(configClass, currentSourceClass, importSourceClasses, false);
- }
- }
- //此处略去的和ImportSelector不相关的逻辑代码
- ...
- ...
- ...
- }
- }
- catch (BeanDefinitionStoreException ex) {
- throw ex;
- }
- catch (Exception ex) {
- throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" +
- configClass.getMetadata().getClassName() + "]", ex);
- }
- finally {
- this.importStack.pop();
- }
- }
- }
-
复制代码
- private void processDeferredImportSelectors() {
- List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
- this.deferredImportSelectors = null;
- //按照Order注解或者Ordered接口进行排序
- Collections.sort(deferredImports, DEFERRED_IMPORT_COMPARATOR);
-
-
- for (DeferredImportSelectorHolder deferredImport : deferredImports) {
- ConfigurationClass configClass = deferredImport.getConfigurationClass();
- try {
- //此处是关键代码,执行DeferredImportSelector实现类的selectImports方法
- String[] imports = deferredImport.getImportSelector().selectImports(configClass.getMetadata());
- processImports(configClass, asSourceClass(configClass), asSourceClasses(imports), false);
- }
- catch (BeanDefinitionStoreException ex) {
- throw ex;
- }
- catch (Exception ex) {
- throw new BeanDefinitionStoreException("Failed to process import candidates for configuration class [" +
- configClass.getMetadata().getClassName() + "]", ex);
- }
- }
- }
-
复制代码
- <?xml version="1.0" encoding="UTF-8"?>
- <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
- xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
- <modelVersion>4.0.0</modelVersion>
-
-
- <groupId>com.bolingcavalry</groupId>
- <artifactId>customizeimportselector</artifactId>
- <version>0.0.1-SNAPSHOT</version>
- <packaging>jar</packaging>
-
-
- <name>customizeimportselector</name>
- <description>Demo project for Spring Boot</description>
-
-
- <parent>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-parent</artifactId>
- <version>1.5.9.RELEASE</version>
- <relativePath/> <!-- lookup parent from repository -->
- </parent>
-
-
- <properties>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
- <java.version>1.8</java.version>
- </properties>
-
-
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
-
-
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-test</artifactId>
- <scope>test</scope>
- </dependency>
- </dependencies>
-
-
- <build>
- <plugins>
- <plugin>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-maven-plugin</artifactId>
- </plugin>
- </plugins>
- </build>
- </project>
-
复制代码
- package com.bolingcavalry.customizeimportselector.service;
-
-
- public interface CustomizeService1 {
- void execute();
- }
-
复制代码
- package com.bolingcavalry.customizeimportselector.service.impl;
-
-
- import com.bolingcavalry.customizeimportselector.service.CustomizeService1;
-
-
- public class CustomizeServiceImpl1 implements CustomizeService1 {
-
-
- public CustomizeServiceImpl1() {
- System.out.println("construct : " + this.getClass().getSimpleName());
- }
-
-
- @Override
-
-
- public void execute() {
- System.out.println("execute : " + this.getClass().getSimpleName());
- }
- }
-
复制代码
- package com.bolingcavalry.customizeimportselector.selector;
-
-
- import org.springframework.context.annotation.DeferredImportSelector;
- import org.springframework.context.annotation.ImportSelector;
- import org.springframework.core.annotation.Order;
- import org.springframework.core.type.AnnotationMetadata;
-
-
- @Order(102)
- public class CustomizeImportSelector1 implements DeferredImportSelector {
- @Override
- public String[] selectImports(AnnotationMetadata annotationMetadata) {
- System.out.println("selectImports : " + this.getClass().getSimpleName());
- return new String[]{"com.bolingcavalry.customizeimportselector.service.impl.CustomizeServiceImpl1"};
- }
- }
-
复制代码
- package com.bolingcavalry.customizeimportselector.selector;
-
-
- import org.springframework.context.annotation.DeferredImportSelector;
- import org.springframework.core.annotation.Order;
- import org.springframework.core.type.AnnotationMetadata;
-
-
- @Order(101)
- public class CustomizeImportSelector2 implements DeferredImportSelector {
- @Override
- public String[] selectImports(AnnotationMetadata annotationMetadata) {
- System.out.println("selectImports : " + this.getClass().getSimpleName());
- return new String[]{"com.bolingcavalry.customizeimportselector.service.impl.CustomizeServiceImpl2"};
- }
- }
-
复制代码
- package com.bolingcavalry.customizeimportselector.selector;
-
-
- import org.springframework.context.annotation.ImportSelector;
- import org.springframework.core.annotation.Order;
- import org.springframework.core.type.AnnotationMetadata;
-
-
- public class CustomizeImportSelector3 implements ImportSelector {
- @Override
- public String[] selectImports(AnnotationMetadata annotationMetadata) {
- System.out.println("selectImports : " + this.getClass().getSimpleName());
- return new String[]{"com.bolingcavalry.customizeimportselector.service.impl.CustomizeServiceImpl3"};
- }
- }
-
复制代码
- package com.bolingcavalry.customizeimportselector;
-
-
- import com.bolingcavalry.customizeimportselector.selector.CustomizeImportSelector1;
- import com.bolingcavalry.customizeimportselector.selector.CustomizeImportSelector2;
- import com.bolingcavalry.customizeimportselector.selector.CustomizeImportSelector3;
- import org.springframework.context.annotation.Configuration;
- import org.springframework.context.annotation.Import;
-
-
- @Configuration
- @Import({CustomizeImportSelector1.class, CustomizeImportSelector2.class, CustomizeImportSelector3.class})
- public class SysConfig {
- }
-
复制代码
- package com.bolingcavalry.customizeimportselector;
-
-
- import org.springframework.boot.SpringApplication;
- import org.springframework.boot.autoconfigure.SpringBootApplication;
-
-
- @SpringBootApplication
- public class CustomizeimportselectorApplication {
-
-
- public static void main(String[] args) {
- SpringApplication.run(CustomizeimportselectorApplication.class, args);
- }
- }
-
复制代码
- 2018-09-09 15:43:45.790 INFO 15364 --- [ main] c.b.c.CustomizeimportselectorApplication : Starting CustomizeimportselectorApplication on DESKTOP-82CCEBN with PID 15364 (D:\github\blog_demos\customizeimportselector\target\classes started by 12167 in D:\github\blog_demos\customizeimportselector)
- 2018-09-09 15:43:45.791 INFO 15364 --- [ main] c.b.c.CustomizeimportselectorApplication : No active profile set, falling back to default profiles: default
- 2018-09-09 15:43:45.825 INFO 15364 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@641147d0: startup date [Sun Sep 09 15:43:45 GMT+08:00 2018]; root of context hierarchy
- selectImports : CustomizeImportSelector3
- selectImports : CustomizeImportSelector2
- selectImports : CustomizeImportSelector1
- 2018-09-09 15:43:46.425 INFO 15364 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
- 2018-09-09 15:43:46.430 INFO 15364 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
- 2018-09-09 15:43:46.431 INFO 15364 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.23
- 2018-09-09 15:43:46.493 INFO 15364 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
- 2018-09-09 15:43:46.493 INFO 15364 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 670 ms
- 2018-09-09 15:43:46.569 INFO 15364 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
- 2018-09-09 15:43:46.572 INFO 15364 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
- 2018-09-09 15:43:46.572 INFO 15364 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
- 2018-09-09 15:43:46.572 INFO 15364 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
- 2018-09-09 15:43:46.572 INFO 15364 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
- construct : CustomizeServiceImpl1
- construct : CustomizeServiceImpl2
- construct : CustomizeServiceImpl3
-
复制代码
学习路上,你不孤单,欣宸原创一路相伴...