Spring IOC源码分析(基于注解)上

1 入口代码

public class Info {
    
    

   public static void main(String[] args) {
    
    
      ApplicationContext ac  = new AnnotationConfigApplicationContext(AppConfig.class);
      System.out.println(ac.getBean(AppConfig.class).name);
   }
}

2 AnnotationConfigApplicationContext

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    
    
		this();
		register(componentClasses);
		refresh();
	}

调用this(),默认无参的构造方法。AnnotationConfigApplicationContext继承GenericApplicationContext。因此在调用自身构造器的时候会隐式的调用父类的构造器。

public GenericApplicationContext() {
    
    
		this.beanFactory = new DefaultListableBeanFactory();
	}

因此在GenericApplicationContext的构造器完成了DefaultListableBeanFactory的初始化。

/**
	 * 这里会首先初始化父类的构造方法
	 * public GenericApplicationContext() {
	 * 		this.beanFactory = new DefaultListableBeanFactory();
	 * }
	 * 因此会实例化beanFactory,也就是DefaultListableBeanFactory
	 */
	public AnnotationConfigApplicationContext() {
    
    
		StartupStep createAnnotatedBeanDefReader = this.getApplicationStartup().start("spring.context.annotated-bean-reader.create");
		// 基于注解的bean定义读取器
		this.reader = new AnnotatedBeanDefinitionReader(this);
		createAnnotatedBeanDefReader.end();
		// 基于注解的bean定义扫描器
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

这里AnnotationConfigApplicationContext有两个属性,bean定义读取器和扫描器。

    private final AnnotatedBeanDefinitionReader reader;

	private final ClassPathBeanDefinitionScanner scanner;

在构造器中开始初始化。

2.1 初始化AnnotatedBeanDefinitionReader

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    
    
		this(registry, getOrCreateEnvironment(registry));
}

这里的BeanDefinitionRegistry是AnnotationConfigApplicationContext实例。因为AnnotationConfigApplicationContext实现了BeanDefinitionRegistry接口。这里的构造器也是门面方法。真正调用的是如下的构造器。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    
    
		//TODO 省略断言
		this.registry = registry;
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

这里的conditionEvaluator是条件计算器。什么条件呢。按照一定的条件进行判断,需要注入的Bean满足给定条件才可以注入到Spring IOC容器中。一般使用@Conditional注解。而使用该注解需要实现Condition接口,并重写方法来自定义match规则。conditionEvaluator 的实例化完成之后,存在五个引用。分别是读取到的:

  1. registry=AnnotationConfigApplicationContext
  2. beanFactory=DefaultListableBeanFactory
  3. environment=StandardEnvironment
  4. 资源加载器
  5. 类加载器

第三行代码:AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);作用是注册注解配置处理器。在给定的注册表中注册所有相关的注解后处理程序。也就是说注解配置读取完成之后然后根据注解上下文AnnotationConfigApplicationContext的情况进行之后的配置。称之为后处理器。具体的实现在AnnotationConfigUtils类里面;

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
			BeanDefinitionRegistry registry, @Nullable Object source) {
    
    

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
    
    
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
    
    
				//设置beanFactory的依赖关系
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
    
    
				//设置设置beanFactory的自动解析程序
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

		Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
		//在Set集合中添加一系列内部的BeanDefinitionHolder.
		//BeanDefinitionHolder 主要持有 BeanDefinition的名称和别名
		//BeanDefinition描述bean实例的信息。如:bean的作用域、bean是否懒加载、bean的角色,bean的属性信息等。
		//bean的角色 role=0 用户使用 role=1内部bean,但是可以通过aware接口获取 role=2完全IOC容器内部。下面添加的bean全部是内部使用

		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    
    
			//添加ConfigurationClassPostProcessor 配置类后处理器
		}

		if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    
    
			//添加AutowiredAnnotationBeanPostProcessor 自动注解bean后处理器
		}

		// 检查  JSR-250、JPA 支持 省略.......
		
		if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
    
    
			//添加EventListenerMethodProcessor 事件方法处理器
		}

		if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
    
    
			//添加DefaultEventListenerFactory 默认事件功工厂处理器
		}

		return beanDefs;
	}

registerAnnotationConfigProcessors注册注解配置处理器做了如下几件事:

  1. 根据传入的注册表registry获取beanFactory,这里的注册表其实就是spring的上下文实例,也就是IOC容器。beanFactory设置依赖关系和自动解析程序。
  2. 添加一系列处理器。设置角色role=2.全部是IOC容器内部使用。
    至此完成了注解bean定义读取器的初始化。

2.2 初始化ClassPathBeanDefinitionScanner

在这里插入图片描述
调用自身的构造器:

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
    
    
		this(registry, true);
	}

这是个门面方法:

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
    
    
		this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
}

最终在构造器下实现:

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
			Environment environment, @Nullable ResourceLoader resourceLoader) {
    
    

		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		this.registry = registry;

		if (useDefaultFilters) {
    
    
		   //注册默认的过滤器
			registerDefaultFilters();
		}
		setEnvironment(environment);
		setResourceLoader(resourceLoader);
	}

注册默认过滤器:

    @SuppressWarnings("unchecked")
	protected void registerDefaultFilters() {
    
    
		this.includeFilters.add(new AnnotationTypeFilter(Component.class));
		ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
		try {
    
    
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
			logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
    
    
			// JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
		}
		try {
    
    
			this.includeFilters.add(new AnnotationTypeFilter(
					((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
			logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
		}
		catch (ClassNotFoundException ex) {
    
    
			// JSR-330 API not available - simply skip.
		}
	}
ClassPathScanningCandidateComponentProvider ClassPathBeanDefinitionScanner

ClassPathBeanDefinitionScanner继承ClassPathScanningCandidateComponentProvider。在注册过滤器的实现中。调用父类的方法registerDefaultFilters()。过滤的注解包括:@Component、@Repository、@Service、@Controller以及Java EE 6的ManagedBean和Named等注解。然后添加到List集合中。也就是说扫描器可以扫描那些注解配置。
这里包括添加

BeanFactory ListableBeanFactory HierarchicalBeanFactory ApplicationContext EnvironmentCapable ConfigurableApplicationContext AbstractApplicationContext GenericApplicationContext AnnotationConfigApplicationContext BeanDefinitionRegistry AliasRegistry

猜你喜欢

转载自blog.csdn.net/GoSaint/article/details/109721801