반응형
의존? 의존성?
의존, 의존성 -> 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를 달아준다. (이 빈들은 인터페이스의 구현체들이다)
@Order 가 붙은 빈들은, 스프링 빈에서 해당 인터페이스 타입을 가진 List로 들어가 있다.
- 그러면 Service에서는 변경할 빈들의 레퍼런스 변수를 갖고 있고, 생성자에서 이 변수를 초기화시켜준다.
- 변수 서로를 change 하는 메서드를 만들어주고, Controller에서 해당 메서드를 실행하는 mapping을 해준다.
- 프로젝트 실행을 하고 중간에 mapping 한 api를 호출하면 빈이 변경된다.
반응형
'Spring' 카테고리의 다른 글
Spring 서버에서 로그아웃할 때 토큰을 Blacklist Token 테이블에 추가한다면. (0) | 2024.01.26 |
---|---|
Spring 프로젝트에 로컬 캐시를 도입해보자. (26) | 2024.01.12 |
[Spring] 의존 주입 패턴을 예제와 함께 알아보자. (0) | 2023.09.27 |
[Spring] 의존 역전에 대해 알아보자. (0) | 2023.09.26 |
[Spring] getter, setter, 생성자로 알아보는 객체지향적인 코드에 대하여 (0) | 2023.09.25 |