Class OwnerController{
private OwnerRepository repository = new OwnerRepository();
}
가 아니라
Class OwnerController{
private OwnerRepository repo;
public OwnerController(OwnerRepository repo){
this.repo = repo;
}
}
Class OwverController Test {
@Test
public void create(){
OwnerRepository repo = new OwnerRepository();
OwnerController controller = new OwnerController(repo);
}
}
의존성 주입도 제어의 역전이다.
빈(bean)을 만들고 엮어주며 제공해준다.
컨테이너에 등록 방법
1. 직접 @Bean
2. @Controller
3. Repository Class
IOC 컨테이너 안에 있는 객체들 끼리만 의존성 주입이 가능하다.
ApplicationContext 안에 빈들을 getBean으로 가져올 수 있다.
예) applicationContext.getBean(OwnerRepository.class);
SingleTone Scope를 사용할 수 있다. - 어떤 인스턴스 하나를 재사용, 매번 새로 만드는게 아니다.
멀티 쓰레드 상황에서 싱글톤 스콥을 구현하는 것 자체는 번거롭고 조심스러우나, IOC 컨테이너를 활용하면 손쉽게 싱글톤 스콥을 사용 할 수 있다.
IOC 컨테이너가 관리하는 객체를 BEAN이라고 부른다.
빈으로 주입하는 방법
1. @Component @Repository @ Controller @Service @ Comfiguration ...
1. repository는 jpa를 통해서.. 인터페이스를 상속받는 클래스를 찾아서 구현체를 만드는 과정에서 생성
2. 빈으로 직접 등록
1. 자바 설정 파일 : @Configuration 의 config 클래스를 만들어서 @Bean을 사용해서 등록하고자 하는 클래스를 직접 구현해준다.
2. xml 설정
꺼내서 쓰는 방법
1. @Autowired
1. 필드
2. 세터
3. 생성자 (스프링 4.3 부터 , 어떤 클래스의 생성자가 하나뿐일 때 , 생성자로 주입받는 레퍼런스 변수들이 빈으로 등록되어 있다면, 그 빈을 자동으로 주입하는 기능이 추가!!) 그래서 생략 가능!
4. 권장 방법은 생성자!! 필수적으로 사용해야하는 레퍼런스 없인 인스턴스를 만들수 없도록 강제할 수 있다.
필드나 세터는 인스턴스를 생성 자체는 가능하다.
그러나, 순환참조에 경우에는 생성자보다는 필드나 세터가 더 좋다.
2. applicationContext에서 직접 꺼낸다.
3. Dependency Injection
?) 세터나 필드 주입시 final을 쓸 수 없다
애노테이션 프로세서 중에 Ioc 컨테이너가 사용하는 여러가지 인터페이스들 라이프사이클 콜백이라고 부른다.
이 중 component 에너테이션이 붙어있는 애노테이션을 찾아서 그 클래스에 인스턴스를 찾아서 빈으로 등록하는 애노테이션 처리기가 등록되어 있다. == @ComponentScan : 이 위치에서부터 모든 하위 패키지를 찾아본다.
반복된 작업
Class A {
method a (){
AAAA
오늘은 ~~~ 입니다.
BBBB
}
method b (){
AAAA
내일은~~~ 입니다.
BBBB
}
method c (){
AAAA
어제는 ~~~ 입니다.
BBBB
}
}
모아놓은 AAAA BBBB
Class A{
method a() {
오늘은 ~ 입니다. 입니다.
}
method b() {
내일은 ~
}
method c() {
어제는 ~~~ 입니다.
}
}
Class AAAABBBB {
method aaaabbbb(JoinPoint point){
AAAA
point.execute()
BBBB
}
}
기존의 코드를 건드리지 않고, 기능을 추가한다.
LogExcution.class
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interfage LogExecutionTime{
}
LogAspect.class
@Component
@Aspect
public Class LogAspect{
Logger logger = LoggerFactory.getLogger(LogAspect.class);
// joinPoint 타겟 메서드
@Around("@annotation(LogExcutionTime)")
public Object logExcutionTime(PodceedingJoinPoint joinPoint) thorws Throwable {
StopWatch stopwatch = new StopWatch();
stopWatch.start();
Object proceed = jointPoint.proceed();
StopWatch.stop();
logger.info(stopWatch.prettyPrint();
return proceed;
}
}
Portable Service Abstraction
나의 코드
확정성이 좋지 못한코드 또는 기술에 특화되어 있는 코드
나의 코드
잘만든 인터페이스 ( PSA)
확정성이 좋지못한 코드 또는 기술에 특화되어 있는 코드
스프링이 제공해주는 추상화 기능들