스프링에서 객체를 직접관리하는데 그렇게 직접관리 되는 객체를 bean라 하고
그 bean들이 관리되는 장소가 Spring Container인 것이다.
그리고 Spring Container가 이렇게 객체들을 제어하는 권한을 개발자로부터 가져갔기 때문에
ioc(제어역전현상)이라고 말한다.
다음의 예제 코드를 살펴보자.
먼저 iocSpring이라는 웹앱의 예제코드이다.
(설명은 주석으로 작성함)
1.iocSpringApplication.java
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
|
package com.example.ioc_spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Base64;
import java.util.stream.BaseStream;
@SpringBootApplication // @SpringBootApplication 이라는 어노테이션을 붙임으로써 이 앱자체가 스프링부트로 동작하게끔 한다.
public class IocSpringApplication {
public static void main(String[] args) {
SpringApplication.run(IocSpringApplication.class, args);
//1. ApplicationContext로 Bean을 가져오기 (bean 등록안한 상태)
ApplicationContext context = ApplicationContextProvider.getContext();
// Base64Encoder base64Encoder = context.getBean(Base64Encoder.class); // bean등록을 안했기에 이렇게 class명으로 bean가져오게 된다.
// UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);
// Encoder encoder = context.getBean(Encoder.class);
// String result = encoder.encode(url);
// System.out.println(result);
// 2. Configuration에 여러개 bean을 등록하고 bean 이름과 class로 가져오기
String url = "www.naver.com/books/it?page=10&size=20&name=spring-boot";
Encoder encoder2 = context.getBean("base64Encode", Encoder.class); // bean 등록을 했기에 이제 앞에 어떤 bean인지 이름을 써주고 클래스명을 써준다.
String result2 = encoder2.encode(url);
System.out.println(result2);
Encoder encoder3 = context.getBean("urlEncode", Encoder.class);
String result3 = encoder3.encode(url);
System.out.println(result3);
// Encoder encoder = new Encoder(base64Encoder);
// String result = encoder.encode(url);
// System.out.println(result);
// encoder.setIEncoder(urlEncoder);
// result = encoder.encode(url);
// System.out.println(result);
}
}
@Configuration // 한개의 클래스에서 여러개의 bean을 등록할때 사용하는 어노테이션
class Appconfig{
@Bean("base64Encode") //Encoder라는 동일한 자료형의 객체이니까Bean 어노테이션에서 이름을 붙여주도록 한다.
public Encoder encoder(Base64Encoder base64Encoder){
return new Encoder(base64Encoder);
}
@Bean("urlEncode") // urlEncoder라는 명이 이미등록되어있어서 de로
public Encoder encoder(UrlEncoder urlEncoder){
return new Encoder(urlEncoder);
}
// 이처럼 스프링 컨테이너 안에서 여러가지 Bean들을 담아서 관리할 수 있다.
}
|
cs |
2. IEncoder.java (인터페이스)
1
2
3
4
5
6
|
package com.example.ioc_spring;
public interface IEncoder {
String encode(String message);
}
|
cs |
3. Encoder.java
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
|
package com.example.ioc_spring;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
public class Encoder {
private IEncoder iEncoder; // 추상화시키기 위해서 IEncoder 객체를 필드로 사용
public Encoder(@Qualifier("base74Encoder") IEncoder iEncoder){ //Qualifier로 컴포넌트의 이름을 바꾸어줄 수 있다.
//this.iEncoder = new Base64Encoder(); // 만약 Base64Encoder가아닌 urlencoding을 요청할 경우 이렇게 기본생성자를 또 바꿔줘야하는 굉장히 비효율적이고 본질적인 문제점이 존재한다.
// 그런데 여기에 DI라는 개념을 도입하면 기본생성자를 건들지 않아도 충분히 이 객체를 재활용할 수 있다.
// 외부에서 내가 사용할 객체를 주입시켜주는 개념이기 때문에 가능한 것이다.
//this.iEncoder = new UrlEncoder();
// 그렇게 하기위해서는 생성자에서 매개변수를 받아줘야한다.
//최종적으로 ioc개념을 위해서는 아래와 같이 작성한다.
this.iEncoder = iEncoder;
}
public void setIEncoder(IEncoder iEncoder){
this.iEncoder= iEncoder;
}
public String encode(String message){
return iEncoder.encode(message);
}
}
|
cs |
4. Base64Encoder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package com.example.ioc_spring;
import org.springframework.stereotype.Component;
import java.util.Base64;
@Component("base74Encoder") // 이 Base64Encoder라는 클래스는 스프링에서 관리를 해줘~ bean으로 만들어서 스프링 너가 관리해 라는 의미
// 이렇게 Component 어노테이션을 붙이면 스프링이 실행이 될 때 이 Component 어노테이션이 붙은 클래스를 찾아서
// 직접 객체를 싱글톤 형태로 만들어서 스프링 컨테이너에서 관리를 하게된다.
// 이 때 어떻게 컨테이너에서 원하는 객체를 꺼내서 쓸까? -> SpringApplicationContext라는 객체를 통해서!
// SpringApplicationContext에 대한 코드들은 인터넷에 굉장히 많이 널려있다.
public class Base64Encoder implements IEncoder{
public String encode(String message){
return Base64.getEncoder().encodeToString(message.getBytes());
}
}
|
cs |
5. UrlEncoder.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
package com.example.ioc_spring;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
@Component
public class UrlEncoder implements IEncoder{ // 인터페이스를 상속
public String encode(String message){
try {
return URLEncoder.encode(message, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
|
cs |
'Spring' 카테고리의 다른 글
Spring - Junit Test (0) | 2022.01.17 |
---|---|
Spring - Component vs Bean vs Configuration (0) | 2022.01.12 |
Spring - DI (의존성 주입) 이란 무엇인가? (0) | 2022.01.11 |
Spring - 왜 Spring을 쓰는가? (0) | 2022.01.11 |
Spring - ObjectMapper (0) | 2022.01.11 |