java 使用Spring防止注入范围较窄的Bean

cld4siwp  于 2022-11-20  发布在  Java
关注(0)|答案(1)|浏览(150)

我正在开发一个Spring应用程序,它使用了不同作用域的bean。许多bean都是单例的、其他请求的或自定义作用域的。特别是使用这些自定义作用域时,有时很难确定哪个作用域可以安全地注入到哪个其他作用域中,或者何时需要使用Provider<T>
我知道我可以为所有基本上不是单例的bean创建作用域代理,但在很多情况下,这似乎并不必要。例如,一个bean可能只被认为是注入到同一作用域的其他bean中,但并不是每个从事项目的人都知道这一点。因此,如果能以某种方式防止“滥用”这些bean,那就太好了。尤其是如果一个人不能总是及时认识到错误的话。
所以我的问题是:是否有某种方法可以定义哪些作用域可以安全地注入到哪个作用域中,然后防止具有较窄作用域的bean直接(不使用Provider<T>)注入到例如单例bean中?

oknwwptz

oknwwptz1#

看起来使用自定义的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注入到另一个作用域中,则需要使用相应的注解显式允许:

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

相关问题