반응형
의존? 의존성?
의존, 의존성 -> Dependency
의존(성) 주입 -> Dependency Injection
의존(관계) 역전 -> Dependency Inversion
스프링 프레임워크가 해주는 일
-> 스프링 빈에서 @Component 들을 갖고있으며, 컴포넌트의 생성자에서 의존성 주입을 해준다.
-> 프로젝트 코드는 밑에서 설명한다.
실행 시점에 어떻게 다른 빈을 주입시켜줄까?
@SpringBootApplication
public class ChangeRepositoryMain {
public static void main(String[] args) {
SpringApplication.run(ChangeRepositoryMain.class, args);
}
}
@RestController
public class Controller {
private Service service;
public Controller(Service service) {
this.service = service;
}
@RequestMapping(value = "/some-api")
public void someApi() {
service.createArticle("의미 없는 데이터");
}
}
@Profile("prod")
@Component
public class DatabaseRepository implements Repository {
@Override
public void someMethod(String articleContent) {
System.out.println("DatabaseRepository");
}
}
@Profile("test")
@Component
public class FileRepository implements Repository {
@Override
public void someMethod(String articleContent) {
System.out.println("FileRepository");
}
}
변경하고자하는 그룹의 빈에다가 @Profile 을 달아준다.
- 그러고나서 해당 프로젝트의 maven 툴바로 간다.
- Lifecycle 에서 clean 후 test 를 꺼주고 package 를 실행한다.
- 해당 프로젝트의 jar 파일이 target 디렉토리로 생성될 것이다. 이제 터미널로간다.
- java -jar [ .jar 파일 ] --spring.profiles.active=[프로파일 이름] 으로 실행해준다.
"런타임에 변경 가능하다"라는 말의 의미
@RestController
public class Controller {
private Service service;
public Controller(Service service) {
this.service = service;
}
@RequestMapping(value = "/some-api")
public void someApi() {
service.createArticle("의미 없는 데이터");
}
@RequestMapping(value = "/change-repository")
public void changeToFileRepository() {
service.changeRepository();
}
}
@Component
public class Service {
private Repository inUseRepository;
private Repository spareRepository;
public Service(List<Repository> repositories) {
this.inUseRepository = repositories.get(0);
this.spareRepository = repositories.get(1);
}
public void changeRepository() {
Repository tempRepository = this.inUseRepository;
this.inUseRepository = this.spareRepository;
this.spareRepository = tempRepository;
System.out.println("repository changed");
}
public void createArticle(String articleContent) {
inUseRepository.someMethod(articleContent);
}
}
public interface Repository {
void someMethod(String articleContent);
}
@Order(0)
@Component
public class DatabaseRepository implements Repository {
@Override
public void someMethod(String articleContent) {
System.out.println("DatabaseRepository");
}
}
@Order(1)
@Component
public class FileRepository implements Repository {
@Override
public void someMethod(String articleContent) {
System.out.println("FileRepository");
}
}
변경하고자하는 그룹의 빈에다가 @Order 를 달아준다. (이 빈들은 인터페이스의 구현체들이다)
@Orde r 가 붙은 빈들은, 스프링 빈에서 해당 인터페이스 타입을 가진 List 로 들어가있다.
- 그러면 Service 에서는 변경할 빈들의 레퍼런스 변수를 갖고있고, 생성자에서 이 변수를 초기화 시켜준다.
- 변수 서로를 change 하는 메서드를 만들어주고, Controller 에서 해당 메서드를 실행하는 mapping 을 해준다.
- 프로젝트 실행을 하고 중간에 mapping 한 api 를 호출하면 빈이 변경된다.
반응형
'백엔드 데브코스' 카테고리의 다른 글
[Java] SOLID란? (2) - 객체 지향 프로그래밍의 5가지 기본 원칙 (0) | 2023.09.29 |
---|---|
[Java] SOLID란? (1) - 객체 지향 프로그래밍의 5가지 기본 원칙 (0) | 2023.09.27 |
[Java] 의존 주입 패턴 (0) | 2023.09.27 |
[Java] 의존 역전 (0) | 2023.09.26 |
[Java] 의존 관계란? (0) | 2023.09.26 |