Spring @PostConstruct 대 init-method 속성


103

@PostConstruct주석을 사용 하는 것과 init-methodSpring XML 구성에서 와 같은 방법을 선언하는 것 사이에 차이점이 있습니까?

답변:


153

실제로는 차이가 없다고 생각하지만 작동 방식에는 우선 순위가 있습니다. @PostConstruct, init-methodBeanPostProcessors입니다.

  1. @PostConstructJSR-250 주석 init-method이며 Spring의 초기화 방법입니다.
  2. @PostConstruct메서드 가있는 경우 초기화 메서드가 호출되기 전에 먼저 호출됩니다.
  3. Bean이 InitializingBean을 구현하고을 재정의하는 afterPropertiesSet경우 먼저 @PostConstruct호출 된 afterPropertiesSet다음 init-method.

자세한 정보는 Spring의 참조 문서를 확인하십시오 .

JSR 250 사양 이전에는 xml의 init-method 사용이 선호되는 방식이었습니다. 스프링 특정 클래스 / 주석에서 자바 클래스 (빈)를 분리하므로 스프링 인프라 빈에 의존 할 필요가없는 라이브러리를 구축하는 경우 init-method를 사용하는 것이 선호되었습니다. 생성 방법 중 u는 초기화 방법으로 호출해야하는 방법을 지정할 수 있습니다.

이제 Java EE에 JSR 250 사양이 도입되고 이러한 주석이 스프링 지원되므로 스프링 프레임 워크에 대한 종속성이 어느 정도 감소했습니다.

그러나 나는 이러한 것들을 추가하면 코드의 가독성이 높아진다는 것을 인정해야하므로 두 가지 접근 방식 모두 장단점이 있습니다.


23
Bean이 이러한 메소드 중 하나 이상을 사용하고 초기화 순서에 의존하는 경우 끔찍하게 복잡하고 유지 관리 할 수 ​​없습니다.
Donal Fellows 2011

2
@Donal 꽤 사실입니다. 이것이 어떻게 작동하는지에 대한 정보를 제공했습니다.
Aravind A 2011 년

1
중요한 차이가있다 : 당신은 @PostConstruct 작업을하는 과정 주석에 특별히 구성 봄에 필요 stackoverflow.com/q/3434377/134898
후안 칼레

@DonalFellows,하지만 인증 시험에 응시하려면이 사실을 알아야합니다.)
S.Klechkovski

@DonalFellows-답변을 자세히 설명해 주시겠습니까? 빈이 초기화 순서에 의존하는 경우 직면 한 어려움을 의미합니다. 사실 나는 어느 것이 더 나은지 알고 싶습니다. 요청을 처리하기 전에 Bean에서 초기화 작업을 수행하려면 PostConstruct 또는 Bean (initMethod = "init")입니까?
Ayaskant

19

실제 차이는 없습니다. 시스템 구성을 선호하는 방식에 따라 다르며 이는 개인적 선택의 문제입니다. 나 자신 @PostConstruct은 내 자신의 코드에 주석 을 사용하는 것을 선호하며 (빈은 메서드가 호출 된 후에 만 ​​올바르게 구성되므로) init-methodSpring을 인식하지 않는 라이브러리에서 Bean을 인스턴스화 할 때 사용합니다 (물론 주석을 적용 할 수 없습니다!) 그러나 나는 어떤 식 으로든 모든 것을하고 싶어하는 사람들을 완전히 이해할 수 있습니다.



3

아래의 Bean Creation Life-Cycle Callback 다이어그램에서 볼 수 있습니다 .

빈 생성 라이프 사이클 콜백

이 3 단계는 Bean Creation Life-Cycle 콜백에서 발생합니다.

  1. @PostConstruct불릴 것이라고 언급 됩니다.
  2. 경우 InitializingBean구현 한 후 afterPropertiesSet()호출됩니다.
  3. 빈 정의에 포함되어 init-method있거나 @Bean(initmethod="..")init 메소드를 호출합니다.

