일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
Tags
- 적용우선순위
- 메소드명
- WeNews
- MySQL
- 테스트메소드
- AuthenticationEntryPoint
- appspec
- subquery
- 2 > /dev/null
- 네이티브쿼리
- appspec.yml
- docker명령어
- 검색
- 외부키
- 서브쿼리
- 테스트
- querydsl
- 컨테이너실행
- 예약
- foreignkey
- 포트
- 참조키
- 추후정리
- Query
- EC2
- ㅔㄴ션
- 메세지수정
- application.yml
- ubuntu
- 커밋메세지수정
Archives
- Today
- Total
제뉴어리의 모든것
[Section2] [Spring Core] Spring Framework의 핵심 개념 - 자바 기반 컨테이너 설정 본문
코드스테이츠/정리 블로깅
[Section2] [Spring Core] Spring Framework의 핵심 개념 - 자바 기반 컨테이너 설정
제뉴어리맨 2022. 8. 12. 14:50@Bean 과 @Configuration
- @Configuration :
스프링 컨테이너의 구성정보임을 알리는 애노테이션.
클래스 내부에 @Bean이 붙은 메소드들의 반환값들이 싱글톤이 지켜지도록 해줌. (메소드에 @Bean만 붙어도 빈등록되지만, 포함하는 클래스에 @Configuration이 안 붙어 있으면 싱글톤 보장 안됨)
@Configuration이 붙은 클래스 또한 스프링빈으로 등록된다. - @Bean :
메소드에 붙여서 리턴되는 타입의 객체가 스프링빈으로 등록되야됨을 알리는 애노테이션.
구성정보를 사용하여 스프링 컨테이너 생성
- 애노테이션을 이용 (@Configuration)
- TestConfig 클래스
@Configuration
class TestConfig{
@Bean
UserRepository userRepository(){
System.out.println("TestConfig.userRepository 호출");
return new UserRepositoryImpl();
}
@Bean
DiscountInfo discountInfo() {
System.out.println("TestConfig.discountInfo 호출");
return new RateDiscountInfo();
}
@Bean
UserService userService(){
System.out.println("TestConfig.userService 호출");
return new UserServiceImpl(userRepository());
}
@Bean
OrderService orderService() {
System.out.println("TestConfig.orderService 호출");
return new OrderServiceImpl(discountInfo(), userRepository());
}
}
- 스프링 컨테이너 생성 부분
package com.spring_ex01.cmarket.springContainer.annotation;
import com.spring_ex01.cmarket.discount.DiscountInfo;
import com.spring_ex01.cmarket.discount.RateDiscountInfo;
import com.spring_ex01.cmarket.order.OrderService;
import com.spring_ex01.cmarket.order.OrderServiceImpl;
import com.spring_ex01.cmarket.user.UserRepository;
import com.spring_ex01.cmarket.user.UserRepositoryImpl;
import com.spring_ex01.cmarket.user.UserService;
import com.spring_ex01.cmarket.user.UserServiceImpl;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
public class annotationConfigTest {
@Test
@DisplayName("@Configuration을 이용한 스프링 컨테이너 생성")
void testConfigurationSpringContainer() {
ApplicationContext ac = new AnnotationConfigApplicationContext(TestConfig.class);
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
- 빈 등록할 클래스 자체를 넣는 방법
ApplicationContext ac = new AnnotationConfigApplicationContext(OrderServiceImpl.class, UserServiceImpl.class, UserRepositoryImpl.class, OrderServiceImpl.class, RateDiscountInfo.class);
- xml 파일을 이용
- xmlAppConfig.xml (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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- services -->
<bean id="orderService" class="com.spring_ex01.cmarket.order.OrderServiceImpl">
<constructor-arg name="discountInfo" ref="discountInfo"/>
<constructor-arg name="userRepository" ref="userRepository"/>
</bean>
<bean id="discountInfo" class="com.spring_ex01.cmarket.discount.RateDiscountInfo"/>
<bean id="userRepository" class="com.spring_ex01.cmarket.user.UserRepositoryImpl"/>
<bean id="userService" class="com.spring_ex01.cmarket.user.UserServiceImpl">
<constructor-arg name="userRepository" ref="userRepository"/>
</bean>
<!-- more bean definitions for services go here -->
</beans>
- 스프링 컨테이너 생성 부분
package com.spring_ex01.cmarket.springContainer.xml;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class xmlConfigTest {
@Test
@DisplayName("xml 구성정보로 스프링 컨테이너 생성")
void testXmlSpringContainer() {
ApplicationContext ac = new GenericXmlApplicationContext("xmlAppConfig.xml");
String[] beanDefinitionNames = ac.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
}
빈 초기화 메소드, 소멸 메소드
- 빈 초기화 메소드
스프링 컨테이너가 빈을 등록하기 위해 빈을 생성하고 빈으로써 필요한 모든 속성들을 세팅하고 나서 바로 호출되는 초기화를 위한 메소드이다.
- java 코드로의 방법
1. 빈으로 등록될 자바 클래스에 InitializingBean 인터페이스를 구현하도록 한다.
2. InitializingBean 인터페이스의 구현 메소드인
public void afterPropertiesSet() throws Exception 를 구현한다.
사용코드
@Configuration
class TestConfig implements InitializingBean{ //인터페이스 implements
public void afterPropertiesSet() throws Exception { //초기화 메소드
System.out.println("스프링빈으로써 필요한 속성 다 세팅하고 돌아가는 콜백 메소드");
}
@Bean
UserRepository userRepository(){
System.out.println("TestConfig.userRepository 호출");
return new UserRepositoryImpl();
}
@Bean
DiscountInfo discountInfo() {
System.out.println("TestConfig.discountInfo 호출");
return new RateDiscountInfo();
}
@Bean
UserService userService(){
System.out.println("TestConfig.userService 호출");
return new UserServiceImpl(userRepository());
}
@Bean
OrderService orderService() {
System.out.println("TestConfig.orderService 호출");
return new OrderServiceImpl(discountInfo(), userRepository());
}
}
TestConfig 클래스의 객체를 빈으로 등록하면서 속성값을 모두 세팅한 뒤 afterPropertiesSet 메소드가 호출 된다.
참고 : @Configuration 이 붙은 클래스는 스프링빈의 구성정보 역할을 하고 팩토리빈의 역할을 하지만, 그 해당 클래스 또한 빈으로써 등록되는 클래스이다.
- XML 로의 방법
위에 xml로 빈 등록 방법 내용을 참고할것.
<bean id="exampleInitBean" class="examples.ExampleBean" init-method="init"/>
빈으로 등록할 <bean> 안에 init-method 속성으로 초기화 메소드를 지정하면 된다.
public void init() {
// do some initialization work
}
- @PostConstruct 방법
[추후 정리]
- 빈 소멸자 메소드
- java 코드로의 방법
org.springframework.beans.factory.DisposableBean 인터페이스를 구현하면 빈을 포함하는 컨테이너가 파괴될 때 빈이 콜백을 받을 수 있다.
1. 소멸 메소드를 호출시키고 싶은 클래스에 DisposableBean인터페이스를 implements한다
class TestConfig implements InitializingBean, DisposableBean
2. 인터페이스의 구현 메소드인 public void destroy() throws Exception 를 구현한다.
@Override
public void destroy() throws Exception
{
System.out.println("빈 파괴시 호출되는 소멸자 메소드!");
}
3. ApplicationContext (스프링 컨테이너)를 명시적으로 닫아줘야한다.
((ConfigurableApplicationContext)ac).close();
//ApplicationContext 명시적 닫기 (명시적으로 닫아야 소멸 메소드들 호출됨)
출처 : https://stackoverflow.com/questions/14423980/how-to-close-a-spring-applicationcontext
- XML로의 방법
1. <bean> 에 destroy-method 속성 추가
<bean id="exampleInitBean" class="examples.ExampleBean" destroy-method="destroy"/>
2. 속석에 기입한 동일한 메소드를 작성
void destroy() {
System.out.println("OrderServiceImpl destroy 호출!");
}
- @PreDestroy 방법
[추후 정리]
@Import 사용 방법
@Configuration
public class ConfigA {
@Bean
public A a() {
return new A();
}
}
@Configuration
@Import(ConfigA.class)
public class ConfigB {
@Bean
public B b() {
return new B();
}
}
ApplicationContext를 인스턴스화할 때 ConfigA.class와 ConfigB.class 모두 지정하는 대신 ConfigB만 제공하면 됨.
즉, @Configuration으로 지정된 클래스가 많을때, @Import를 사용하여 ApplicationContext의 매개변수를 단순화 시킬 수 있다.
'코드스테이츠 > 정리 블로깅' 카테고리의 다른 글
[Section2] [Spring Core] Spring Framework의 핵심 개념 - Component Scan (0) | 2022.08.12 |
---|---|
[Section2] [Spring Core] Spring Framework의 핵심 개념 - Spring DI (0) | 2022.08.12 |
[Section2] [관계형 데이터베이스] [Spring Core] Spring Framework 기본 2 (0) | 2022.08.10 |
[Section2] [관계형 데이터베이스] [Spring Core] Spring Framework 기본 (0) | 2022.08.09 |
[Section2] [관계형 데이터베이스] 데이터베이스 정규화 [추후 정리] (0) | 2022.08.08 |