spring bean 이름 에 대한 자세 한 설명

머리말
여러 해 동안 spring 을 사 용 했 습 니 다.물론 spring 의 기본 beanName 을 유사 한 이름 의 이니셜 소문 자로 생각 했 습 니 다.예 를 들 어 Hello Service 의 beanName 은 hello Service 입 니 다.어느 날 공급 업 체 의 인 터 페 이 스 를 연결 할 때 까지 그 는 ABService 와 같은 유형 이 있어 서 사용 했다.

getBean(“aBService”)
bean 을 가 져 오 는 방식 입 니 다.결 과 는 null 입 니 다.처음에는 ABservice 가 주입 되 지 않 은 줄 알 았 는데 나중에 사 용 했 습 니 다.

getBean(ABService.class)
bean 을 성공 적 으로 얻 을 수 있 습 니 다.ABC 서 비 스 는 IOC 용기 에 주입 되 어 있 지만 왜 aBService 로 bean 을 얻 지 못 합 니까?따라서 다음 코드 세그먼트 로 ABService 에 대응 하 는 beanName 을 출력 합 니 다.

applicationContext.getBeansOfType(ABService.class).forEach((beanName,bean)->{
            System.out.println(beanName + ":" + bean);
        });
인쇄 된 결 과 는 다음 과 같다.
ABService:com.github.lybgeek.ABService@245b6b85
beanName 이 ABService 라 니,이것 은 당연히 이전의 생각 과 차이 가 있 습 니 다.그래서 소스 코드 를 볼 수 밖 에 없 었 습 니 다.
02 원본 보기
원본 코드 를 보면 두 가지 방식 이 있 는데 본 고의 예 는 springboot 프로젝트 이다.
01 main 방법 에서 정지점 직접 디 버 깅

그림 에서 알 수 있 듯 이 스 캔 주해 주입 형식 이 라면 beanName 의 생 성 규칙 은

org.springframework.context.annotation.AnnotationBeanNameGenerator#generateBeanName

결정
ps:이러한 직접 main 시작 류 디 버 깅 부터 시간 이 비교적 많 거나 조사 가 두서 가 없다.
02 질문 을 가지 고 보기,추측 과 검증 방식
아이디어 의 find Usage 를 이용 하여 인용 을 찾 습 니 다.예 를 들 어 ABService 의 주석@service,우 리 는 어떤 인용 이@Service 에 있 는 지 직접 보고 beanName 의 생 성 규칙 을 추측 할 수 있 습 니 다.

추측 을 통 해 우 리 는 기본적으로 우리 의 수요 에 비교적 부합 되 는 방법 을 찾 을 수 있다.
03 소스 코드 검증
위의 분석 을 통 해 우 리 는 bean 주 해 를 스 캔 하여 주입 하 는 방식 이 라면 beanName 규칙 을 생 성 하 는 것 이

org.springframework.context.annotation.AnnotationBeanNameGenerator

그 생 성 규칙 코드 는 다음 과 같다.

@Override
  public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
    if (definition instanceof AnnotatedBeanDefinition) {
      String beanName = determineBeanNameFromAnnotation((AnnotatedBeanDefinition) definition);
      if (StringUtils.hasText(beanName)) {
        // Explicit bean name found.
        return beanName;
      }
    }
    // Fallback: generate a unique default bean name.
    return buildDefaultBeanName(definition, registry);
  }

코드 세그먼트 에서 알 수 있 듯 이 주석 에@Service("abService")와 같은 이름 이 있 으 면 beanName 은 abService 이 고 이름 이 없 으 면 볼 수 있 습 니 다.

protected String buildDefaultBeanName(BeanDefinition definition) {
    String beanClassName = definition.getBeanClassName();
    Assert.state(beanClassName != null, "No bean class name set");
    String shortClassName = ClassUtils.getShortName(beanClassName);
    return Introspector.decapitalize(shortClassName);
  }


public static String decapitalize(String name) {
        if (name == null || name.length() == 0) {
            return name;
        }
        if (name.length() > 1 && Character.isUpperCase(name.charAt(1)) &&
                        Character.isUpperCase(name.charAt(0))){
            return name;
        }
        char chars[] = name.toCharArray();
        chars[0] = Character.toLowerCase(chars[0]);
        return new String(chars);
    }
사실 코드 에서 우 리 는 쉽게 답 을 알 수 있 습 니 다.만약 에 유형 명 앞의 두 글자 이상 이 모두 대문자 라면 beanName 과 유형 명 은 똑 같 고 이니셜 소문 자 변환 을 하지 않 습 니 다.
decapitalize 라 는 방법의 주석 도 명확 하 게 쓰 여 있 습 니 다.주석 은 다음 과 같 습 니 다.

/**
     * Utility method to take a string and convert it to normal Java variable
     * name capitalization. This normally means converting the first
     * character from upper case to lower case, but in the (unusual) special
     * case when there is more than one character and both the first and
     * second characters are upper case, we leave it alone.
     * <p>
     * Thus "FooBah" becomes "fooBah" and "X" becomes "x", but "URL" stays
     * as "URL".
     *
     * @param name The string to be decapitalized.
     * @return The decapitalized version of the string.
     */

총화
비 안 주 해 를 스 캔 하여 IOC 에 주입 할 때 비 안 이름 의 기본 규칙 이 클래스 이름 의 이니셜 소문 자로 지정 되 지 않 으 면 클래스 이름 앞의 두 글자 이상 이 대문자 라면 비 안 이름 은 클래스 이름과 같 습 니 다.
사실 이 디 테 일 은 다 알 수 있 습 니 다.본 논문 의 달걀 은 주로 평소에 소스 코드 를 보 는 소감 을 공유 하 는 것 입 니 다.하하.
spring bean 이름 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 spring bean 이름 이름 에 관 한 내용 은 예전 의 글 을 검색 하거나 아래 의 관련 글 을 계속 찾 아 보 세 요.앞으로 도 많은 응원 부 탁 드 리 겠 습 니 다!

좋은 웹페이지 즐겨찾기