가수면
[Spring] 심화 본문
지연 초기화
일반적으로는 context가 실행되면 즉시 Spring Bean이 초기화됨
@Component
class ClassB {
private ClassA classA;
public ClassB(ClassA classA) {
System.out.println("초기화");
this.classA = classA;
}
public void doSomthig() {
System.out.println("doSomthig");
}
}
@Configuration
@ComponentScan
public class LazyInitializationLauncherApplication {
public static void main(String[] args) {
try(var context = new AnnotationConfigApplicationContext(LazyInitializationLauncherApplication.class)) {
System.out.println("context 초기화 완료");
context.getBean(ClassB.class).doSomthig();
}
}
}
// 초기화
// context 초기화 완료
// doSomthig
지연 초기화
@Lazy를 사용하면 사용되는 순간에 초기화시킬 수 있음
그러나 오류 등을 바로 확인할 수 있으므로 즉시 초기화가 더 권장됨 (드물게 사용되거나 무거운 Bean 등의 경우 추천)
@Component 외에도 @Configuration에도 사용 가능함(이 경우 @Configuration의 모든 Bean에 적용)
@Component
@Lazy
class ClassB {
private ClassA classA;
public ClassB(ClassA classA) {
System.out.println("초기화");
this.classA = classA;
}
public void doSomthig() {
System.out.println("doSomthig");
}
}
.
.
.
try(var context = new AnnotationConfigApplicationContext(LazyInitializationLauncherApplication.class)) {
System.out.println("context 초기화 완료");
context.getBean(ClassB.class).doSomthig();
// context 초기화 완료
// 초기화
// doSomthig
스코프
싱글톤
스프링 컨테이너 당 객체 인스턴스가 하나
여러곳에서 사용하더라도 같은 인스턴스를 공유
프로토타입
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
스프링 컨테이너 당 객체 인스턴스가 여러 개일 수 있음
호출할 때마다 새로운 인스턴스를 생성
@Scope(value=ConfigurableBeanFactory.SCOPE_PROTOTYPE)
@Component
class PrototypeClass {
}
System.out.println(context.getBean(NormalClass.class));
System.out.println(context.getBean(NormalClass.class));
System.out.println(context.getBean(PrototypeClass.class));
System.out.println(context.getBean(PrototypeClass.class));
// com.in28minutes.learnspringframwork.examples.e1.NormalClass@81d9a72
// com.in28minutes.learnspringframwork.examples.e1.NormalClass@81d9a72
// com.in28minutes.learnspringframwork.examples.e1.PrototypeClass@747f281
// com.in28minutes.learnspringframwork.examples.e1.PrototypeClass@1169afe1
리퀘스트
HTTP 요청 당 하나의 객체 인스턴스
세션
사용자 HTTP 섹션 당 하나의 객체 인스턴스
애플리케이션 스코프
웹 애플리케이션 전체에 객체 인스턴스 하나
웹소켓 스코프
웹소켓 인스턴스 당 하나의 객체 인스턴스
Java 싱글톤 vs Spring 싱글톤
Java 싱글톤
JVM 하나 당 객체 인스턴스가 하나
Spring 싱글톤
스프링 컨테이너 하나 당 객체 인스턴스가 하나
JVM에 스프링 컨테이너가 여러 개일 수도 있음 (일반적이진 않음)
의존성 주입 후 자동 실행
메소드에 @PostConstruct를 사용하면 의존성을 연결하는 대로 메소드를 호출함
의존성 주입이 완료된 후 실행해야 하는 메소드에 사용 (ex. 데이터베이스에 연결)
한마디로 useEffect 같은 거
@Component
class SomeClass {
private SomeDependency someDependency;
public SomeClass(SomeDependency someDependency) {
super();
this.someDependency = someDependency;
System.out.println("모든 의존성 준비 완료");
}
@PostConstruct
public void initialize() {
someDependency.getReady();
}
}
@Component
class SomeDependency {
public void getReady() {
System.out.println("SomeDependency를 사용");
}
}
데이터베이스에 연결된 경우 등 @PreDestroy를 이용해 클린업해주면 됨
애플리케이션이 종료되기 전, 컨텍스트에서 Bean을 삭제하기 전에 실행됨
@PostConstruct
public void initialize() {
someDependency.getReady();
}
@PreDestroy
public void cleanup() {
System.out.println("클린업");
}
CDI 어노테이션
JEE에 속한 규격
@Component를 @Named가 대체할 수 있음
@Autowired를 @Inject가 대체할 수 있음
Xml
이전에는 XML 설정으로 스프링을 썼음. 그러나 Java 어노테이션이 도입되면서 레거시가 됨
spring xml configuration example 검색
context schema
Java로 정의할 수 있는 거라면 xml로도 정의 가능
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
// 빈 설정
<bean id="name" class="java.lang.String">
<constructor-arg value="Ranga" />
</bean>
<bean id="age" class="java.lang.Integer">
// XML에서 생성자 주입 방식
<constructor-arg value="35" />
</bean>
// 컴포넌트 스캔도 가능
<context:component-scan base-package="com.in28minutes.learnspringframwork.game"/>
// 특정 빈 설정 가능
<bean id="game" class="com.in28minutes.learnspringframwork.game.PacmanGame"/>
<bean id="gameRunner" class="com.in28minutes.learnspringframwork.game.GameRunner">
// 생성자 인수는 ref로 설정
<constructor-arg ref="game" />
</bean>
</beans>
어노테이션 | XML | |
난이도 | 쉬움 | 패키지 이름 입력하는 등 번거로움 |
코드 | 어노테이션에 의지해야 함 | POJO가 깔끔해짐 |
유지보수 | 쉬움 | 복잡함 |
최근 사용률 | 현재 높음 | 현재 낮음 |
디버깅 난이도 | 스프링 프레임워크에 대한 이해도가 필요 |
중간 |
'Java' 카테고리의 다른 글
H2, JDBC, JPA, Hibernate (2) | 2023.12.02 |
---|---|
[Spring Boot] 기본 (0) | 2023.12.01 |
[Spring] 기본 (0) | 2023.11.29 |
[Java] 기본 (0) | 2023.11.29 |
개발 환경 설정 (feat. Tomcat) (0) | 2023.11.27 |