为列表中的每个bean调用PostConstruct



我有以下伪代码:

@Bean
public List<BeanB> beanB(
List<BeanA> beansA) {
List<BeanB> beansB = new ArrayList<>();
for (BeanA beanA : beansA) {
beansB.add(new BeanB(beanA))
}
return beansB;
}
@Bean
public BeanC beanC(
List<BeanB> beansB) {
return new BeanC(beansB);
}

现在的挑战是,当构建BeansB列表时,没有对列表中的那些bean调用构造。是否有惯用的方法来触发这些bean上的构造后调用?

这不能很好地工作,因为@PostConstruct被Spring调用。从你的代码中,对于List<BeanB>, Spring将只尝试在List中找到@PostConstruct。如果它能找到它,它将执行@PostConstruct代码。

我怀疑你写beanA如下,以防你有@PostConstruct在beanA的类如下。

@Bean
public BeanA beanA_1() {
return new BeanA(); 
}
@Bean
public BeanA beanA_2() {
return new BeanA(); 
}
// which naming List of Bean B as beanB does not seems a good idea though
@Bean
public List<BeanB> beanB(List<BeanA> beansA) {
List<BeanB> beansB = new ArrayList<>();
for (BeanA beanA : beansA) {
beansB.add(new BeanB(beanA))
}
return beansB;
}

要使它起作用,有多种方法,我只建议其中的一些。

  1. 创建一个新的类,说BeanBCollectionWrappe包装BeanB的列表。为了使代码更健壮,我正在实现InitializingBean而不是@PostConstruct,这基本上是相同的,但允许我确保方法是afterPropertiesSet,而不是任何方法。
public class BeanBCollectionWrapper implements InitializingBean {
private List<BeanB> beansB;

public void afterPropertiesSet() throws Exception {
for (BeanB beanB: beansB) {
beanB.afterPropertiesSet();
}
}
// getter and setter
}
public class BeanB implements InitializingBean {
public void afterPropertiesSet() throws Exception {
// ...
}
}

通过使用泛型,包装器代码肯定会更好一些,比如将BeanB替换为<T extends InitializingBean>

最后一部分

@Bean
public BeanC beanC(BeanBCollectionWrapper wrapper) {
return new BeanC(wrapper.getBeansB());
}
  1. 另一种方法可以通过实现BeanPostProcessor来完成。例如,
@Component 
public class BeanBListBeanPostProcessor implements BeanPostProcessor{
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("beanB")) {
List<BeanB> beanBList = (List) bean;
for (BeanB beanB : beanBList) {
try {
beanB.afterPropertiesSet();
} catch (Exception exception) {
exception.printStackTrace();
}
}
}
return null;
}
}
public class BeanB implements InitializingBean {
public void afterPropertiesSet() throws Exception {
// ...
}
}

最新更新