티스토리 뷰
목차
의존성관계주입
Spring ICO (Inversion Of Control)
IOC 예제
@Component 를 입력했더니 에러가 발생했다.
번외 실무에서는 잘 사용하지 않는다는 말
의존성관계주입
Spring ICO
스프링에서 일반적인 Java 객체를 new
로 생성하여 개발자가 관리하는 것이 아닌 Spring Container
에 모두 맡긴다.
따라서 개발자의 직접 관리 없없도 Spring Container
는 객체의 생명주기를 관리할 수 있게되며 개발자가 원하는 요청에 따라 DI
의 요청을 수행할 수도 있다.
개발자 중심의 관리 ➡ 프레임워크 중심의 객체관리 권한 제공
그렇다면 Spring Container
가 객체를 관리하면 개발자는 어떻게 Container
로 부터 객체를 가져와야할까?
IOC 예제
이전 포스팅에서는 DI
를 구현하여 개발자가 직접 주입하는 방식을 따랐지만 이번 포스팅에서는Container
가 자동으로 주입하는 방식을 구현한다.
IOC - 적용 전
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
context = applicationContext;
}
public static ApplicationContext getContext(){
return context;
}
}
public class UrlEncoder implements IEncoder {
@Override
public String encode(String message) {
try {
return UrlEncoder.encode(message, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
@Component
public class Base64Encoder implements IEncoder {
public String encode(String message) {
return Base64Encoer.getEncoer()
.encodeToString(message.getByres());
}
}
@Component
public class Encoder {
private IEncoder iEncoder;
//TODO: 호출한 인터페이스를 Encoder 자체에 주입했다.
public Encoder(IEncoder iEncoder){
this.iEncoder=iEncoder;
}
public void setIEncoder(IEncoder iEncoder){
this.iEncoder = iEncoder;
}
public String encode(String message) {
return iEncoder.encode(message);
}
}
@SpringBootApplication
public class Main() {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
//TODO: Spring Container 호출
ApplicationContext context = ApplicationContextProvider.getContext();
//TODO: 컨테이너가 관리중인 특정 Bean을 가져온다.
Base64Encoder encoder = context.getBean(Base64Encoder.class);
UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);
String url = "www.google.com";
Encoder encoder = new Encoder();
String result = encoder.encode(url);
System.out.println(result);
encoder.setIEncoder(urlEncoder);
String urlresult = encoder.encode(url);
System.out.println(result);
}
}
@Component
어노테이션 이 달려있는 클래스는 앞으로 Spring Container
에서 Bean으로서 관리하도록 지정한다.
Container
에 주입까지 완료했다면 더 나아가 컨테이너가 자동 관리 및 주입 과정을 수행할 수 있도록 구성해야한다.
IOC - 적용 후
@Component
public class ApplicationContextProvider implements ApplicationContextAware {
private static ApplicationContext context;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException{
context = applicationContext;
}
public static ApplicationContext getContext(){
return context;
}
}
public class UrlEncoder implements IEncoder {
@Override
public String encode(String message) {
try {
return UrlEncoder.encode(message, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
@Component
public class Base64Encoder implements IEncoder {
public String encode(String message) {
return Base64Encoer.getEncoer()
.encodeToString(message.getByres());
}
}
@Component
public class Encoder {
private IEncoder iEncoder;
//TODO: @Component 에러 발생
public Encoder(IEncoder iEncoder){
this.iEncoder=iEncoder;
}
//TODO: 어떤 Bean을 사용할지 지정해주자!
public void setIEncoder(@Qualifier("urlEncoder")IEncoder iEncoder){
this.iEncoder = iEncoder;
}
public String encode(String message) {
return iEncoder.encode(message);
}
}
@SpringBootApplication
public class Main() {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
//TODO: Spring Container 호출
ApplicationContext context = ApplicationContextProvider.getContext();
//Base64Encoder encoder = context.getBean(Base64Encoder.class);
//UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);
String url = "www.google.com";
Encoder encoder = context.gerBean(Encoder.class);
String result = encoder.encode(url);
//TODO: @Qualifier 어노테이션에 주입한 Bean에 따라 출력 결과가 달라진다.
System.out.println(result);
}
}
@Component 를 입력했더니 에러가 발생했다.
다음 코드에서 @Component
를 가지는 클래스가 Encoder
와 Base54Encoder
두가지가 있다.
여기서 에러가 발생하는데 Spring 에서는 두가지의 @Component
에서 어떤 Bean 사이에 충돌이 발생하는데
우리는 @Qualifier
어노테이션을 통해 변수를 지정해주어야한다.
public class UrlEncoder implements IEncoder {
@Override
public String encode(String message) {
try {
return UrlEncoder.encode(message, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
@Component
public class Base64Encoder implements IEncoder {
public String encode(String message) {
return Base64Encoer.getEncoer()
.encodeToString(message.getByres());
}
}
@Component
public class Encoder {
private IEncoder iEncoder;
//TODO: @Component 에러 발생
public Encoder(IEncoder iEncoder){
this.iEncoder=iEncoder;
}
//TODO: 어떤 Bean을 사용할지 지정해주자!
public void setIEncoder(@Qualifier("urlEncoder")IEncoder iEncoder){
this.iEncoder = iEncoder;
}
public String encode(String message) {
return iEncoder.encode(message);
}
}
그렇다면 왜 발생하는 걸까?
IEncoder
를 상속받은 두 클래스를 본다면 Spring
입장에서는 어떤 두 클래스 중에서 객체를 받아야 하는지 궁금할 것이기
때문에 지정해 주어야한다. 라고 나는 생각한다.
번외 실무에서는 잘 사용하지 않는다는 말
난 두개의 Encoder
를 모두 사용하고 싶다면 어떻게 해야할까?
직접 등록할 클래스의 @Component
를 지우고 직접 Bean
으로 등록하면 가능하다!
@Configuration : 한개의 클래스에서 여러개의 Bean을 관리할 것을 명시
@Configuration
class AppConfig{
@Bean("base64Encode")
public Encoder encoder(Base64Encoder base64Encoder){
return new Encoder(base64Encoder);
}
@Bean("urlEncode")
public Encoder encoder(UrlEncoder urlEncoder){
return new Encoder(urlEncoder);
}
}
@SpringBootApplication
public class Main() {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
//TODO: Spring Container 호출
ApplicationContext context = ApplicationContextProvider.getContext();
String url = "www.google.com";
Encoder encoder = context.gerBean("urlEncode", Encoder.class);
String result = encoder.encode(url);
//TODO: @Qualifier 어노테이션에 주입한 Bean에 따라 출력 결과가 달라진다.
System.out.println(result);
}
}
🧾 Reference
'SPRING 🍃 > Basic' 카테고리의 다른 글
Spring DI - 여러가지 방법 편 (0) | 2022.04.17 |
---|---|
Spring AOP의 용어 (0) | 2022.04.16 |
Spring AOP 관점지향 프로그래밍 (0) | 2022.04.15 |
Gradle 과 Maven 차이 (0) | 2022.04.07 |
Spring을 다루기전 알고가야할 IOC와 DI (0) | 2022.02.28 |
- Total
- Today
- Yesterday
- java
- 매트랩
- 릿코드
- Algorithm
- 프로그래머스
- ajax
- CS
- 스프링
- OOP
- Matlab
- springboot
- security
- kakao
- 그래프
- 수학
- 자바
- spring-cloud
- 자격증
- Spring
- nginx
- JPA
- 디자인패턴
- C언어
- 알고리즘
- interview
- 면접
- Solid
- 백준
- docker
- 스프링부트
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |