Spring Boot - 특정 객체를 여러개의 bean으로 생성하기
객체 A를 조금씩 다른 속성을 가진 여러개의 bean으로 등록하고 사용하기 위해
@Bean 어노테이션의 name 속성 값과 @Qulifier(“bean name”) 어노테이션 조합을 이용하거나
@Bean 어노테이션의 name 속성 값과 인스턴스 이름을 같게 하는 것을 이용하는 조합으로 사용해볼 수 있다.
실습 1.
@Bean(name)
+ @Qualifier("bean name")
사용
이 조합을 사용할 때 주의할 점은 기본으로 사용될 Bean에 @Primary
어노테이션을 붙여줘야 하는 것이다.
만약 기본으로 사용될 bean에 @Primary 어노테이션을 붙이고 싶지 않다면 모든 bean에 name 값을 작성해주어야 하고 인스턴스 생성 시 이름을 bean 이름과 똑같게 해주어야 한다.
@Primary 어노테이션을 bean 선언시 붙여주게 되면 인스턴스 생성 시 @Primary @Bean 객체와 이름을 다르게 붙여주어도 @Primary @Bean이 주입되기 때문에 코드 작성에 조금 더 유연해진다.
ObjectMapper 객체 2개의 bean으로 등록
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
@Configuration
public class ObjectMapperConfig {
@Bean
@Primary
public ObjectMapper objectMapper() {
return setObjectMapperConfig(new ObjectMapper(), false);
}
@Bean(name = "objectMapperWithTimestamp")
public ObjectMapper objectMapperWithTimestamp() {
return setObjectMapperConfig(new ObjectMapper(), true);
}
private ObjectMapper setObjectMapperConfig(ObjectMapper objectMapper, boolean enableTimestamp) {
objectMapper.registerModule(new Jdk8Module());
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, enableTimestamp);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategies.SnakeCaseStrategy());
return objectMapper;
}
}
test
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
@SpringBootTest
public class ObjectMapperTest {
@Autowired
@Qualifier("objectMapperWithTimestamp")
ObjectMapper objectMapperWithTimestamp;
@Autowired
ObjectMapper objectMapper;
@Autowired
ObjectMapper mapper;
@Test
void test() throws JsonProcessingException {
Object temp = new Object() {
public final String name = "test";
public final LocalDateTime createdAt = LocalDateTime.now();
};
String getTempWithTimestamp = objectMapperWithTimestamp.writeValueAsString(temp);
System.out.println(getTempWithTimestamp);
String getTemp = objectMapper.writeValueAsString(temp);
System.out.println(getTemp);
String getTemp2 = mapper.writeValueAsString(temp);
System.out.println(getTemp2);
}
}
실행 값
1
2
3
{"name":"test","created_at":[2024,7,3,6,58,35,403181300]}
{"name":"test","created_at":"2024-07-03T06:58:35.4031813"}
{"name":"test","created_at":"2024-07-03T06:58:35.4031813"}
Lombok + @Qualifier
Lombok 사용 시 @RequireArgsConstructor 어노테이션을 통해 생성자 주입을 받도록 사용하는 경우, @Qualifier 어노테이션은 생성자 주입에 사용되지 않도록 기본 설정이 되어있다.
@Qualifier 어노테이션이 생성자 주입시 사용되게 하려면 Lombok 설정파일을 작성하여 설정해줘야 한다.
- Lombok 설정 파일 작성
프로젝트 루트 위치에 lombok.config
파일을 생성하고 아래 내용을 작성
1
lombok.copyableAnnotations += org.springframework.beans.factory.annotation.Qualifier
실습 2.
@Bean(name)
+ 인스턴스 이름 = 'bean name'
조합으로 사용
이 조합을 사용할 때 주의할 점은 다음과 같다.
- 생성하는 bean의 이름을 모두 작성해줘야 하는 것
- bean 이름과 인스턴스 이름을 똑같게 지정하는 것
이 경우 @Qulifier 어노테이션을 사용하지 않기 때문에
bean 생성시 기본으로 사용될 bean에 @Primary를 붙여주게 되면
인스턴스 이름을 각각의 bean 이름과 같게 작성해도 전부 @Primary가 붙은 bean이 주입 된다
는 점에 주의해야 한다.
ObjectMapper 객체 2개의 bean으로 등록
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
@Configuration
public class ObjectMapperConfig {
@Bean(name = "objectMapper")
public ObjectMapper objectMapper() {
return setObjectMapperConfig(new ObjectMapper(), false);
}
@Bean(name = "objectMapperWithTimestamp")
public ObjectMapper objectMapperWithTimestamp() {
return setObjectMapperConfig(new ObjectMapper(), true);
}
private ObjectMapper setObjectMapperConfig(ObjectMapper objectMapper, boolean enableTimestamp) {
objectMapper.registerModule(new Jdk8Module());
objectMapper.registerModule(new JavaTimeModule());
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, enableTimestamp);
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
objectMapper.setPropertyNamingStrategy(new PropertyNamingStrategies.SnakeCaseStrategy());
return objectMapper;
}
}
test
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@SpringBootTest
public class ObjectMapperTest {
@Autowired
ObjectMapper objectMapperWithTimestamp;
@Autowired
ObjectMapper objectMapper;
@Test
void test() throws JsonProcessingException {
Object temp = new Object() {
public final String name = "test";
public final LocalDateTime createdAt = LocalDateTime.now();
};
String getTempWithTimestamp = objectMapperWithTimestamp.writeValueAsString(temp);
System.out.println(getTempWithTimestamp);
String getTemp = objectMapper.writeValueAsString(temp);
System.out.println(getTemp);
}
}
실행 값
1
2
{"name":"test","created_at":[2024,7,3,6,58,35,403181300]}
{"name":"test","created_at":"2024-07-03T06:58:35.4031813"}
참고한 사이트