본문 바로가기

개발중/Spring

new -> autowrite 생성자 이해하기

728x90
반응형

 

JAVA 의 고전적인 객체 주입 사용법

 

✔  TestController

 

public class TestController {
	
	private TestService service;
	
	public TestController( ) {
		this.service = new TestService();
	}
}

 

 

✔  TestService

 

public class TestService {
	public TestService( ) {
   		System.out.print("TestService 생성 완료")
	}
}

 

위에 TestController 의 생성자에서 하는일처럼 기초적인 자바에서는 new 를 이용해서 객체를 주입해.

즉, TestController 에서 TestService 에 접근하기 위해서 new 를 사용해서 TestService 를 주입 한거지.

 

그럼 TestController 에서는 TestService 에 있는 public 으로 된 메소드에 접근할 수 있는 권한이 생긴거야.

 


Spring

 

이제 스프링을 이용하면서 사람들이 좀 더 편한 방법을 추구하기 시작했어.

스프링을 설명하자면 너무 막대한 양이라 짧게 요약할께.

 

스프링

더보기

스프링을 쓰는 이유는 정말 다양해.

 

스프링이 제공해주는 다양한 도구들

  - Spring Security

        - 인증에 관한 라이브러리 지원.

  - Spring Jdbc

        - DB 접속에 관한 라이브러리 지원.

  - Spring Autuator

        - 애플리케이션 상태를 종합적으로 모니터링.

 

기존에 무거운 기존 프레임워크를 대신해 경량 프레임워크인 스프링이 등장했어.

기존의 프레임 워크는 특정 부분에 한정 짓고 기능을 제공하고 나머지 개발은 모두 개발자의 몫이었는데,

스프링 프레임워크는 프로세스 구축 전 단계를 지원해.

 

그리고 다른 프레임 워크와의 호환성이 좋아서 사용하기도 해. 그로 인해 다양한 프로세스와 혼용하여서 개발이 가능해지기도 하고.

 

스프링의 4가지 특징으로는 의존성 주입, POJO 방식, 관점지향 프로그래밍, 제어의 반전 이렇게 있어.

 

 


스프링 - 의존성 주입

 

나는 이 부분을 이해하는게 먼저인 것 같아서 의존성 주입을 간단하게 정리해줄께.

 

스프링의 특징 중에 의존성 주입( DI, Dependency Injection )이라는 특징이 있어.

 

어떤 객체가 사용하는 의존 객체를 직접 만들어 사용하는 것이 아닌,

생성자를 사용하여 주입 받아서 사용하는 방법이야.

 

결합도는 낮을 수록 좋은 것은 알지 ?

 

의존성 주입을 이용함으로써 느슨한 결합이 이루어지는데, 객체를 주입 받는 다는 것은 외부에서 생성된 객체를 인터페이스를 통해서 넘겨 받는거야. 이렇게 하면 결합도는 낮출 수 있고, 런타임시에 의존 관계가 결정되기 때문에 유연한 구조를 가질 수 있어.

 


기본적인 어노테이션

@Bean

개발자가 컨트롤 할 수 없는 외부 라이브러리 Bean으로 등록하고 싶은 경우에 사용.

 

@Component

개발자가 직접 컨트롤할 수 있는 클래스(직접 만든)를 Bean으로 등록하고 싶은 경우에 사용.

 

@Controller, @Service, @Repository 

비즈니스 레이어에 따라 명칭을 달리 지정해준 것.


@Autowired

IOC 컨테이너에 있는 참조할 Bean을 찾아 주입.

 


JAVA 의 고전적인 생성자 사용법을 보안한 @AutoWrite

 

'JAVA 의 고전적인 객체 주입 사용법' 과 비교하면서 읽어보기 !

 

1 - TestController 에는 @RestController 로 해당 class 가 Controller 에서 하는 일을 할 것이라고 Bean 등록을 한거야.

 

2 - '고전' 에서 보던 new 주입 방식 대신에 TestController의 생성자에 @Autowrite 를 선언했어.

     그로 인해서 매개변수에 있는 TestService 가 자동으로 주입되면서

     자신의 TestService 에 주입을 받아 사용할 수 있게 된거야.

 

3 - TestService 에서는 @Service 라고 써주면서 자신이 하는 비지니스를 정한거야. 동시에 Bean 등록도 한거야.

 

 

✔ TestController

 

@RestController
@RequestMapping("/api/test")
public class TestController {
	
	private TestService service;
	
	@Autowired
	public TestController( TestService service ) {
		this.service = service;
	}
}

 

✔  TestService

 

@Service
public class TestService {

	public TestService( ) {
   		System.out.print("TestService 생성 완료")
	}
}

 


 한줄로 @AutoWrite

 

위에 방법보다 더 간단하게 사용할 수도 있어.

코드가 훨씬 깔끔하지 ?

 

@RestController
@RequestMapping("/api/test")
public class TestController {
	
    @Autowired
    private TestService service;
}

 

그래도 기능은 똑같이 작동해.

 

@AutoWrite 로 객체를 의존성 주입 하기 때문에 !

 


@PostConstruct

 

이게 내가 설명해주고 싶은 어노테이션이었는데 !

 

@PostConstruct는 의존성 주입이 이루어진 후 초기화를 수행하는 메서드야.

 

한줄로 @Autowrite 를 사용하면 '생성자에서 해줘야 하는 일을 어디서 작성을 해야 할까?' 라는 고민이 생기잖아.

나는 그 때 @PostConstruct 를 이용해.

 

@Service
public class TestService {

    @Autowired
    private Test1 test1;
    
    @Autowired
    private Test2 test2;
    
    @PostConstruct
	public void init( ) {
   		System.out.print("This is TestService")
        test1.testMethod();
        test2.testMethod();
	}
}

 

@PostConstruct 를 사용하면 Bean LifeCycle 에서 해당 객체가 Bean 으로 등록 되자마자 실행하는 초기화, 오로지 딱 한번만 실행해. 그래서 외부 라이브러리를 연결할 때나 객체 초기화 할 때 잘 써먹으면 쓸 곳이 많은 어노테이션이야.

 

TestService 가 생성될 때 제일 먼저 하는 일은 Test1 과 Test2 에 의존성 주입을 하는거겠지.

바로 그 다음에 실행되는게 @PostConstruct 를 선언한 init() 메서드야.

 

init 에서 Test1 과 Test2에 접근 하려는 순간 이미 의존성 주입이 이루어진 이후 이므로 접근하는데 아무 지장이 없겠지 ??

 

 


 

 

728x90
반응형