예전 했던 코드로 IOC 코드 실습을 진행했다.
@Component: class에 붙이면 Spring bean 취급을 한다.
@Component
import org.springframework.stereotype.Component;
import java.util.Base64;
@Component
public class Base64Encoder implements IEncoder{
public String encode(String message){
return Base64.getEncoder().encodeToString(message.getBytes());
}
}
@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;
}
}
}
이렇게 되면 스프링이 실행이 될 때 어노테이션이 붙은 클래스를 찾아서 직접 객체를 싱글톤 형태로 만들어서 스프링 컨테이너에서 관리를 한다.
이걸 쓰는 법.
스프링컨테이너에 접근해서 꺼내오면 된다.
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@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;
}
}
스프링 어플리케이션이 실행이 될 때 Provider를 만들 때 set메서드에 어플리케이션컨텍스트를 주입시키고 그걸 받아서 static 변수에 할당을 하고 그것을 받아서 쓴다.
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import java.util.Base64;
@SpringBootApplication
public class SpringIocApplication {
public static void main(String[] args) {
SpringApplication.run(SpringIocApplication.class, args);
ApplicationContext context = ApplicationContextProvider.getContext();
Base64Encoder base64Encoder = context.getBean(Base64Encoder.class);
Encoder encoder = new Encoder(base64Encoder);
String url = "www.naver.com/books/it?page=10&size=20&naver=spring-boot";
String result = encoder.encode(url);
System.out.println(result);
}
}
Bean을 찾는 방법은 몇 가지 있는데 클래스 타입을 가지고 찾았다.
Bean을 주입 받을 수 있는 장소는 변수, 생성자, Set메서드가 있다.
정리
@Coponent를 붙이면 Spring이 관리를 시작한다 => 제어의 역전, IOC
그런데 컴포넌트가 여러 개이면 스프링에서 어떤 것을 매칭할 지 결정을 못한다.
그럴 때에는 @Qulifier 라는 어노테이션을 사용하여 무엇을 사용할 지 정해주면 된다.
package com.example.springioc;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component
public class Encoder {
private IEncoder iEncoder;
public Encoder(@Qualifier("base64Encoder") IEncoder iEncoder){
this.iEncoder = iEncoder;
}
public void setIEncoder(IEncoder iEncoder){
this.iEncoder = iEncoder;
}
public String encode(String message){
return iEncoder.encode(message);
}
}
base64Encoder를 매칭 시켰다.
그럼 실행 코드는
@SpringBootApplication
public class SpringIocApplication {
public static void main(String[] args) {
SpringApplication.run(SpringIocApplication.class, args);
ApplicationContext context = ApplicationContextProvider.getContext();
//Base64Encoder base64Encoder = context.getBean(Base64Encoder.class);
//UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);
Encoder encoder = context.getBean(Encoder.class);
String url = "www.naver.com/books/it?page=10&size=20&naver=spring-boot";
String result = encoder.encode(url);
System.out.println(result);
}
}
이렇게 간결하게 된다.
스프링컨테이너에 관리되는 객체를 bean이라고 부른다.
특정 클래스에서 new로 생성되는 개체를 bean이라 생각하면 된다.
정리: Component 어노테이션을 붙여서 스프링에 주입 받아서 사용한다.
2개의 인코더를 사용하고 싶을 때 사용하는 방법.
직접 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);
}
}
이런 식으로 작성할 수 있다.
Encoder 라는 bean이 중복되었는데 Bean에 이름을 붙이면 해결 된다.
서비스 로직에서는 new를 사용하지 않고 Spring Context에 저장하여 불러오고 생성자나 set 메서드 변수에 어노테이션을 통해 직접 객체를 받아오는 방식으로 진행된다.
정리: 스프링에서 객체를 직접 관리하고 그 객체를 Bean이라 불리고 그 Bean은 스프링 컨테이너고 스프링이 권한을 다 가져갔기 때문에 제어의 역전이 일어났고 그것이 IOC라고 한다.
쉽게 이야기 하면
스프링 컨테이너를 관리하는 것 = IOC
그리고 그것을 통해 주입을 받는다 = DI
라고 생각하면 편할 것 같다.
'Spring > Spring 공부' 카테고리의 다른 글
6. Spring Boot Annotations (0) | 2022.07.03 |
---|---|
5. ObjectMapper (0) | 2022.07.02 |
4. AOP 코딩 실습-2 (0) | 2022.07.02 |
3. AOP 코드 실습 (0) | 2022.07.01 |
1. IoC, DI/ DI 관련 코드 실습 (0) | 2022.06.30 |