@PostConstruct和@PreDestroy注解

如果支持JSR-250,就会添加CommonAnnotationBeanPostProcessor到 Spring容器。 JSR-250 规范依赖于JSR-175,因此也是基于Java SE 5.0。

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
  BeanDefinitionRegistry registry, @Nullable Object source) {
  // 略。。。
  
  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));
  }
  
  // 略。。。
}

CommonAnnotationBeanPostProcessor的构造器

// CommonAnnotationBeanPostProcessor
public CommonAnnotationBeanPostProcessor() {
  setOrder(Ordered.LOWEST_PRECEDENCE - 3);
  // 设置 InitAnnotationType 为 PostConstruct 注解类
  setInitAnnotationType(PostConstruct.class);
  // 设置 DestroyAnnotationType 为 PreDestroy 注解类
  setDestroyAnnotationType(PreDestroy.class);
  ignoreResourceType("javax.xml.ws.WebServiceContext");
}

CommonAnnotationBeanPostProcessor调用父类InitDestroyAnnotationBeanPostProcessor#setInitAnnotationType方法

// InitDestroyAnnotationBeanPostProcessor
public void setInitAnnotationType(Class<? extends Annotation> initAnnotationType) {
  this.initAnnotationType = initAnnotationType;
}

因为InitDestroyAnnotationBeanPostProcessor实现DestructionAwareBeanPostProcessor接口,也是一个BeanPostProcessor,所以会在容器初始化时,调用其BeanPostProcessor#postProcessBeforeInitialization方法
并且会销毁对象时调用DestructionAwareBeanPostProcessor#postProcessBeforeDestruction方法

@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  // 找到 LifecycleMetadata,LifecycleMetadata 对象有 PostConstruct 注解的方法和 PreDestroy 注解的方法
  LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
  try {
    // 这里也就是执行 @PostConstruct 注解的方法
    metadata.invokeInitMethods(bean, beanName);
  }
  catch (InvocationTargetException ex) {
    throw new BeanCreationException(beanName, "Invocation of init method failed", ex.getTargetException());
  }
  catch (Throwable ex) {
    throw new BeanCreationException(beanName, "Failed to invoke init method", ex);
  }
  return bean;
}

@Override
public void postProcessBeforeDestruction(Object bean, String beanName) throws BeansException {
  LifecycleMetadata metadata = findLifecycleMetadata(bean.getClass());
  try {
    // 这里也就是执行 @PreDestroy 注解的方法
    metadata.invokeDestroyMethods(bean, beanName);
  }
  catch (InvocationTargetException ex) {
    String msg = "Destroy method on bean with name '" + beanName + "' threw an exception";
    if (logger.isDebugEnabled()) {
      logger.warn(msg, ex.getTargetException());
    }
    else {
      logger.warn(msg + ": " + ex.getTargetException());
    }
  }
  catch (Throwable ex) {
    logger.warn("Failed to invoke destroy method on bean with name '" + beanName + "'", ex);
  }
}

private LifecycleMetadata findLifecycleMetadata(Class<?> clazz) {
  if (this.lifecycleMetadataCache == null) {
    // 如果缓存不存在,直接创建LifecycleMetadata
    return buildLifecycleMetadata(clazz);
  }
  LifecycleMetadata metadata = this.lifecycleMetadataCache.get(clazz);
  // 用了DCL,从缓存里获取LifecycleMetadata
  // 如果不存在,则创建LifecycleMetadata,并放入缓存
  if (metadata == null) {
    synchronized (this.lifecycleMetadataCache) {
      metadata = this.lifecycleMetadataCache.get(clazz);
      if (metadata == null) {
        metadata = buildLifecycleMetadata(clazz);
        this.lifecycleMetadataCache.put(clazz, metadata);
      }
      return metadata;
    }
  }
  return metadata;
}

private LifecycleMetadata buildLifecycleMetadata(final Class<?> clazz) {
  List<LifecycleElement> initMethods = new ArrayList<>();
  List<LifecycleElement> destroyMethods = new ArrayList<>();
  Class<?> targetClass = clazz;

  // 不断向上找父类,找 PostConstruct 注解的方法和 PreDestroy 注解的方法
  do {
    final List<LifecycleElement> currInitMethods = new ArrayList<>();
    final List<LifecycleElement> currDestroyMethods = new ArrayList<>();

    ReflectionUtils.doWithLocalMethods(targetClass, method -> {
      if (this.initAnnotationType != null && method.isAnnotationPresent(this.initAnnotationType)) {
        // 如果方法上有 PostConstruct 注解,创建 LifecycleElement 对象
        LifecycleElement element = new LifecycleElement(method);
        currInitMethods.add(element);
        if (logger.isTraceEnabled()) {
          logger.trace("Found init method on class [" + clazz.getName() + "]: " + method);
        }
      }
      if (this.destroyAnnotationType != null && method.isAnnotationPresent(this.destroyAnnotationType)) {
        // 如果方法上有 PreDestroy 注解,创建 LifecycleElement 对象
        currDestroyMethods.add(new LifecycleElement(method));
        if (logger.isTraceEnabled()) {
          logger.trace("Found destroy method on class [" + clazz.getName() + "]: " + method);
        }
      }
    });
    // 添加到 initMethods 集合
    initMethods.addAll(0, currInitMethods);
    // 添加到 destroyMethods 集合
    destroyMethods.addAll(currDestroyMethods);
    targetClass = targetClass.getSuperclass();
  }
  while (targetClass != null && targetClass != Object.class);
  // 返回LifecycleMetadata对象
  return new LifecycleMetadata(clazz, initMethods, destroyMethods);
}

@PostConstruct方法:

  • 方法必须没有任何参数,除非是拦截器,在这种情况下,它接受interceptors规范定义的InvocationContext对象
  • 非拦截器的方法,不能有返回值
  • 除了应用程序客户端之外,该方法不能是静态的
  • 方法可以是 final 的

综上所述,Constructor@Autowired@PostConstruct这三者的执行顺序是:Constructor > @Autowired > @PostConstruct


欢迎小伙伴们积极指正和讨论,一起共同成长。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值