Spring源码分析之组件扫描通用配置类

本文深入探讨了Spring框架中组件扫描的通用配置类,重点关注如何注册CommonAnnotationBeanPostProcessor,处理bean属性值,以及资源元数据的查找和注入过程。详细分析了Resource注解的使用,包括懒加载和直接从bean工厂获取bean的逻辑。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

注册通用配置处理类CommonAnnotationBeanPostProcessor

// 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));
}

设置解析的注解信息

public CommonAnnotationBeanPostProcessor() {
  setOrder(Ordered.LOWEST_PRECEDENCE - 3);
  setInitAnnotationType(PostConstruct.class);
  setDestroyAnnotationType(PreDestroy.class);
  ignoreResourceType("javax.xml.ws.WebServiceContext");
}

实现接口InstantiationAwareBeanPostProcessor,执行postProcessPropertyValues方法,进行bean的属性值处理

public PropertyValues postProcessPropertyValues(
    PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {

  InjectionMetadata metadata = findResourceMetadata(beanName, bean.getClass(), pvs);
  try {
    metadata.inject(bean, beanName, pvs);
  }
  catch (Throwable ex) {
    throw new BeanCreationException(beanName, "Injection of resource dependencies failed", ex);
  }
  return pvs;
}

查找资源元数据


private InjectionMetadata findResourceMetadata(String beanName, final Class<?> clazz, PropertyValues pvs) {
  // Fall back to class name as cache key, for backwards compatibility with custom callers.
  String cacheKey = (StringUtils.hasLength(beanName) ? beanName : clazz.getName());
  // Quick check on the concurrent map first, with minimal locking.
  InjectionMetadata metadata = this.injectionMetadataCache.get(cacheKey);
  if (InjectionMetadata.needsRefresh(metadata, clazz)) {
    synchronized (this.injectionMetadataCache) {
      metadata = this.injectionMetadataCache.get(cacheKey);
      if (InjectionMetadata.needsRefresh(metadata, clazz)) {
        if (metadata != null) {
          metadata.clear(pvs);
        }
        try {
          metadata = buildResourceMetadata(clazz);
          this.injectionMetadataCache.put(cacheKey, metadata);
        }
        catch (NoClassDefFoundError err) {
          throw new IllegalStateException("Failed to introspect bean class [" + clazz.getName() +
         
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值