今天,我们在代码中发现了这种模式:
class Foo {
private List<String> errors;
public void addError(String error) { ... }
public List<String> getErrors();
}
虽然代码似乎可以工作,但这是一个单例 Spring bean,它被注入到几个独立的位置,并且 bean 的使用者假设他们每个人都有自己的错误列表。所以这引入了微妙的错误。
显而易见的解决方案是教育开发人员避免这种错误,但我想知道是否有静态或运行时代码分析工具可以找到这种错误。
例如,bean 后处理器可以在 bean 返回之前对其进行分析,并查找不是
@Autowired
的私有字段。
在投入更多的大脑(我们和其他人的)之后,我们想出了这个方法:
BeanPostProcessor
,确保所有单例bean(即bean定义中的范围为Singleton
)在实际bean类型上都具有自定义注释@Stateless
。我们选择了自定义注释,而不是重复使用
@Singleton
,因为我们在其他地方也需要此功能。
如果缺少注释,工厂会抛出错误。
ClassPathScanningCandidateComponentProvider
来定位类路径上的所有类。然后,我们可以进行复杂且昂贵的测试,以确保 bean 在初始配置后(即自动装配发生后)没有发生变化的状态。如果我们将自动装配字段移至构造函数中,第二步可能会变得容易一些,但我们不喜欢采用很多很多参数的方法。如果 Java 或 IDE 可以从 bean 代码生成构建器,那就太好了。由于情况并非如此,我们坚持使用自动装配字段和/或设置器。
为了确保 bean 是无状态的,它必须根本没有字段,或者所有字段都必须是最终字段,并且所有非最终字段必须由 Spring 管理(即该字段必须具有常用注释之一,如
@Autowired
) .
您可以创建一个 JUnit 测试来加载您的应用程序配置。 这可以从这里组合 ListableBeanFactory :
我可以通过扫描spring配置文件中的bean来动态创建List吗?
在此处检查“isSingleton”:
即列出应用程序上下文中的所有 bean,然后检查哪些是单例。
这可以让你找到所有单例 bean...尽管它并不能真正阻止你的错误情况,即有人将这些单例之一视为不存在。