설계를 할 때는 원칙적으로 영역을 구분해서 작성해야 한다. 일반적으로 비즈니스 영역에 있는 객체들은 '서비스(Service)'라는 용어를 많이 사용한다.
메소드를 정의를 할 때 업무와 관련되게 설정하는 것이 바람직하다.
예를 들어, 사용자 입장에서 생각해서 INSERT라는 메소드 대신 Register라고 설정할 수 있다.
Service Interface에서 할 일을 spring에선 알 수 없으므로 impl 클래스를 작성해야 한다.
com.zerock.service 패키지, BoardService Interface을 다음과 같이 생성한다.
package com.zerock.service;
import java.util.List;
import com.zerock.domain.BoardVO;
public interface BoardService {
public List<BoardVO> getList();
public void register(BoardVO board);
public BoardVO get(long bno);
public boolean modify(BoardVO board);
public boolean remove(long bno);
}
Mapper에서 보면 update의 리턴타입이 int이다. 이는 몇 개의 항목이 영향을 받았는지 알려준다. 하지만 사용자가 게시글 수정을 할 때는 보통 1개의 글을 수정을 할 것이 거의 default로 정해져 있다고 생각해도 무방하다. 따라서 Service 쪽에서 메서드를 작성할 때는 수정이 성공을 했는지 실패를 했는지를 Boolean 타입으로 지정해서 알려주는 것이 바람직하다. 사용자에게 응답을 주는 방식을 개발자가 정할 수 있다. Service 상에서 0이 돌아오면 실패, 1이 돌아오면 성공 이런 식으로 확인할 수 있다.
package com.zerock.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.zerock.domain.BoardVO;
import com.zerock.mapper.BoardMapper;
import lombok.AllArgsConstructor;
import lombok.Setter;
import lombok.extern.log4j.Log4j;
@Log4j
@Service
@AllArgsConstructor
public class BoardServiceImpl implements BoardService {
@Setter(onMethod_=@Autowired)
private BoardMapper mapper;
// public BoardServiceImpl(BoardMapper mapper) {
// this.mapper = mapper;
// }
@Override
public List<BoardVO> getList() {
// TODO Auto-generated method stub
log.info("getList : ");
return mapper.getList();
}
@Override
public void register(BoardVO board) {
// TODO Auto-generated method stub
log.info("register:" + board);
mapper.insertSelectKey(board);
}
@Override
public BoardVO get(long bno) {
// TODO Auto-generated method stub
log.info("get:" + bno);
return mapper.read(bno);
}
@Override
public boolean modify(BoardVO board) {
// TODO Auto-generated method stub
log.info("modify:" + board);
return mapper.update(board) == 1;
}
@Override
public boolean remove(long bno) {
// TODO Auto-generated method stub
log.info("remove:" + bno);
return mapper.delete(bno) == 1;
}
}
비즈니스 계층의 인터페이스와 구현 클래스가 작성되었다면, 이를 스프링의 빈으로 인식하기 위해서 @Service 어노테이션이 있는 org.zerock.service 패키지를 스캔하도록 추가해야 한다.
root-context.xml의 네임스페이스 탭에서 context 항목을 다음과 같이 체크한다.
네임스페이스를 추가하면 해당 이름으로 시작하는 태그들을 활용할 수 있다.
@Controller를 쓸 수 있었던 이유는 servlet-context.xml 부분에 프로젝트 생성시에 위와 같이 스캔하라는 코드가 있었기 때문이다.
<context:component-scan base-package="com.zerock.controller" />
servlet-context에 위와 같은코드가 있고
root-context.xml에
<context:component-scan base-package="com.zerock.service"></context:component-scan>
가 있는데 차이점이 뭔지 알려줘
Spring Framework에서 <context:component-scan>
태그는 지정된 패키지 및 하위 패키지에서 Spring의 컴포넌트 스캔이 수행되도록 설정합니다. 이 컴포넌트 스캔은 @Component
, @Service
, @Repository
, @Controller
등의 애노테이션이 붙은 클래스를 찾아 Spring의 ApplicationContext에 빈(bean)으로 등록합니다.
servlet-context.xml
: 이 파일은 보통 웹과 관련된 빈 설정, 뷰 리졸버(view resolver), 핸들러 매핑(handler mapping) 등을 정의합니다. 여기서 <context:component-scan base-package="com.zerock.controller" />
는 com.zerock.controller
패키지 및 하위 패키지에서 컴포넌트를 찾아서 빈으로 등록하라는 의미입니다. 이 설정은 주로 웹 레이어에서만 필요한 빈들을 스캔하는 데 사용됩니다.
root-context.xml
: 이 파일은 일반적으로 전체 애플리케이션 컨텍스트에 대한 빈 설정을 담당합니다. 여기서 <context:component-scan base-package="com.zerock.service" />
는 com.zerock.service
패키지 및 하위 패키지에 있는 컴포넌트를 찾아서 빈으로 등록하라는 의미입니다. 이 설정은 주로 서비스 레이어, 데이터 레이어 등 전체 애플리케이션에서 공유되어야 하는 빈들을 스캔합니다.
이 두 설정의 주된 차이점은 범위(scope)입니다.
servlet-context.xml
에 정의된 빈들은 주로 웹 레이어에서만 사용됩니다.root-context.xml
에 정의된 빈들은 전체 애플리케이션에서 공유되어 사용됩니다.따라서, 컨트롤러가 서비스를 사용해야 한다면 com.zerock.service
패키지는 root-context.xml
에 정의되어야 하며, 컨트롤러 자체는 servlet-context.xml
에 정의되어야 합니다. 이렇게 구성하면 레이어별로 책임을 분리할 수 있으며, 빈의 범위도 적절하게 관리할 수 있습니다.
else가 없이 코드를 작성하는 추세다
if(board != null) 이렁식으로 x