[java] Spring Controller의 Init 메소드 (주석 버전)

컨트롤러를 최신 주석 버전으로 변환하고 있습니다. 이전 버전에서는 다음을 사용하여 springmvc-servlet.xml에서 init 메소드를 지정했습니다.

<beans>
    <bean id="myBean" class="..." init-method="init"/>
</beans>

주석 버전을 사용하여 초기화 방법을 어떻게 지정할 수 있습니까?



답변

당신이 사용할 수있는

@PostConstruct
public void init() {
   // ...
}


답변

또는 클래스가 InitializingBean인터페이스를 구현 afterPropertiesSet()하여 Bean이 생성 될 때 ApplicationContext가 호출 할 콜백 함수 ( ) 를 제공하도록 할 수 있습니다 .


답변

Spring에서 초기화 프로세스를 가로채는 방법에는 여러 가지가 있습니다. 모든 bean을 초기화하고 autowire / inject해야한다면 적어도 두 가지 방법이 있습니다. 나는 두 번째 testet 만 가지고 있지만 둘 다 똑같이 작동한다고 믿습니다.

@Bean을 사용하는 경우 이와 같이 initMethod로 참조 할 수 있습니다.

@Configuration
public class BeanConfiguration {

  @Bean(initMethod="init")
  public BeanA beanA() {
    return new BeanA();
  }
}

public class BeanA {

  // method to be initialized after context is ready
  public void init() {
  }

} 

@Component를 사용하는 경우 이와 같이 @EventListener로 주석을 달 수 있습니다.

@Component
public class BeanB {

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
  }
}

제 경우에는 Spring Boot가 선택된 프레임 워크 인 IoC / DI를 사용하는 레거시 시스템이 있습니다. 이전 시스템은 테이블에 많은 순환 종속성을 가져 오므로 setter-dependency를 많이 사용해야합니다. setter에 의한 autowiring / injection이 아직 완료되지 않았기 때문에 @PostConstruct를 신뢰할 수 없기 때문에 두통이 생겼습니다. 순서는 생성자, @PostConstruct, autowired setter입니다. 모든 빈에 대해 “동일한”시간에 마지막으로 실행되는 @EventListener 주석으로 해결했습니다. 이 예제는 InitializingBean의 구현도 보여줍니다.

서로 종속성이있는 두 개의 클래스 (@Component)가 있습니다. 이 예제에서는 클래스 중 하나만 표시하기 위해 동일하게 보입니다.

@Component
public class BeanA implements InitializingBean {
  private BeanB beanB;

  public BeanA() {
    log.debug("Created...");
  }

  @PostConstruct
  private void postConstruct() {
    log.debug("@PostConstruct");
  }

  @Autowired
  public void setBeanB(BeanB beanB) {
    log.debug("@Autowired beanB");
    this.beanB = beanB;
  }

  @Override
  public void afterPropertiesSet() throws Exception {
    log.debug("afterPropertiesSet()");
  }

  @EventListener
  public void onApplicationEvent(ContextRefreshedEvent event) {
    log.debug("@EventListener");
  }
}

컨테이너가 시작될 때 호출 순서를 보여주는 로그 출력입니다.

2018-11-30 18:29:30.504 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : Created...
2018-11-30 18:29:30.509 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : Created...
2018-11-30 18:29:30.517 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @Autowired beanA
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : afterPropertiesSet()
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @Autowired beanB
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @PostConstruct
2018-11-30 18:29:30.518 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : afterPropertiesSet()
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanA                   : @EventListener
2018-11-30 18:29:30.607 DEBUG 3624 --- [           main] com.example.demo.BeanB                   : @EventListener

보시다시피 @EventListener는 모든 것이 준비되고 구성된 후에 마지막으로 실행됩니다.


답변

public class InitHelloWorld implements BeanPostProcessor {

   public Object postProcessBeforeInitialization(Object bean,
             String beanName) throws BeansException {
       System.out.println("BeforeInitialization : " + beanName);
       return bean;  // you can return any other object as well
   }

   public Object postProcessAfterInitialization(Object bean,
             String beanName) throws BeansException {
       System.out.println("AfterInitialization : " + beanName);
       return bean;  // you can return any other object as well
   }

}


답변