이 다이어그램은 Pro Spring 5 : Spring 프레임 워크 및 도구에 대한 심층 가이드 에서 가져온 것입니다 .


3

수도 의 차이 @PostConstructinit-method때문에 @PostConstruct에서 처리 postProcessAfterInitialization콩 초기화 (의 상 AbstractAutowireCapableBeanFactory.initializeBean()에 의한 방법) CommonAnnotationBeanPostProcessor동안, init방법의 완료 후에 호출되는 postProcessBeforeInitialization단계 (이 문제에 대한과의 시작하기 전에 postProcessAfterInitialization상)을.
편집 : 그래서, 순서는 1) postProcessBeforeInitialization단계, 2) init메서드가 호출되고, 3) 메서드 postProcessAfterInitialization를 호출 @PostConstruct하는 단계입니다.

(부수적으로, 수락 된 답변의 진술

@PostConstruct, init-method는 BeanPostProcessors입니다.

는 정확 하지 않습니다.는 , 메서드에 @PostConstruct의해 처리 되지 않습니다.)BeanPostProcessorinit

될 것입니다 차이 경우 일부 (잠재적으로 사용자 정의) BeanPostProcessor로 구성되어있는, ( Ordered.getOrder()) 후에 실행되는 CommonAnnotationBeanPostProcessor자사의 심각한 뭔가하고있다 postProcessBeforeInitialization방법.
'노 의 기본 봄 구성에 차이 BeanPostProcessors모든 때문에 BeanPostProcessors후에 실행되도록 구성되어있는가 CommonAnnotationBeanPostProcessor에 아무것도하지 않는 postProcessBeforeInitialization방법.

결론적으로 받아 들여진 대답과 그와 유사한 것이 맞습니다. 99 %의 경우에서이 게시물은 "악마가 세부 사항에 있습니다"라는 개념에 경의를 표하는 것입니다.


안녕하세요! 이것은 혼란 스럽습니다. PostConstruct가 init-method 이전에 실행되면 init 메소드가 postProcessBeforeInitialization 이후와 postProcessAfterInitialization 이전에 실행되면 postProcessAfterInitialization에 의해 어떻게 처리됩니까 ???
Maxrunner

@Maxrunner, 혼란을 드려 죄송하며 알려 주셔서 감사합니다! 사실, 나는 PostConstruct가 init-method보다 먼저 실행된다는 것을 결코 말하지 않았습니다. 어쨌든, 나는 몇 가지 해명 내 대답을 업데이 트
igor.zh

2

전체 코드 : https://github.com/wkaczurba/so8519187 ( spring-boot )

주석 사용 :

@Slf4j
@Component
public class MyComponent implements InitializingBean {

    @Value("${mycomponent.value:Magic}")
    public String value;

    public MyComponent() {
        log.info("MyComponent in constructor: [{}]", value); // (0) displays: Null
    }

    @PostConstruct
    public void postConstruct() {
        log.info("MyComponent in postConstruct: [{}]", value); // (1) displays: Magic
    }

    @Override // init-method; overrides InitializingBean.afterPropertiesSet()
    public void afterPropertiesSet() {
        log.info("MyComponent in afterPropertiesSet: [{}]", value);  // (2) displays: Magic
    }   

    @PreDestroy
    public void preDestroy() {
        log.info("MyComponent in preDestroy: [{}]", value); // (3) displays: Magic
    }
}

우리를 가져옵니다 :

org.springframework.context 새로 고침 중 ...

MyComponent in constructor : [null]
MyComponent in postConstruct : [Magic]
MyComponent in afterPropertiesSet : [Magic]
...

시작시 JMX 노출을위한 Bean 등록
0.561 초 내에 DemoApplication 시작 (JVM 1.011 실행)
org.springframework.context .. . 종료시 JMX 노출 Bean 등록 취소

중 ...
MyComponent in preDestroy : [Magic]

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.