簡體   English   中英

Spring - 在獲得 @Autowired 之前將字段注入 bean

[英]Spring - Inject fields to bean before it gets @Autowired

在 Spring 中,是否有一種機制或偵聽器來檢測帶有特定注釋的 bean 何時獲得@Autowired並在其上運行一些自定義邏輯? 類似於@ConfigurationProperties已經做的事情,它會在自動裝配之前自動注入字段。

我有一個要求,我需要在實例化之前將值注入到使用@ExampleAnnotation注釋的某些 bean 的字段中。 理想情況下,在這個聽眾中,我會:

  1. 詢問當前被實例化的 bean 是否用@ExampleAnnotation注釋
  2. 如果不是,請返回。 如果是,我會使用反射從這個 bean 中獲取字段的名稱,並使用存儲庫填充它們。

這樣的事情可能嗎?

您可以使用以下代碼實現它:

@Component
class MyBeanPostProcessor implements BeanPostProcessor, ApplicationContextAware {

    private ApplicationContext applicationContext;

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
      // Every spring bean will visit here

      // Check for superclasses or interfaces
      if (bean instanceof MyBean) {
        // do your custom logic here
        bean.setXyz(abc);
        return bean;
      }
      // Or check for annotation using applicationContext
      MyAnnotation myAnnotation = this.applicationContext.findAnnotationOnBean(beanName, MyAnnotation.class);
      if (myAnnotation != null) {
        // do your custom logic here
        bean.setXyz(myAnnotation.getAbc());
        return bean;
      }
      return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }
    
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
      this.applicationContext = applicationContext;
    }

    // Optional part. If you want to use Autowired inside BeanPostProcessors 
    // you can use Lazy annotation. Otherwise they may skip bean processing
    @Lazy
    @Autowired
    public MyBeanPostProcessor(MyLazyAutowiredBean myLazyAutowiredBean) {
    }
}

我猜如果它類似於ConfigurationProperties ,那么將屬性綁定到 bean 的 class ConfigurationPropertiesBindingPostProcessor可以作為示例。 它實現BeanPostProcessor並在postProcessBeforeInitialization方法中進行綁定。 此方法具有以下 Javadocs:

在任何 beaninitialization 回調之前將此 BeanPostProcessor 應用於給定的新 bean 實例(如 InitializingBean 的 afterPropertiesSetor 自定義 init 方法)。bean 將已填充屬性值。返回的 bean 實例可能是原始的包裝器。

一種可能的解決方案是編寫一個自定義設置器並使用@Autowired 對其進行注釋,如下所示:

@Autowired
public void setExample(Example example)
{

    // Do your stuff here.

    this.example = example;
}

但是,我不推薦這種在自動裝配之前修改 bean 的做法,因為它會導致代碼的可維護性差,並且對於其他需要處理您的代碼的人來說,這可能是違反直覺的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM