当前位置: 首页 > 知识库问答 >
问题:

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

边健
2023-03-14

我正在使用不同作用域的bean开发一个Spring应用程序。许多bean是单例的,有其他请求或自定义的作用域。特别是,使用这些自定义作用域有时很难找出哪个作用域可以安全地注入到其他作用域中,或者何时需要使用提供程序

我知道我可以为所有基本上不是单例的bean创建范围代理,但在许多情况下,这似乎是不必要的。例如,一个bean可能只应该被注入到相同范围的其他bean,但并不是每个在项目中工作的人都知道这一点。因此,如果人们能以某种方式防止这些豆子的“误用”,那就太好了,尤其是如果人们不能总是及时认识到错误的话。

所以我的问题是:是否有某种方法可以定义哪些作用域可以安全地注入到wich作用域中,然后防止作用域较窄的bean直接(不使用provider )被注入到例如singleton bean中?

共有1个答案

卜泓
2023-03-14

使用自定义的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;
  }
}

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

  • 单例可以注入到所有东西中
  • 一切都可以注入原型
  • AOP代理可以注入到所有东西
  • 所有内容都可以注入到相同作用域的bean中
@Bean
@Scope("prototype")
@InjectableInto("singleton")
MyBean getMyBean(){
  //...
} 
 类似资料:
  • 问题内容: 我有一个现有的代码,其中应用程序根据很多条件生成不同的sql并通过hibernate会话createSQLQuery()执行它们。在这里,这些参数与作为普通字符串替换驻留在java类中的sql字符串相连接。现在的问题是,我需要防止sql注入。因此,为此,我必须使用getNamedQuery()并绑定参数,以便hibernate将处理特殊字符。但是问题在于将字符串sql的字符串移动到xm

  • 在中是否存在防止SQL注入的好方法? 我将此方法用于。实际上,我在查询中使用用户给出的字符串参数。 有什么想法吗?

  • 我正在尝试验证注释框的输入,以便只接受文本,并在用户输入数字(1-0)或符号(@\$%)时提醒消息^ 有没有办法在html中做到这一点

  • 所谓 SQL 注入,就是通过把 SQL 命令插入到 Web 表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。具体来说,它是利用现有应用程序,将(恶意)的 SQL 命令注入到后台数据库引擎执行的能力,它可以通过在 Web 表单中输入(恶意)SQL 语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行 SQL 语句。比如先前的很多影视网站泄露 VI

  • 问题内容: 考虑以下请求范围的CDI bean: 现在,我将其注入到应用程序范围的bean中: 我运行了这段代码,并注意到两个请求之间的请求范围的Bean实例是不同的,但应用程序范围的Bean实例是相同的。我的疑问是:这如何运作?在每个请求时,是否将请求范围的Bean实例重新分配给应用程序范围的字段?还是应用程序范围的bean的代理只是在请求之间改变? 问题答案: 在CDI中,每个注入的对象实际上

  • 如果我尝试用web感知范围(即会话范围、请求范围)注入bean,那么注入器会忽略该bean。未调用bean方法和对象构造函数。这只发生在我声明的类上,因为我可以为标准库类型(如List或Map)注入会话范围的bean。此外,如果我使用单例或原型作用域,则注入工作正常。 有人能解释这种奇怪的行为吗?我创建了一个准系统样本来演示这个问题。(我也尝试搜索,但找不到遇到此问题的任何人。 我想注入的类 配置