Giken Dev
article thumbnail
반응형

의존? 의존성?

의존, 의존성 -> 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 를 호출하면 빈이 변경된다.

 

출력

 

 

반응형
profile

Giken Dev

@기켄

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!