Spring从2.5开始支持基于注解的bean扫描,考虑到目前流行的SpringBoot框架也是大量采用了注解驱动开发,所以本文直接跨过xml配置,从注解驱动开始,一探究竟为什么加了@Service,就可以直接在Spring中注入并调用方法了?

1、初始化AnnotationConfigApplicationContext

入口代码:

  1. public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
  2. this();
  3. register(componentClasses);
  4. refresh();
  5. }

1.1 构造函数,首先需要调用无参构造函数

  1. //调用父类无参的构建函数new出一个DefaultListableFactory
  2. public AnnotationConfigApplicationContext() {
  3. /**
  4. * 1.2 初始化基于注解的beanDefinition扫描器
  5. * 把处理注解的bean定义 放入到容器中
  6. */
  7. this.reader = new AnnotatedBeanDefinitionReader(this);
  8. //1.3初始化 基于classpath的beanDefinition扫描器 默认使用的是这个
  9. this.scanner = new ClassPathBeanDefinitionScanner(this);
  10. }

在调用无参构造函数的时候,由于AnnotationConfigApplicationContext继承了GenericApplicationContext类。根据类的初始化顺序,是会先初始化父类的构造函数,所以在执行AnnotationConfigApplicationContext的无参的构造函数的时候,先调用了GenericApplicationContext()。:

  1. /**
  2. * Create a new GenericApplicationContext.
  3. * @see #registerBeanDefinition
  4. * @see #refresh
  5. */
  6. public GenericApplicationContext() {
  7. this.beanFactory = new DefaultListableBeanFactory();
  8. }

这个就是我们经常说的Spring的容器类DefaultListableBeanFactory

1.2、初始化基于注解的beanDefinition扫描器

初始化基于注解的beanDefinition扫描器。把处理注解的bean定义 放入到容器中

  1. public AnnotationConfigApplicationContext() {
  2. // 初始化基于注解的beanDefinition扫描器.
  3. // 把处理注解的bean定义 放入到容器中
  4. this.reader = new AnnotatedBeanDefinitionReader(this);
  5. this.scanner = new ClassPathBeanDefinitionScanner(this);
  6. }
  7. public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
  8. .....
  9. //传递过来的 AnnotationConfigApplicationContext bean定义 容器
  10. this.registry = registry;
  11. /**
  12. * 用于计算判断 {@link Conditional} 注解
  13. */
  14. this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
  15. /**
  16. * 1.1.1注册 所相关注解的后置处理器 到registry
  17. */
  18. AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
  19. }
  • 几个细节问题看一下,我们可以看到传到AnnotatedBeanDefinitionReader()方法的第一个参数是BeanDefinitionRegistry。这个猜测就是AnnotationConfigApplicationContext的接口。一看代码果然是的。下面是关于BeanDefinitionRegistry接口的定义,从中看到这个接口主要定义的是注册删除获取是否包含判断BeanName是否使用的一些接口,也就是定义关于BeanDefinition常用操作的接口。
  1. public interface BeanDefinitionRegistry extends AliasRegistry {
  2. void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;
  3. void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
  4. BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;
  5. boolean containsBeanDefinition(String var1);
  6. String[] getBeanDefinitionNames();
  7. int getBeanDefinitionCount();
  8. boolean isBeanNameInUse(String var1);
  9. }
  • 核心逻辑是**AnnotationConfigUtils.registerAnnotationConfigProcessors**
    调用工具类注册 AnnotationConfigProcessors, 也就是配置的前置处理器
    而就是在这个方法中完成了对多个重要Bean的注册
  1. /**
  2. * Register all relevant annotation post processors in the given registry.
  3. * @param registry the registry to operate on
  4. */
  5. public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
  6. registerAnnotationConfigProcessors(registry, null);
  7. }
  8. /**
  9. * Register all relevant annotation post processors in the given registry.
  10. * @param registry the registry to operate on
  11. * @param source the configuration source element (already extracted)
  12. * that this registration was triggered from. May be {@code null}.
  13. * @return a Set of BeanDefinitionHolders, containing all bean definitions
  14. * that have actually been registered by this call
  15. */
  16. public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) {
  17. DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
  18. if (beanFactory != null) {
  19. if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
  20. beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
  21. }
  22. if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
  23. beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
  24. }
  25. }
  26. // 1、BeanDefinitionHolder只是存放BD的,里面有三个属性:BD对象、beanName以及别名组成的String[]
  27. Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
  28. // 注册最关键的类,对应的类为ConfigurationClassPostProcessor,父类的父类是BeanFactoryPostProcessor
  29. // 判断register是否包含 internalConfigurationAnnotationProcessor名称的BeanDefinition,初始化是不包含的
  30. if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  31. RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
  32. def.setSource(source);
  33. // 将BD注入进容器中,没经过什么处理,只是放入了DefaultListableBeanFactory中的beanDefinitionMap跟存放beanName的list中
  34. beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  35. }
  36. // 此类实现了BeanPostProcessor,用于处理@Autowired、@Value注解
  37. if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  38. RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
  39. def.setSource(source);
  40. beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
  41. }
  42. // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
  43. if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  44. RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
  45. def.setSource(source);
  46. beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
  47. }
  48. // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
  49. if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  50. RootBeanDefinition def = new RootBeanDefinition();
  51. try {
  52. def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
  53. AnnotationConfigUtils.class.getClassLoader()));
  54. }
  55. catch (ClassNotFoundException ex) {
  56. throw new IllegalStateException(
  57. "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
  58. }
  59. def.setSource(source);
  60. beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
  61. }
  62. if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
  63. RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
  64. def.setSource(source);
  65. beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
  66. }
  67. if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
  68. RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
  69. def.setSource(source);
  70. beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
  71. }
  72. return beanDefs;
  73. }
  • 这段代码是核心逻辑,我们首先看看第一个比较重要的类BeanDefinitionHolderBeanDefinitionHolder是BeanDefinition的封装类, 封装了BeanDefinition、Bean的名字和别名, 用它来完成向IoC容器注册
  • 这这一段后面一直重复的逻辑
  1. /**
  2. * The bean name of the internally managed Configuration annotation processor.
  3. */
  4. public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
  5. "org.springframework.context.annotation.internalConfigurationAnnotationProcessor";
  6. Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
  7. if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
  8. RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
  9. def.setSource(source);
  10. // 将BD注入进容器中,没经过什么处理,只是放入了DefaultListableBeanFactory中的beanDefinitionMap跟存放beanName的list中
  11. beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  12. }
  13. .....
  14. return beanDefs
  1. registryAnnotationConfigApplicationContext类实例,AnnotationConfigApplicationContext是继承了GenericApplicationContext类,这个类继承了抽象类AbstractApplicationContext。这个里面实现了containsBeanDefinition(String beanName)方法。这个方法,最终还是调用的是DefaultListableBeanFactory Bean工厂的方法containsBeanDefinition(beanName)完成的。

