코드프레소 Java 웹 개발 체험단 활동 중 Spring Boot 웹 개발 입문 강의에서 Spring Service, Bean과 의존성 주입에 관련 포스팅을 할려 한다.
Spring Bean은 정말 많은 개념이 있고 관련하여 의존성 주입도 하는 방법에 대해 글을 작성할 것이다.
Spring Service
시스템의 핵심 비즈니스 로직을 구현하는 계층이다.
SNS 시스템의 경우
- 이미지, 글 등의 컨텐츠 정보를 저장
- 사용자가 선호할 한 컨텐츠를 추천
- 회원가입, 로그인, 회원 탈퇴 등의 회원 관련 처리
view의 종류와 DB 종류에 영향을 받지 않는 독립적인 계층이다.
Service의 구현
- 클래스에 @Service 에노테이션 사용
- 파라미터로 전달된 데이터들의 검증 작업 수행
- Repository 계층을 활용하여 DB에 접근
- Service 계층의 단일 메소드가 트랜잭션의 단위가 된다.
- 애플리케이션의 세부 영역(User, Post, ..) 별도 클래스를 생성하여 구현
- 인터페이스의 사용이 권장되나, 다형성을 활용한 기능 확장의 요구사항이 없는 경우 사용하지 않기도 한다.
컨트롤러도 애플리케이션 세부 영역을 생각하여 개발을 한다. 이와 같이 나눠서 개발한다.
이어서 서비스도 애플리케이션 세부 영역을 나누어 클래스 개발을 한다.
그러나 필요한 경우에는 다른 서비스를 활용할 수 있으며, 서비스 계층끼리 사용을 할 수 있다.
import com.codepresso.controllerexercise.dto.PostDto;
import org.springframework.stereotype.Service;
@Service
public class PostService {
public PostDto getPost(Long id){
System.out.println("find post data from database by " + id);
System.out.println("validate data from database");
System.out.println("process data if necessary");
return new PostDto(id, "title", "this is content", "ybcha");
}
}
기존의 exercise 프로젝트에서 service 패키지를 생성 후 PostService 라는 클래스를 생성하자.
생성 후에 위 코드를 작성한다.
현재 DB를 연결하지는 않아 출력문으로 ID 출력과 DTO에 새로 추가해보자.
@RestController
@RequestMapping(value = "/post")
public class PostController {
PostService postService = new PostService();
@GetMapping
public PostDto getPost(@RequestBody Long id){
return postService.getPost(id);
}
이후 PostController에서 코드를 위와 같이 수정하자.
서비스 객체를 새로 선언하여 GetMapping된 return값을 위와 같이 바꾼다.
postService에서 getPost하여 id값을 받는 결과값을 반환해준다.
객체의 활용과 의존성
- 의존성(Dependency)- 하나의 모듈이 다른 모듈을 사용하는 것
- 일반적으로 다른 객체의 기능을 사용하기 위해서는 멤버 변수에 new로 객체를 생성하여 참조
- 생성한 객체의 메소드를 호출
- 어떤 객체를 생성하여 사용할 것인지 코드 상에 명시
의존성 주입(DI, Dependency Injection)
- 객체 생성을 외부에서 대신 수행
- 활용할 객체에 대한 의존성 설정을 외부에서 대신 해준다.
- 활용할 클래스 타입의 멤버 변수만 선언 후 생성자를 구현
- new 키워드를 사용하여 객체를 직접 생성하지 않고 바깥에서 누군가 객체를 생성해 주입해준다.
Spring Framework가 특정 조건을 만나면 객체를 생성
- 클래스 상단의 에노테이션
- @Configuration 클래스의 @Bean 에노테이션
- XML 설정
객체로 생성할 대상을 검색하는 과정을 컴포넌트 스캔이라 하며, 조건에 따라 객체들의 의존성을 관리한다.
Spring IoC 컨테이너와 Bean
- Spring IoC 컨테이너는 프레임워크에서 객체의 생성과 관리의 역할을 하는 컴포넌트이다.
- Spring Bean은 Spring IoC 컨테이너에 의해서 생성되어 관리되는 Java 객체이다.
- Bean은 사용자가 코드에서 new 키워드를 직접 생성한 객체가 아니라 Spring IoC에 의해 생성된 객체로 관리되는 Java의 객체이다.
의존성 주입을 위한 단계
- Spring에 의해 객체가 생성되게끔 에노테이션 설정
- 사용할 객체를 멤버 변수와 생성자에 추가 (new 키워드 사용x)
- 객체를 사용한다.
@Configuration과 @Bean Annotation
- 해당 에노테이션을 클래스 상단에 사용하면 설정 정보를 위한 클래스로 사용된다.
- @Configuration 클래스 내에 @Bean을 사용한 메소드로 Bean 생성이 가능하다. (Bean으로 등록할 객체를 생성 후 return)
- 컴포넌트 스캔 단계에서 Bean 에노테이션이 있는 코드를 만나면 스프링 프레임워크이 객체를 직접 생성을 한다.
@RestController
@RequestMapping(value = "/post")
public class PostController {
PostService postService;
public PostController(PostService postService) {
this.postService = postService;
}
@GetMapping
public PostDto getPost(@RequestParam Long id){
PostDto result = postService.getPost(id);
return result;
}
Controller에서 new를 사용한 객체 생성을 하지 않고 생성자를 작성한다.
이후 실행하여 Postman에서 정상적으로 실행이 되는 지 확인한다.
이와 같이 정상적인 Response가 받아지는 것을 확인할 수 있다.
그리고 인텔리제이 콘솔창에서 정상적으로 출력이 되는 것을 확인할 수 있다.
다음으로 application.properties라는 스프링 프레임워크 애플리케이션 설정 파일이 있다.
logging.level.org.springframework.beans= DEBUG
클릭하여 위와 같은 내용을 작성하고 재시작한다.
재시작하면 콘솔 로그 창에서 로그가 이전보다 많이 출력된 것을 확인할 수 있다.
위 내용은 스프링이 컨트롤러 내에 Bean을 새로 생성을 한다는 내용이다.
중간에 Autowiring... 출력문을 보면 의존성 주입에 대한 로그 내용이다.
Bean을 생성하는 다른 방법
이번엔 이와 같이 config라는 새로운 패키지를 생성하여 안에 AppConfig라는 클래스를 생성한다.
생성하여 내용은 이와 같이 @Configuration이라는 에노테이션을 작성한다.
아까 작성한대로 @Configuration 에노테이션은 스프링 프레임워크에 의해 설정 정보를 넣는 클래스입니다.
@Configuration
public class AppConfig {
@Bean
public PostService postService(){
//객체 생성과 동시에 return
return new PostService();
}
}
그리고 이와 같은 내용을 작성하고 PostService 클래스에 Service 에노테이션을 삭제하여 실행한다.
실행 후 똑같이 Postman에서 send하면 정상적으로 똑같은 response가 온다.
코드프레소 URL: https://www.codepresso.kr
프리미엄 IT 교육 서비스 - 코드프레소
www.codepresso.kr
'Spring' 카테고리의 다른 글
[Spring boot] @ManyToMany를 사용하면 안 되는 이유 (2) | 2022.10.12 |
---|---|
JPA vs MyBatis 비교 (0) | 2022.03.25 |
[Spring] MyBatis 연동 및 API 테스트 (3) | 2022.02.11 |
[Spring Boot] Spring 웹 개발 입문 (Spring Controller, HTTP, REST API 문서) (0) | 2022.02.03 |
[Spring Boot] Spring 웹 개발 입문 (Spring 프로젝트 생성) (0) | 2022.01.27 |