@PostConstruct를 사용하는 이유는 무엇입니까?
관리 Bean @PostConstruct
에서 일반 Java 오브젝트 생성자 후에 호출됩니다.
@PostConstruct
일반 생성자 대신 Bean으로 초기화하는 이유는 무엇 입니까?
생성자가 호출 될 때 Bean이 아직 초기화되지 않았기 때문에 종속성이 주입되지 않기 때문입니다. 에서
@PostConstruct
방법 빈은 완전히 초기화 당신은 종속성을 사용할 수 있습니다.이는이 메소드가 Bean 라이프 사이클에서 한 번만 호출되도록 보장하는 계약이기 때문입니다. 내부 작업에서 컨테이너에 의해 Bean이 여러 번 인스턴스화
@PostConstruct
될 수 있지만 (한번도는 아니지만) 한 번만 호출 될 수 있습니다.
주요 문제는 다음과 같습니다
생성자에서 종속성 주입이 아직 발생하지 않았습니다. *
* 생성자 주입은 분명히 제외
실제 예 :
public class Foo {
@Inject
Logger LOG;
@PostConstruct
public void fooInit(){
LOG.info("This will be printed; LOG has already been injected");
}
public Foo() {
LOG.info("This will NOT be printed, LOG is still null");
// NullPointerException will be thrown here
}
}
중요 : @PostConstruct
및 @PreDestroy
완전히 된 자바 (11)에서 제거 .
계속 사용하려면 종속성에 javax.annotation-api JAR을 추가해야합니다 .
메이븐
<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>javax.annotation-api</artifactId>
<version>1.3.2</version>
</dependency>
그래들
// https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api
compile group: 'javax.annotation', name: 'javax.annotation-api', version: '1.3.2'
클래스가 생성자에서 모든 초기화를 수행하는 경우 @PostConstruct
실제로 중복됩니다.
그러나 클래스에 setter 메소드를 사용하여 의존성이 주입 된 경우 클래스 생성자는 객체를 완전히 초기화 할 수 없으며 때로는 모든 setter 메소드를 호출 한 후 일부 초기화를 수행해야하므로 유스 케이스입니다 @PostConstruct
.
다음 시나리오를 고려하십시오.
public class Car {
@Inject
private Engine engine;
public Car() {
engine.initialize();
}
...
}
필드 주입 전에 Car를 인스턴스화해야하므로 생성자 실행 중에 주 입점 엔진이 여전히 널이므로 NullPointerException이 발생합니다.
이 문제는 Java 생성자 삽입을위한 JSR-330 종속성 주입 또는 Java @PostConstruct 메소드 주석을위한 JSR 250 공통 주석 으로 해결할 수 있습니다 .
@PostConstruct
JSR-250은 Java SE 6에 포함 된 공통 주석 세트를 정의합니다.
PostConstruct 주석은 초기화를 수행하기 위해 종속성 주입이 완료된 후에 실행되어야하는 메소드에서 사용됩니다. 이 메소드는 클래스를 서비스하기 전에 호출해야합니다. 이 주석은 의존성 주입을 지원하는 모든 클래스에서 지원되어야합니다.
JSR-250 Chap. 2.5 javax.annotation.PostConstruct
@PostConstruct 어노테이션은 인스턴스가 인스턴스화되고 모든 인젝션이 수행 된 후에 실행될 메소드 정의를 허용합니다.
public class Car {
@Inject
private Engine engine;
@PostConstruct
public void postConstruct() {
engine.initialize();
}
...
}
생성자에서 초기화를 수행하는 대신 코드는 @PostConstruct로 주석이 달린 메소드로 이동합니다.
post-construct 메소드의 처리는 @PostConstruct로 주석이 달린 모든 메소드를 찾아서 차례로 호출하는 간단한 문제입니다.
private void processPostConstruct(Class type, T targetInstance) {
Method[] declaredMethods = type.getDeclaredMethods();
Arrays.stream(declaredMethods)
.filter(method -> method.getAnnotation(PostConstruct.class) != null)
.forEach(postConstructMethod -> {
try {
postConstructMethod.setAccessible(true);
postConstructMethod.invoke(targetInstance, new Object[]{});
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
throw new RuntimeException(ex);
}
});
}
인스턴스화 및 주입이 완료된 후 사후 생성 방법의 처리가 수행되어야합니다.
또한 생성자 기반 초기화는 일종의 프록시 또는 원격 작업이 필요할 때마다 의도 한대로 작동하지 않습니다.
ct는 EJB가 deserialize 될 때마다 그리고 새로운 프록시가 생성 될 때마다 호출됩니다 ...
참고 URL : https://stackoverflow.com/questions/3406555/why-use-postconstruct
'IT' 카테고리의 다른 글
정규식과 일치하는 문자열인지 확인하기위한 regex.test VS string.match (0) | 2020.03.27 |
---|---|
MIME 유형으로 인해 스타일 시트가로드되지 않았습니다. (0) | 2020.03.27 |
백 스페이스 키가 다시 탐색되지 않도록하려면 어떻게해야합니까? (0) | 2020.03.27 |
JavaScript로 CSS 클래스를 동적으로 작성하고 적용하는 방법? (0) | 2020.03.27 |
Linux에서 SCP 복사 중 경로에서 공백을 피하는 방법은 무엇입니까? (0) | 2020.03.27 |