点击查看【processon】

  1. new RootBeanDefinition(ConfigurationClassPostProcessor.class);创建的是BeanDefinition的定义
  2. registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)这行代码会调用GenericApplicationContextregisterBeanDefinition(beanName,beanDefinition)方法,然后这个方法就是会获取到DefaultListableBeanFactory Bean工厂的registerBeanDefinition方法。这个方法会放入到DefaultListableBeanFactorythis.beanDefinitionMap属性中存起来。 ```java private static BeanDefinitionHolder registerPostProcessor(
    1. BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
    2. // BD设置role
    3. definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    4. // 把该BD放入到beanDefinitionMap和beanDefinitionNames
    5. registry.registerBeanDefinition(beanName, definition);
    6. // 生成BDHoder
    7. return new BeanDefinitionHolder(definition, beanName);
    }

@Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { // 代码省略 if (hasBeanCreationStarted()) { ….. } else { // Still in startup registration phase // 放入到beanDefinitionMap和beanDefinitionNames this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } // 代码省略…. }

  1. <a name="6067b6d7"></a>
  2. #### 1.3、初始化 基于classpath的beanDefinition扫描器
  3. ```java
  4. //调用父类无参的构建函数new出一个DefaultListableFactory
  5. public AnnotationConfigApplicationContext() {
  6. /**
  7. * 1.2 初始化基于注解的beanDefinition扫描器
  8. * 把处理注解的bean定义 放入到容器中
  9. */
  10. this.reader = new AnnotatedBeanDefinitionReader(this);
  11. //1.3初始化 基于classpath的beanDefinition扫描器 默认使用的是这个
  12. this.scanner = new ClassPathBeanDefinitionScanner(this);
  13. }

详细代码:

  1. public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
  2. this(registry, true);
  3. }
  4. public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
  5. this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
  6. }
  7. // useDefaultFilters = true
  8. public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
  9. Environment environment, @Nullable ResourceLoader resourceLoader) {
  10. this.registry = registry;
  11. if (useDefaultFilters) {
  12. // 初始化默认的包扫描过滤器,主要是 3类注解扫描
  13. registerDefaultFilters();
  14. }
  15. // ClassPathBeanDefinitionScanner设置enviroment
  16. setEnvironment(environment);
  17. // 设置classLoader
  18. setResourceLoader(resourceLoader);
  19. }

核心函数是registerDefaultFilters(),看一下里面的具体的实现:

  1. protected void registerDefaultFilters() {
  2. // 加入扫描@Component注解的过滤器,这样就能扫到 @Component注解 以及其派生注解 @Controller,@Service,Repository...
  3. // 这里的this是 ClassPathBeanDefinitionScanner
  4. this.includeFilters.add(new AnnotationTypeFilter(Component.class));
  5. // 获取到类加载器ClassLoader
  6. ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
  7. try {
  8. this.includeFilters.add(new AnnotationTypeFilter(
  9. ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
  10. logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
  11. }
  12. catch (ClassNotFoundException ex) {
  13. // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
  14. }
  15. try {
  16. this.includeFilters.add(new AnnotationTypeFilter(
  17. ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
  18. logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
  19. }
  20. catch (ClassNotFoundException ex) {
  21. // JSR-330 API not available - simply skip.
  22. }
  23. }

到此完成了BeanFactory,注解后处理PostProcessorAnnotationTypeFilter初始化(includeFilters的加入了AnnotationTypeFilter)。

参考文章

https://juejin.cn/post/6982118467126198309