Spring构造函数初始化this( )-01

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

1、初始化AnnotationConfigApplicationContext

入口代码:

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

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

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

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

/**
  * Create a new GenericApplicationContext.
  * @see #registerBeanDefinition
  * @see #refresh
  */
 public GenericApplicationContext() {
  this.beanFactory = new DefaultListableBeanFactory();
 }

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

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

其中构造函数的this.reader = new AnnotatedBeanDefinitionReader(this);主要的作用是:

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

public AnnotationConfigApplicationContext() {
  this.reader = new AnnotatedBeanDefinitionReader(this);
  this.scanner = new ClassPathBeanDefinitionScanner(this);
}

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
  Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
  Assert.notNull(environment, "Environment must not be null");
  //传递过来的 AnnotationConfigApplicationContext bean定义 容器
  this.registry = registry;
  /**
   * 用于计算判断 {@link Conditional} 注解
   */
  this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
  /**
   * 1.1.1注册 所相关注解的后置处理器 到registry
   */
  AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
 }

  • 几个细节问题看一下,我们可以看到传到AnnotatedBeanDefinitionReader()方法的第一个参数是BeanDefinitionRegistry。这个猜测就是AnnotationConfigApplicationContext的接口。一看代码果然是的。下面是关于BeanDefinitionRegistry接口的定义,从中看到这个接口主要定义的是注册删除获取是否包含判断BeanName是否使用的一些接口,也就是定义关于BeanDefinition常用操作的接口。
public interface BeanDefinitionRegistry extends AliasRegistry {
    void registerBeanDefinition(String var1, BeanDefinition var2) throws BeanDefinitionStoreException;

    void removeBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    BeanDefinition getBeanDefinition(String var1) throws NoSuchBeanDefinitionException;

    boolean containsBeanDefinition(String var1);

    String[] getBeanDefinitionNames();

    int getBeanDefinitionCount();

    boolean isBeanNameInUse(String var1);
}

核心逻辑是AnnotationConfigUtils.registerAnnotationConfigProcessors
调用工具类注册 AnnotationConfigProcessors, 也就是配置的前置处理器
而就是在这个方法中完成了对多个重要Bean的注册

/**
* Register all relevant annotation post processors in the given registry.
* @param registry the registry to operate on
*/
public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
  registerAnnotationConfigProcessors(registry, null);
}

/**
  * Register all relevant annotation post processors in the given registry.
  * @param registry the registry to operate on
  * @param source the configuration source element (already extracted)
  * that this registration was triggered from. May be {@code null}.
  * @return a Set of BeanDefinitionHolders, containing all bean definitions
  * that have actually been registered by this call
  */
public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(BeanDefinitionRegistry registry, Object source) {

  DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
  if (beanFactory != null) {
   if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
    beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
   }
   if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
    beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
   }
  }

     // 1、BeanDefinitionHolder只是存放BD的,里面有三个属性:BD对象、beanName以及别名组成的String[]
  Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

     // 注册最关键的类,对应的类为ConfigurationClassPostProcessor,父类的父类是BeanFactoryPostProcessor
     // 判断register是否包含 internalConfigurationAnnotationProcessor名称的BeanDefinition,初始化是不包含的
  if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
   def.setSource(source);
            // 将BD注入进容器中,没经过什么处理,只是放入了DefaultListableBeanFactory中的beanDefinitionMap跟存放beanName的list中
   beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
  }

     // 此类实现了BeanPostProcessor,用于处理@Autowired、@Value注解
  if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
   def.setSource(source);
   beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
  }

  // Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
  if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
   def.setSource(source);
   beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
  }

  // Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
  if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   RootBeanDefinition def = new RootBeanDefinition();
   try {
    def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
      AnnotationConfigUtils.class.getClassLoader()));
   }
   catch (ClassNotFoundException ex) {
    throw new IllegalStateException(
      "Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
   }
   def.setSource(source);
   beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
  }

  if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
   RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
   def.setSource(source);
   beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
  }

  if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
   RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
   def.setSource(source);
   beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
  }

  return beanDefs;
 }

  • 这段代码使我们的核心逻辑,我们首先看看第一个比较重要的类BeanDefinitionHolder。_BeanDefinitionHolder_是BeanDefinition的封装类, 封装了BeanDefinition、Bean的名字和别名, 用它来完成向IoC容器注册

  • 这这一段后面一直重复的逻辑

/**
* The bean name of the internally managed Configuration annotation processor.
*/
public static final String CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME =
   "org.springframework.context.annotation.internalConfigurationAnnotationProcessor";

if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
   RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
   def.setSource(source);
            // 将BD注入进容器中,没经过什么处理,只是放入了DefaultListableBeanFactory中的beanDefinitionMap跟存放beanName的list中
   beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}

  1. registryAnnotationConfigApplicationContext类实例,AnnotationConfigApplicationContext是继承了GenericApplicationContext类,这个类继承了抽象类AbstractApplicationContext。这个里面实现了containsBeanDefinition(String beanName)方法。这个方法,最终还是调用的是DefaultListableBeanFactory Bean工厂的方法containsBeanDefinition(beanName)完成的。

  2. new RootBeanDefinition(ConfigurationClassPostProcessor.class);创建的是BeanDefinition的定义

  3. registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)这行代码会调用GenericApplicationContextregisterBeanDefinition(beanName,beanDefinition)方法,然后这个方法就是会获取到DefaultListableBeanFactory Bean工厂的registerBeanDefinition方法。这个方法会放入到DefaultListableBeanFactorythis.beanDefinitionMap属性中存起来。

1.2、初始化 基于classpath的beanDefinition扫描器
public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
  this(registry, true);
}

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

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

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

  if (useDefaultFilters) {
            // 初始化默认的包扫描过滤器,主要是 3类注解扫描
   registerDefaultFilters();
  }
     // ClassPathBeanDefinitionScanner设置enviroment
  setEnvironment(environment);
     // 设置classLoader
  setResourceLoader(resourceLoader);
 }

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

protected void registerDefaultFilters() {
  // 加入扫描@Component注解的过滤器,这样就能扫到 @Component注解 以及其派生注解 @Controller,@Service,Repository...
     // 这里的this是 ClassPathBeanDefinitionScanner
  this.includeFilters.add(new AnnotationTypeFilter(Component.class));
     // 获取到类加载器ClassLoader
  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.
  }
 }

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

参考文章

https://juejin.cn/post/6982118467126198309

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值