1. MessageSource
- 국제화를 지원하는 인터페이스
- 다양한 언어로 메시지를 관리하고 사용자에게 언어별로 적절한 메시지를 제공할 수 있게 함
public interface MessageSource {
@Nullable
String getMessage(String code, @Nullable Object[] args, @Nullable String defaultMessage, Locale locale);
String getMessage(String code, @Nullable Object[] args, Locale locale) throws NoSuchMessageException;
String getMessage(MessageSourceResolvable resolvable, Locale locale) throws NoSuchMessageException;
}
메소드 | 설명 |
getMessage (String code, Object[] args, String defaultMessage, Locale locale) |
지정된 코드에 해당하는 메시지를 찾음 없으면 기본 메시지를 반환합니다. |
getMessage (String code, Object[] args, Locale locale) |
지정된 코드에 해당하는 메시지를 찾음 없으면 NoSuchMessageException을 던집니다. |
getMessage (MessageSourceResolvable resolvable, Locale locale) |
MessageSourceResolvable 객체를 사용하여 메시지 검색 |
구현체
클래스 | 설명 |
ResourceBundleMessageSource (기본 메시지 소스) |
ResourceBundle을 사용하여 메시지 로드 주로 프로퍼티 파일에서 메시지를 로드함 |
ReloadableResourceBundleMessageSource | ResourceBundleMessageSource의 확장형 메시지 파일을 변경 시, 동적으로 다시 로드할 수 있음 (파일 감지) |
StaticMessageSource | 메시지가 미리 정적으로 설정된 경우 사용되는 메시지 소스입니다. |
2. Events
ApplicationEvent 클래스
기본 제공 이벤트
이벤트 | 설명 |
ContextRefreshedEvent |
ApplicationContext가 초기화되거나 갱신될 때 게시됩니다. (예: refresh() 메서드 호출 시)
|
ContextStartedEvent |
ApplicationContext가 시작될 때 게시됩니다. (예: start() 메서드 호출 시)
|
ContextStoppedEvent |
ApplicationContext가 중지될 때 게시됩니다. (예: stop() 메서드 호출 시)
|
ContextClosedEvent |
ApplicationContext가 닫힐 때 게시됩니다. (예: close() 메서드 호출 또는 JVM 종료 시)
|
RequestHandledEvent |
HTTP 요청이 처리되었을 때 게시됩니다. (Spring의 DispatcherServlet을 사용하는 웹 애플리케이션에서만 적용)
|
ServletRequestHandledEvent |
RequestHandledEvent의 서블릿 관련 확장 이벤트입니다.
|
ApplicationListener 클래스
커스텀 이벤트
기능 | 방법 | 설명 |
이벤트 정의 | ApplicationEvent를 상속한 클래스 작성 |
커스텀 이벤트 객체 정의
|
이벤트 게시 | ApplicationEventPublisherAware 구현 ApplicationEventPublisher.publishEvent() 호출 |
스프링 컨텍스트에서 이벤트를 발행
|
이벤트 수신 | ApplicationListener<?> 구현 |
특정 이벤트 타입을 수신하여 처리
|
예제
더보기
public class BlockedListEvent extends ApplicationEvent {
private final String address;
private final String content;
public BlockedListEvent(Object source, String address, String content) {
super(source);
this.address = address;
this.content = content;
}
// 접근자 및 기타 메서드
}
public class EmailService implements ApplicationEventPublisherAware {
private List<String> blockedList;
private ApplicationEventPublisher publisher;
public void setBlockedList(List<String> blockedList) {
this.blockedList = blockedList;
}
public void setApplicationEventPublisher(ApplicationEventPublisher publisher) {
this.publisher = publisher;
}
public void sendEmail(String address, String content) {
if (blockedList.contains(address)) {
publisher.publishEvent(new BlockedListEvent(this, address, content));
return;
}
// 이메일 전송...
}
}
public class BlockedListNotifier implements ApplicationListener<BlockedListEvent> {
private String notificationAddress;
public void setNotificationAddress(String notificationAddress) {
this.notificationAddress = notificationAddress;
}
public void onApplicationEvent(BlockedListEvent event) {
// notificationAddress로 적절한 알림 전송
}
}
애너테이션 기반
사용 애너테이션 | 기능 | 설명 |
@EventListener | 이벤트 수신 |
해당 메서드가 이벤트를 수신하도록 지정.
condition 속성으로 조건 지정 가능 |
@Async, @EventListener | 비동기 이벤트 수신 |
이벤트를 비동기 방식으로 처리 (별도 스레드에서 실행)
|
@Order | 이벤트 리스너 우선순위 설정 |
이벤트 리스너 메서드의 실행 순서 지정 (숫자가 작을수록 우선순위 높음)
|
예제
더보기
public class BlockedListNotifier {
private String notificationAddress;
public void setNotificationAddress(String notificationAddress) {
this.notificationAddress = notificationAddress;
}
@EventListener(condition = "#blEvent.content == 'my-event'")
public void processBlockedListEvent(BlockedListEvent event) {
// notificationAddress로 알림 전송
}
}
@EventListener
@Async
public void processBlockedListEvent(BlockedListEvent event) {
// BlockedListEvent는 별도의 스레드에서 처리됨
}
@EventListener
@Order(42)
public void processBlockedListEvent(BlockedListEvent event) {
// 알림 전송
}
3. Low-level Resources
ResourceLoader
- 다양한 위치(classpath, 파일 시스템, URL 등)에서 리소스를 투명하게 로드할 수 있음
- JDK의 java.net.URL보다 더 많은 기능을 제공
항목 | 설명 |
ApplicationContext는 ResourceLoader |
ApplicationContext 자체가 ResourceLoader이므로 Resource를 로드할 수 있음
|
ResourceLoaderAware |
빈이 ResourceLoaderAware를 구현하면 초기화 시점에 ResourceLoader가 주입됨
|
Resource 타입의 속성 주입 |
Resource 타입의 속성을 String 경로로 설정하면 자동으로 Resource 객체로 변환됨
|
예제
더보기
@Component
public class ResourceLoaderAwareExample implements ResourceLoaderAware {
private ResourceLoader resourceLoader;
@Override
public void setResourceLoader(ResourceLoader resourceLoader) {
this.resourceLoader = resourceLoader;
}
public void readFile() throws Exception {
Resource resource = resourceLoader.getResource("classpath:data.txt");
String content = new String(resource.getInputStream().readAllBytes(), StandardCharsets.UTF_8);
System.out.println("1. ResourceLoaderAware 내용: " + content);
}
}
4. Startup Tracking
ApplicationStartup
- 애플리케이션 시작 시 단계별 메트릭을 추적할 수 있음
항목 | 설명 |
기본 구현체 |
기본값은 noop이므로 별도 설정 없이는 추적이 비활성화됨
|
추적 활성화 방법 |
ApplicationContext 생성 시 FlightRecorderApplicationStartup 같은 구현체를 설정해야 추적 가능
|
사용 목적 |
애플리케이션 시작 시간 분석 및 컨텍스트 라이프사이클 파악 (Micrometer나 프로파일러 대체 아님)
|
사용 방법 |
ApplicationStartupAware 구현
DI로 주입받아 커스텀 단계 추적 가능 |
주의사항 |
spring.* 네임스페이스는 내부 용도이므로 커스텀 추적 시 사용 금지
|
예제
더보기
public class MyApplication {
public static void main(String[] args) {
SpringApplication app = new SpringApplication(MyApplication.class);
app.setApplicationStartup(new FlightRecorderApplicationStartup());
app.run(args);
}
}
@Component
public class StartupExample implements ApplicationRunner {
@Autowired
private ApplicationContext context;
@Override
public void run(ApplicationArguments args) throws Exception {
ApplicationStartup startup = context.getApplicationStartup();
StartupStep step = startup.start("custom.startup.step");
// 작업 수행
System.out.println("✨ Startup 작업 중...");
step.tag("작업", "예제");
step.end();
}
}
- 결과는 Java FlightRecorder 에서 수집할 수 있음 (로그, 커스텀 리스너도 가능)
5. ApplicationContext Installation
ContextLoaderListener
- 선언적으로 ApplicationContext 등록 가능
항목 | 설명 |
contextConfigLocation |
여러 파일 지정 가능 (공백, 콤마, 세미콜론으로 구분)
|
Ant 패턴 지원 |
예: /WEB-INF/*Context.xml, /WEB-INF/**/*Context.xml
|
예제
더보기
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/applicationContext.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
...>
<bean id="helloBean" class="com.example.HelloBean" />
</beans>
사용
public class MyServlet extends HttpServlet {
@Override
public void doGet(HttpServletRequest req, HttpServletResponse res) throws IOException {
ApplicationContext context = WebApplicationContextUtils.getWebApplicationContext(getServletContext());
HelloBean helloBean = context.getBean(HelloBean.class);
res.getWriter().write("Hello from: " + helloBean.sayHello());
}
}
6. Deploy a ApplicationContext as a Jakarta EE RAR file
항목 | 설명 |
RAR 배포란? |
Spring ApplicationContext를 RAR 파일로 만들어 Jakarta EE 환경에 배포하는 방법
|
사용 시점 |
HTTP 엔트리 포인트가 필요 없는 메시지 처리, 스케줄링 등의 목적일 때 적합
|
장점 |
JTA, JNDI, JMS 등 Jakarta EE 리소스와 통합 가능.
Spring의 트랜잭션, JNDI, JMX 지원 사용 가능 |
RAR 구성 |
1. 모든 클래스와 라이브러리를 포함한 .rar 생성
2. META-INF/ra.xml 및 applicationContext.xml 포함 3. 서버 배포 디렉터리에 RAR 파일 배치 |
관련 클래스 |
SpringContextResourceAdapter를 참고 (구체 설정은 Javadoc 참고)
|
출처
'Spring > Spring' 카테고리의 다른 글
[Spring][Field] 2. Formatting (0) | 2025.04.06 |
---|---|
[Spring][Field] 1. Type Conversion (0) | 2025.04.06 |
[Spring][Core] 3-4. Container: Environment Abstraction (0) | 2025.04.06 |
[Spring][Core] 3-3. Container: Using JSR 330 Standard Annotations (0) | 2025.04.06 |
[Spring][Core] 3-2. Container: Classpath Scanning and Managed Components (0) | 2025.04.06 |