使用Spring防止注入范围更窄的bean

时间:2018-11-29 12:45:48

标签: java spring dependency-injection

我正在使用不同范围的Bean开发Spring应用程序。许多bean是单例,其他请求或自定义范围的。特别是使用那些自定义范围使有时很难找出可以安全地注入到其他范围中的范围,或何时将其注入。需要使用Provider<T>

我知道我可以为基本上不是单例的所有bean创建作用域代理,但是在许多情况下似乎没有必要。例如,可能只应将一个bean注入到相同范围的其他bean中,但并非每个从事该项目的人都可能意识到这一点。因此,如果人们能够以某种方式防止这些bean的“滥用”,那将是很棒的,特别是如果人们可能不总是及时地发现错误。

所以我的问题是:有没有办法定义可以将哪个范围安全地注入到最广泛的范围中,然后防止范围更窄的bean直接(不使用Provider<T>)注入到例如单身豆吗?

1 个答案:

答案 0 :(得分:0)

使用自定义BeanPostProcessor可以很简单地实现这一目标。在postProcessBeforeInitialization中,您可以简单地检查bean的范围和所有依赖项的范围。这是一个简单的示例:

@Component
public class BeanScopeValidator implements BeanPostProcessor {

  private final ConfigurableListableBeanFactory configurableBeanFactory;

  @Autowired
  public BeanScopeValidator(ConfigurableListableBeanFactory configurableBeanFactory) {
    this.configurableBeanFactory = configurableBeanFactory;
  }

  @Override
  public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    String beanScope = configurableBeanFactory.getBeanDefinition(beanName).getScope();
    String[] dependenciesForBean = configurableBeanFactory.getDependenciesForBean(beanName);

    for (String dependencyBeanName : dependenciesForBean) {
      String dependencyBeanScope = configurableBeanFactory.getBeanDefinition(dependencyBeanName).getScope();

      // TODO: Check if the scopes are compatible and throw an exception
    }

    return bean;
  }
}

该示例仍然非常基础,使用起来并不方便。最突出的是,它缺乏定义可以将哪个范围注入到其他范围的能力。因此,我创建了一个更完整的示例here。使用该项目,默认情况下允许以下注入:

  • 可以将东西注入所有东西
  • 一切都可以注入原型
  • 可以将AOP代理注入所有内容
  • 一切都可以注入到相同范围的豆子中

如果要允许将bean注入另一个作用域,则需要使用相应的注释明确允许它:

@Bean
@Scope("prototype")
@InjectableInto("singleton")
MyBean getMyBean(){
  //...
}