我们给 spring 注释命名是有原因的吗?

Is there a reason that we give spring annotation a name?

我注意到在为 spring 或 spring mvc 使用注解时,一些程序员会为注解连同一个名称。例如:

@Repository("customerRepository")
public class CustomerRepositoryImpl implements CustomerRepository{
}

我相信 class 在不给 @Repository 命名的情况下也能发挥同样的作用。会不会有命名注解有用的情况?

如果自动检测到,它有助于将实体转换为 Spring bean。

来自官方文档here:-

The value may indicate a suggestion for a logical component name, to be turned into a Spring bean in case of an autodetected component.

主要是为了解决执行自动扫描和使用时的歧义@Autowired. I gave a thorough answer explaining about @Autowired in this answer,这也解释了命名bean的需要。

假设我们有 2 个 class 实现 CustomerRepository:

@Repository
public class MyCustomerRepositoryImpl implements CustomerRepository {
}

@Repository
public class OtherCustomerRepositoryImpl implements CustomerRepository {
}

现在假设我们有一个 class 使用 @Autowired 注入 CustomerRepository:

public class SomeClass {
  @Autowired
  private CustomerRepository customerRepository;
}

执行自动扫描时,您需要有办法区分它们。否则 Spring 会抛出一个异常,说明它无法判断应该注入哪个 bean。

所以我们现在可以为每个实现添加一个逻辑名称:

@Repository("myRepository")
public class MyCustomerRepositoryImpl implements CustomerRepository {
}

@Repository("otherRepository")
public class OtherCustomerRepositoryImpl implements CustomerRepository {
}

现在你可以帮助Spring解决歧义如下:

public class SomeClass {
  @Autowired
  @Qualifier("myRepository")
  private CustomerRepository customerRepository;
}

AnnotationBeanNameGenerator 负责为您的 bean 取一个名称。如果您指定一个名称,您可以为您的 bean 名称使用不同的约定,而不是根据 class 名称生成的名称。

自动生成的bean 名称并非万无一失;两个具有相同名称的 class 会导致重复的 bean 定义,两个 class 会继承相同的接口。

使用显式名称还可以确保代码重构不会隐式破坏 bean 连接。