BeanNameGenerator是beans體系很是重要的一個組件,主要功能是從必定的條件中計算出bean的name.若是出現問題,是能夠規避的。一樣能夠重寫解決。java
/** Map of bean definition objects, keyed by bean name */ private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<String, BeanDefinition>(256); /** Map of singleton and non-singleton bean names, keyed by dependency type */ private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64); /** Map of singleton-only bean names, keyed by dependency type */ private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<Class<?>, String[]>(64); /** List of bean definition names, in registration order */ private volatile List<String> beanDefinitionNames = new ArrayList<String>(256); /** List of names of manually registered singletons, in registration order */ private volatile Set<String> manualSingletonNames = new LinkedHashSet<String>(16); /** Cached array of bean definition names in case of frozen configuration */ private volatile String[] frozenBeanDefinitionNames;
從上面的數據中能夠看出,bean的管理基本是基於beanName的。因此如何得到beanName是一個重要的關鍵。因此深刻了解BeanNameGenerator體系是十分重要的spring
public interface BeanNameGenerator { String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry); }
BeanNameGenerator就一個方法聲明,generateBeanName的聲明並不複雜,傳遞BeanDefinition與BeanDefinitionRegistry 返回一個string類型的beanname。因此本節深刻解讀仍是比較簡單的。api
public class DefaultBeanNameGenerator implements BeanNameGenerator { @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { return BeanDefinitionReaderUtils.generateBeanName(definition, registry); } }
public static String generateBeanName(BeanDefinition beanDefinition, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException { return generateBeanName(beanDefinition, registry, false); } public static String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry, boolean isInnerBean) throws BeanDefinitionStoreException { // ((Class<?>) beanClassObject).getName() 返回的是 class的徹底限定名 // 也多是類名 String generatedBeanName = definition.getBeanClassName(); if (generatedBeanName == null) { if (definition.getParentName() != null) { //當generatedBeanName爲null,parentName不爲空。命名方式爲parentName+"$child" generatedBeanName = definition.getParentName() + "$child"; }else if (definition.getFactoryBeanName() != null) { //當generatedBeanName爲null,FactoryBeanName不爲空。命名方式爲FactoryBeanName+"$child" generatedBeanName = definition.getFactoryBeanName() + "$created"; } } if (!StringUtils.hasText(generatedBeanName)) { throw new BeanDefinitionStoreException("Unnamed bean definition specifies neither " +"'class' nor 'parent' nor 'factory-bean' - can't generate bean name"); } String id = generatedBeanName; // generatedBeanName + 「#」 + value // isInnerBean 爲true.使用系統identityHashCode做爲value,false使用自增的方法做爲value if (isInnerBean) { // Inner bean: generate identity hashcode suffix. id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + ObjectUtils.getIdentityHexString(definition); }else { int counter = -1; // 到容器裏面看看是否存在一樣名字的BeanDefinition while (counter == -1 || registry.containsBeanDefinition(id)) { counter++; id = generatedBeanName + GENERATED_BEAN_NAME_SEPARATOR + counter; } } return id; }
public class AnnotationBeanNameGenerator implements BeanNameGenerator { private static final String COMPONENT_ANNOTATION_CLASSNAME = "org.springframework.stereotype.Component"; @Override public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { // 判斷是AnnotatedBeanDefinition的實現,就從annotation得到。 if (definition instanceof AnnotatedBeanDefinition) { String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition); // 是文本就返回這個beanName,可是也有可能annotation的value是null,就後從buildDefaultBeanName得到 if (StringUtils.hasText(beanName)) { return beanName; } } return buildDefaultBeanName(definition, registry); } protected String determineBeanNameFromAnnotation(AnnotatedBeanDefinition annotatedDef) { // 得到類或者方法上全部的Annotation AnnotationMetadata amd = annotatedDef.getMetadata(); // 獲得全部annotation的類名 Set<String> types = amd.getAnnotationTypes(); String beanName = null; for (String type : types) { // 把annotation裏面的字段與value,解讀出來成map,字段名是key,value爲value AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(amd, type); // 判斷annotation是否有效,是否存在做爲beanName的字段有value if (isStereotypeWithNameValue(type, amd.getMetaAnnotationTypes(type), attributes)) { // 從註解中得到value字段的值, Object value = attributes.get("value"); if (value instanceof String) { String strVal = (String) value; if (StringUtils.hasLength(strVal)) { if (beanName != null && !strVal.equals(beanName)) { throw new IllegalStateException("Stereotype annotations suggest inconsistent " +"component names: '" + beanName + "' versus '" + strVal + "'"); } beanName = strVal; } } } } return beanName; } protected boolean isStereotypeWithNameValue(String annotationType,Set<String> metaAnnotationTypes, Map<String, Object> attributes) { // 判斷annotation的類型是不是這三種. // org.springframework.stereotype.Component // javax.annotation.ManagedBean // javax.inject.Named boolean isStereotype = annotationType.equals(COMPONENT_ANNOTATION_CLASSNAME) || (metaAnnotationTypes != null && metaAnnotationTypes.contains(COMPONENT_ANNOTATION_CLASSNAME)) || annotationType.equals("javax.annotation.ManagedBean") || annotationType.equals("javax.inject.Named"); // 而且value存在值。纔會返回true return (isStereotype && attributes != null && attributes.containsKey("value")); } protected String buildDefaultBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) { return buildDefaultBeanName(definition); } protected String buildDefaultBeanName(BeanDefinition definition) { // 得到類名 String shortClassName = ClassUtils.getShortName(definition.getBeanClassName()); // 把類名第一個字母大寫轉小寫 return Introspector.decapitalize(shortClassName); } }
org.springframework.stereotype.Component#value() org.springframework.stereotype.Repository#value() org.springframework.stereotype.Service#value() org.springframework.stereotype.Controller#value() javax.inject.Named#value() javax.annotation.ManagedBean#value()ide
當註解的value字段不存在值的時候,會默認把首字母小寫的類名作的beanNameui
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { this.reader.setBeanNameGenerator(beanNameGenerator); this.scanner.setBeanNameGenerator(beanNameGenerator); getBeanFactory().registerSingleton( AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator); }
public void setBeanNameGenerator(BeanNameGenerator beanNameGenerator) { this.beanNameGenerator = beanNameGenerator; }
@Override public Object getBean(String name) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { assertBeanFactoryActive(); return getBeanFactory().getBean(name, requiredType); }
@Override public Object getBean(String name) throws BeansException { return getBean(name, Object.class); } @Override public <T> T getBean(String name, Class<T> requiredType) throws BeansException { try { if (isSingleton(name)) { return doGetSingleton(name, requiredType); } else { return lookup(name, requiredType); } } catch (NameNotFoundException ex) { throw new NoSuchBeanDefinitionException(name, "not found in JNDI environment"); } catch (TypeMismatchNamingException ex) { throw new BeanNotOfRequiredTypeException(name, ex.getRequiredType(), ex.getActualType()); } catch (NamingException ex) { throw new BeanDefinitionStoreException("JNDI environment", name, "JNDI lookup failed", ex); } } private <T> T doGetSingleton(String name, Class<T> requiredType) throws NamingException { synchronized (this.singletonObjects) { if (this.singletonObjects.containsKey(name)) { Object jndiObject = this.singletonObjects.get(name); if (requiredType != null && !requiredType.isInstance(jndiObject)) { throw new TypeMismatchNamingException( convertJndiName(name), requiredType, (jndiObject != null ? jndiObject.getClass() : null)); } return (T) jndiObject; } T jndiObject = lookup(name, requiredType); this.singletonObjects.put(name, jndiObject); return jndiObject; } }