Spring Boot 는 자바 코드 를 사용 하여 Bean 을 만 들 고 Spring 에 등록 합 니 다.

9367 단어 springbootbean
Spring 3.0 부터 Bean Definition 을 설정 하 는 새로운 경 로 를 추 가 했 습 니 다.이것 이 바로 자바 코드 를 통 해 Bean Definition 을 설정 하 는 것 입 니 다.
Xml 와 Annotation 두 가지 설정 방식 과 다른 점 은:
앞의 두 가지 Xml 와 Annotation 의 설정 방식 은 미리 정 의 된 방식 입 니 다.즉,개발 자가 XML 파일 이나 Annotation 을 통 해 bean 의 각종 속성 을 미리 정의 한 후에 spring 용 기 를 시작 하면 Spring 용 기 는 먼저 이러한 설정 속성 을 분석 하여 대응 도 를 생 성 합 니까?Bean Definition,Default Listable Bean Factory 대상 의 속성 용기 에 불 러 옵 니 다.이와 함께 Spring 프레임 워 크 는 내부 에서 사용 되 는 Bean 정 의 를 정의 합 니 다.예 를 들 어 bean 이름 은'org.springframework.context.annotation.internalConfigurationAnnotationProcessor'의 ConfigurationClassPostProcessor 정 의 를 정의 합 니 다.
이후 이 때 는 Bean Definition 의 정의 해석 동작 을 하지 않 습 니 다.Spring 프레임 워 크 는 앞의 두 가지 설정 에 따라 Bean Definition Registry PostProcessor 형식의 Bean 정 의 를 걸 러 내 고 Spring 프레임 워 크 를 통 해 해당 하 는 Bean 대상(예 를 들 어 ConfigurationClassPostProcessor 인 스 턴 스)을 생 성 합 니 다.Spring 컨 텍스트 소스 코드 를 결합 하면 이 대상 은 processor 형식 도구 류 임 을 알 수 있 습 니 다.Spring 용 기 는 개발 자 들 이 정의 하 는 Bean 전에 이 processor 의 post ProcessBean Definition Registry(...)방법 을 먼저 호출 합 니 다.자바 코드 설정 Bean Definition 을 기반 으로 처리 합 니 다.
자바 코드 기반 Bean 순서 도 분석(큰 그림 보기)

자바 코드 의 설정 방식 을 바탕 으로 그 집행 원 리 는 앞의 두 가지 와 다르다.이것 은 Spring 프레임 워 크 에서 XML 과 Annotation 설정 을 분석 한 후,Bean Definition Registry PostProcessor 형식의 processor 를 추가 하여 설정 정 보 를 처리 하여 개발 자 들 이 자바 프로 그래 밍 방식 으로 자바 대상 을 정의 하도록 합 니 다.설정 정 보 를 일정 수량의 자바 대상 에 집중 시 키 는 동시에 자바 프로 그래 밍 방식 을 통 해 Annotation 방식 보다 유연성 이 높다 는 장점 이 있다.또한 이 설정 방식 은 개발 자 에 게 사용자 정의 분석 도구 류 를 추가 하 는 좋 은 범례 를 제공 합 니 다.그 주요 단점 은 자바 코드 와 밀접 하 게 결합 되 고 설정 정보의 변 화 는 자바 코드 를 다시 컴 파일 해 야 한 다 는 것 이다.또한 이것 은 새로 도 입 된 분석 방식 으로 일정한 학습 비용 이 필요 하 다.
또 하나 언급 한 것 은 Spring 프레임 워 크 는 세 가지 주요 훅 류 가 있 는데 그것 이 바로 다음 과 같다.

org.springframework.context.ApplicationContextAware 
그것 의 setapplicationContext 방법 은 Spring 이 시작 되 기 전에 첫 번 째 로 호출 될 것 입 니 다.우 리 는 Jdon 프레임 워 크 를 동시에 시작 하 는 데 사용 합 니 다.

org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor 
그것 의 post ProcessBean Definition Registry 와 post ProcessBean Factory 방법 은 두 번 째 와 세 번 째 로 호출 되 었 습 니 다.Bean 이 초기 화 되 기 전에 시작 합 니 다.만약 Spring 의 bean 이 필요 로 하 는 다른 제3자 의 구성 요소 가 있다 면,우 리 는 여기에서 Spring 에 주입 합 니 다.

org.springframework.context.ApplicationListener 
초기 화 완료 후 몇 가지 일 을 할 때 사용 합 니 다.Spring 의 모든 XML 이나 원 주해 의 Bean 이 시작 되 어 생 성 되 었 을 때 유일한 방법 인 onApplicationEvent 를 호출 합 니 다.
자바 코드 를 통 해 bean 을 만 들 고 Spring 관리 로 등록 합 니 다.
이 예 에서,우 리 는 인 터 페 이 스 를 만 든 다음,이 인터페이스의 두 개의 실현 클래스 를 만 들 고,각각 다른 이름 을 명명 한 다음,주입 할 곳 에@Qualifier 를 사용 하여 주입 에 대응 하 는 실례 를 지정 합 니 다.
1.인터페이스 Shanhy.java

