检测未使用的Spring bean

时间:2016-03-16 22:51:11

标签: java spring-boot spring-bean dead-code

如果一个Spring配置专门包含eager(非延迟)单例bean,即默认值,那么在任何那些bean没有注入任何地方的情况下,是否可以让Spring抛出异常?我本质上是在寻找一种以Spring bean的形式检测死代码的方法。

我的问题有点类似于这些。

然而,

  • 我对手动检查图表或解析日志数据不感兴趣。
  • 我没有增加多个上下文文件,覆盖bean,bean后期处理或xml的复杂性。它是一个简单,直接,注释驱动的配置。
  • 我使用的是Spring Boot 1.2.6,它比那些问题要新几年(可能还有新的功能)。
如果缺少必要的bean,Spring肯定会抛出异常。它是否也会在相反的情况下抛出异常,在这种情况下找到bean但不必要?

1 个答案:

答案 0 :(得分:1)

  

如果必不可少的bean是Spring,肯定会引发异常。   失踪。在相反的情况下,它还能引发异常吗?   找到了一个豆但是没有必要吗?

TL / DR

Spring不支持(也许永远不会)。

长版:

很难确定是否使用了bean。

首先,让我们定义spring什么时候抛出“ missing bean”异常。

在spring上下文的初始化期间,spring将按照允许满足所有依赖关系的顺序创建bean(如果可能)。如果bean缺少依赖项,spring将抛出异常(如您所说)。 因此,在 spring上下文初始化过程中会引发异常。

现在,您可以说我们可以监视此过程并查找未在任何其他Bean中用作依赖项的Bean。 问题在于在 spring上下文初始化过程中并不是所有的bean依赖项都被定义。

让我们看下面的示例:

首先,我们有一个简单的界面DataService

public interface DataService {
 String getData();
}

现在我们有2个实现该接口的spring bean:

@Service("firstDataService")
public class FirstDataService implements DataService {

  @Override
  public String getData() {
    return "FIRST DATA SERVICE";
  }
}

@Service("secondDataService")
public class SecondDataService implements DataService {
  @Override
  public String getData() {
    return "SECOND DATA SERVICE";
  }
}

现在,假设没有一个直接依赖于这两个bean的bean。当我直接说的时候,我的意思是没有通过constructor-basedsetter-basedfield-based依赖注入依赖于这些bean的bean。

因此,在上下文初始化过程中,spring不会将这些bean注入任何其他bean中。

现在,考虑以下bean:

@Service
public class DataCollector {

  @Autowired
  ApplicationContext applicationContext;


  String getDataFromService(String beanName) {
    DataService ds = (DataService) applicationContext.getBean(beanName);
    return ds.getData();
  }
}

如果我使用getDataFromService参数的“ firstDataService”值调用DataCollector bean的beanName方法,结果该方法将返回“ FIRST DATA SERVICE”。 如果我使用“ secondDataService”调用该方法,则结果将返回“ SECOND DATA SERVICE”。

现在,当spring在上下文初始化期间查看DataController的定义时,无法确定DataCollector依赖哪个bean。 这完全取决于应用程序逻辑以及调用beanName方法时用于getDataFromService参数的值。

因此,spring无法确定是否存在从未使用过的bean(因为如上例所示,bean的使用可以是动态的)。