반응형
IoC(Inversion of Control)
스프링에서는 일반적인 Java 객체를 new로 생성하여 개발자가 관리하는 것이 아닌 Spring Container에 모두 맡긴다.
즉, 개발자에서 -> 프레임워크로 제어의 객체 관리의 권한이 넘어 갔음 으로 "제어의 역전"이라고 한다.
DI(Dependency Injection)
DI 장점
- 의존성으로 부터 격리시켜 코드 테스트에 용이하다.
- DI를 통하여, 불가능한 상황을 Mock와 같은 기술을 통하여, 안정적으로 테스트 가능하다.
- 코드를 확장하거나 변경 할 때 영향을 최소화 한다. (추상화)
- 순환참조를 막을 수 있다.
DI(의존성 주입) 예제
encode를 해야하는 상황에서 method를 실행해줄 interface를 생성후 상속받아 사용
Encode Method를 상속해줄 Interface
package com.example.ioc;
public interface IEncoder {
String encode(String message);
}
Base64Encode
package com.example.ioc;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
public class Base64Encoder implements IEncoder{
public String encode(String message){
return Base64.getEncoder().encodeToString(message.getBytes());
}
}
URL Encode
package com.example.ioc;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
public class UrlEncoder implements IEncoder{
public String encode(String message){
try {
return URLEncoder.encode(message, "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return null;
}
}
}
사용자가 선택한 Encode 값에 따라 인터페이스가 동작하는 코드
package com.example.ioc;
import java.util.Base64;
public class Encoder {
private IEncoder iEncoder;
public Encoder(IEncoder iEncoder){
this.iEncoder = iEncoder;
}
public String encode(String message){
return iEncoder.encode(message);
}
}
Main(사용자가 원하는 Encode 선택하여 실행)
package com.example.ioc;
public class Main {
public static void main(String[] args) {
String url = "www.naver.com/books/it?page=10&size=20&name=spring-book";
// Base 64 encoding
//Base64Encoder encoder = new Base64Encoder();
IEncoder encoder = new Base64Encoder();
String result = encoder.encode(url);
System.out.println(result);
// URL encoder
//UrlEncoder urlEncoder = new UrlEncoder();
IEncoder urlEncoder = new UrlEncoder();
String urlResult = urlEncoder.encode(url);
System.out.println(urlEncoder);
// DI 코드(외부에서 주입을 받는다)
Encoder encoder2 = new Encoder(new Base64Encoder());
String result2 = encoder2.encode(url);
System.out.println("result2: " + result2);
Encoder encoder3 = new Encoder(new UrlEncoder());
String result3 = encoder3.encode(url);
System.out.println("result3: " + result3);
}
}
IoC 예제(스프링에서 객체 관리)
@Component: 스프링에서 관리하는 클래스로 선언(bean)
기존에 작성된 클래스에 어노테이션 추가(bean으로 등록, spring이 실행될때 객체를 싱글톤으로 만들어서 스프링 컨테이너에서 관리)
스프링컨테이너에 직접 접근하여 객체를 가져오기 위해 ApplicationContext 사용
class 작성
package com.example.ioc;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
// @Component: 스프링에서 관리하는 클래스로 선언(bean)
@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;
}
}
package com.example.ioc;
import org.springframework.stereotype.Component;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
// @Component: 스프링에서 관리하는 클래스로 선언(bean)
// bean의 이름을 사용자가 지정할 수 있다.
@Component("base74Encoder")
public class Base64Encoder implements IEncoder{
public String encode(String message){
return Base64.getEncoder().encodeToString(message.getBytes());
}
}
package com.example.ioc;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
import java.util.Base64;
// @Component: 스프링에서 관리하는 클래스로 선언(bean)
//@Component
public class Encoder {
private IEncoder iEncoder;
public Encoder(IEncoder iEncoder){
this.iEncoder = iEncoder;
}
// 기본적으로 Base64Encoder를 사용한다는 가정
// @Qualifier: bean의 이름을 지정할 수 있다.
/*
public Encoder(@Qualifier("base74Encoder") IEncoder iEncoder){
this.iEncoder = iEncoder;
}
*/
public void setiEncoder(IEncoder iEncoder){
this.iEncoder = iEncoder;
}
public String encode(String message){
return iEncoder.encode(message);
}
}
package com.example.ioc;
import org.springframework.stereotype.Component;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
// @Component: 스프링에서 관리하는 클래스로 선언(bean)
@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;
}
}
}
@Configuration: 하나의 클래스에서 여러 Bean을 등록할 때 선언하는 어노테이션
그안에는 @Bean("name")으로 Bean을 지정한다.
package com.example.ioc;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import java.util.Base64;
@SpringBootApplication
public class IocApplication {
public static void main(String[] args) {
SpringApplication.run(IocApplication.class, args);
ApplicationContext context = ApplicationContextProvider.getContext();
// bean을 찾는다
/* Base64Encoder base64Encoder = context.getBean(Base64Encoder.class);
UrlEncoder urlEncoder = context.getBean(UrlEncoder.class);
Encoder encoder = new Encoder(base64Encoder);
String url = "www.naver.com/books/it?page=10&size=20&name=spring-book";
String result = encoder.encode(url);
System.out.println(result);
encoder.setiEncoder(urlEncoder);
result = encoder.encode(url);
System.out.println(result);*/
// 기본적으로 base64encoder를 사용한다는 가정(new를 사용하지 않는다)
Encoder encoder = context.getBean("base64Encode",Encoder.class);
String url = "www.naver.com/books/it?page=10&size=20&name=spring-book";
String result = encoder.encode(url);
System.out.println(result);
encoder = context.getBean("urlEncode", Encoder.class);
result = encoder.encode(url);
System.out.println(result);
}
}
// 하나의 클래스에서 여러 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);
}
}
아래와 같은 돋보기 모양을 클릭하면 bean으로 등록된 클래스들을 확인할 수 있다.
반응형
'Spring' 카테고리의 다른 글
주요 어노테이션 (0) | 2021.06.13 |
---|---|
AOP (0) | 2021.06.13 |
Spring 핵심 (0) | 2021.06.12 |
Object Mapper (0) | 2021.06.12 |
Response 내려주기 (0) | 2021.06.12 |