package org.springboot.sample.config;

public interface Shanhy {

  void display();

}

2.실현 류 ShanhyA.java

package org.springboot.sample.config;

public class ShanhyA implements Shanhy {

  @Override
  public void display() {
    System.out.println("AAAAAAAAAAAA");
  }

}

3.실현 류 ShanhyB.java

package org.springboot.sample.config;

public class ShanhyB implements Shanhy {

  @Override
  public void display() {
    System.out.println("BBBBBBBBBBBB");
  }

}

4.인터페이스 BeanDefinition Registry PostProcessor 의 실현 을 정의 합 니 다.

package org.springboot.sample.config;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.AnnotatedGenericBeanDefinition;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionReaderUtils;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.BeanNameGenerator;
import org.springframework.context.annotation.AnnotationBeanNameGenerator;
import org.springframework.context.annotation.AnnotationConfigUtils;
import org.springframework.context.annotation.AnnotationScopeMetadataResolver;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ScopeMetadata;
import org.springframework.context.annotation.ScopeMetadataResolver;

/**
 *        bean    Spring  
 *
 * @author     (365384722)
 * @create  2016 1 21 
 */
@Configuration
public class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {

  private static final Logger logger = LoggerFactory.getLogger(MyBeanDefinitionRegistryPostProcessor.class);

  private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
  private BeanNameGenerator beanNameGenerator = new AnnotationBeanNameGenerator();

  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    logger.info("Invoke Metho postProcessBeanFactory");
    //         ,  
    BeanDefinition bd = beanFactory.getBeanDefinition("dataSourceA"); 
    MutablePropertyValues mpv = bd.getPropertyValues(); 
    mpv.addPropertyValue("driverClassName", "com.mysql.jdbc.Driver");
    mpv.addPropertyValue("url", "jdbc:mysql://localhost:3306/test");
    mpv.addPropertyValue("username", "root");
    mpv.addPropertyValue("password", "123456");
  }

  @Override
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    logger.info("Invoke Metho postProcessBeanDefinitionRegistry");
    registerBean(registry, "shanhyA", ShanhyA.class);
    registerBean(registry, "shanhyB", ShanhyB.class);
    registerBean(registry, "dataSourceA", org.apache.tomcat.jdbc.pool.DataSource.class);
  }

  private void registerBean(BeanDefinitionRegistry registry, String name, Class<?> beanClass){
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);

    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());
    //       name
    String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, registry));

    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
  }
}

5.사용 테스트
평소 와 마찬가지 로 우리 의 대상 을 직접 주입 할 수 있 습 니 다.같은 인터페이스 에 대해 서 는 name 을 지정 해 야 합 니 다.

/**
 *       
 *
 * @author     (365384722)
 * @create  2016 1 13 
 */
@Configuration
public class MyConfiguration {

  @Bean
  public FilterRegistrationBean filterRegistrationBean(@Qualifier("shanhyB") Shanhy shanhy) {
    FilterRegistrationBean filterRegistration = new FilterRegistrationBean();
    shanhy.display();
    //     
    return filterRegistration;
  }
}

@Resource 또는@Autowired 를 사용 하여@Qualifier 를 지정 하 셔 도 됩 니 다.

@RestController
@RequestMapping("/hello")
public class HelloController {

  @Resource(name="shanhyA")
  private Shanhy shanhyA;

  @Autowired
  @Qualifier("shanhyB")
  private Shanhy shanhyB;

  //     

}

여기 서 경험 이 있 습 니 다.@Configuration 에 서 는 속성 을 주입 하 는 방식 으로 주입 할 수 없습니다.매개 변수 로 만 주입 할 수 있 습 니 다.그 이 유 는@Configuration 의 클래스 가 처음에 불 러 오기 시 작 했 기 때 문 입 니 다.이때 속성 주입 을 하려 면 주입 해 야 할 bean 대상 이 존재 하지 않 습 니 다.
다음 글 은 이 방법 을 사용 하여 MyBatis 기반 의 다 중 데이터 원본 을 동적 으로 만 들 것 입 니 다.
아래 의 코드 세 션 도 Bean 을 등록 할 수 있 습 니 다.비교적 간단 합 니 다.

@Configuration
@Import(Registrar.class)
public class TestConfig {

}

class Registrar implements ImportBeanDefinitionRegistrar {

  private static final String BEAN_NAME = "myTestBean";

  @Override
  public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {

    if (!registry.containsBeanDefinition(BEAN_NAME)) {
      GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
      beanDefinition.setBeanClass(ExamplePostProcessor.class);
      beanDefinition.setSynthetic(true);
      registry.registerBeanDefinition(BEAN_NAME, beanDefinition);
    }
  }

}

이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

좋은 웹페이지 즐겨찾기