除了未明确指定名称的情况外,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,例如,例如定义BeanPostProcessor或BeanFactoryPostProcessor 。 考虑下面的虚拟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