除了未明确指定名称的情况外,Spring Bean名称很简单。 首先, 这种方式为基于XML的bean定义指定Spring bean名称:

<bean name='sampleService1' class='mvcsample.beanname.SampleService'>
 <constructor-arg>
  <bean class='mvcsample.beanname.SampleDao'></bean>
 </constructor-arg>
</bean>

对于基于Java @Configuration的Bean定义,带@Bean注释的方法的方法名称将成为Bean名称:

@Configuration
@ComponentScan(basePackages='mvcsample.beanname')
public static class SpringConfig{

 @Bean
 public SampleService sampleService(){
  return new SampleService(sampleDao());
 }

 @Bean
 public SampleDao sampleDao(){
  return new SampleDao();
 }

}

对于基于构造型注释 (@ Component,@ Service,@ Repository等)的bean,值字段指示bean名称:

@Repository('aSampleDao')
public class SampleDao {
    ...
}

@Service('aSampleService')
public class SampleService {
    ...
}

现在,在未指定Bean名称的情况下会发生什么。

基于XML的Bean配置案例:

对于基于xml的配置,通常不指定Bean名称的情况适用于可以作用于整个Bean工厂的Bean,例如,例如定义BeanPostProcessorBeanFactoryPostProcessor 。 考虑下面的虚拟BeanPostProcessor,它仅从Bean工厂获取所有Bean名称:

public class BeanNameScanningBeanPostProcessor implements BeanPostProcessor{
 private List<String> beanNames = new ArrayList<>();
 @Override
 public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
  return bean;
 }

 @Override
 public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
  beanNames.add(beanName);
  return bean;
 }

 public List<String> getBeanNames(){
  return this.beanNames;
 }
}

通常可以通过以下方式在xml bean配置中定义它:

<bean class='mvcsample.beanname.BeanNameScanningBeanPostProcessor'/>

第二种情况是基于XML的配置,其中通常不指定名称,例如内部Bean。 这样定义:

<bean class='mvcsample.beanname.SampleService'>
 <constructor-arg>
  <bean class='mvcsample.beanname.SampleDao'></bean>
 </constructor-arg>
</bean>

这些情况下的Bean名称由一个名为BeanNameGenerator的组件处理。 对于顶级bean,该名称通常以符合包的类名以及实例数的形式结束,这种方式是:

mvcsample.beanname.BeanNameScanningBeanPostProcessor#0

对于内部bean,由于它仅存在于其包含bean的范围内,因此名称并不相关,但是在内部,它确实基于bean定义的十六进制哈希码(例如'mvcsample)获得名称。 beanname.SampleDao#1881ee8b'

基于Java的@Configuration案例:

另一方面,对于基于Java的@Configuration,无法指定没有名称的bean,bean名称是方法名。

基于注释的配置

对于基于构造型注释的Bean,如果未使用构造型注释的value字段显式指定名称,则该名称再次由AnnotationBeanNameGenerator生成,后者是BeanNameGenerator策略接口的实现,生成的名称只是该类的简称。 ,例如从AnnotationBeanNameGenerator的javadoc中获取-com.xyz.FooServiceImpl的bean名称变为fooServiceImpl。

结论:

因此,最后得出结论,如果Bean名称以某种方式与您相关(例如,为了消除多个相同类型的Bean实例之间的歧义),则最好明确名称,否则依靠Spring生成用于您。 在某些情况下,例如 使用Spring-data项目,可以将存储库的自定义行为指定为单独的Bean,
默认情况下,Spring-data使用Spring命名约定来查找自定义实现,并且了解如何生成Bean名称会有所帮助。

翻译自: https://www.javacodegeeks.com/2013/02/spring-bean-names.html