Spring 어노테이션 정리
트랜잭션 관리 어노테이션
@Transactional
스프링에서 @Transactional을 사용하지 않으면, 스프링이 트랜잭션 경계를 관리하지 않습니다.
DB 연결 설정에 따라 MyBatis Mapper 호출 시마다 auto-commit 될 수 있습니다.
여러 쿼리를 하나의 트랜잭션으로 묶으려면 @Transactional을 사용해야 합니다.
@Transactional이 붙은 클래스는 모든 public 메서드에 @Transactional이 자동 적용됩니다.
스프링 트랜잭션 동작 원리
@Transactional이 적용된 메서드가 호출되면 프록시 기반 AOP가 가로채서 트랜잭션 경계를 설정하고,
스프링 애플리케이션 컨텍스트에 설정된 트랜잭션 매니저가 실제 트랜잭션의 시작, 커밋, 롤백을 관리합니다.
@Transactional 사용 시 주의사항
같은 클래스 내부에서 @Transactional이 적용된 다른 메서드를 호출하면 트랜잭션이 적용되지 않습니다.
스프링 AOP는 외부 호출 시에만 적용되고, 내부 호출 시에는 적용되지 않기 때문입니다.
클래스 레벨 어노테이션
@Component
@Component를 클래스에 붙이면, XML 등에 직접 등록하지 않아도 스프링 컨테이너가 Bean으로 등록합니다.
Bean으로 등록된 클래스는 애플리케이션이 실행될 때 객체가 자동 생성되어 바로 사용 가능합니다.
@Controller, @Service, @Repository는 @Component의 특수화된 형태입니다.
@Controller
MVC 패턴에서 컨트롤러 클래스를 나타냅니다.
주로 JSP, Thymeleaf 등 View를 반환할 때 사용합니다.
@RestController
RESTful API를 제공하는 컨트롤러 클래스에 지정하면 좋습니다.
@RestController를 사용하면 내부적으로 모든 메서드에 @ResponseBody가 적용되어
뷰 리졸버를 거치지 않고 HTTP 응답 본문에 JSON, XML 등 데이터를 직렬화하여 반환하게 됩니다.
@Service
비즈니스 로직을 처리하는 서비스 계층 클래스에 사용합니다.
@Repository
DAO 역할을 수행하는 데이터 접근 계층 클래스에 사용합니다.
스프링이 DB 관련 예외를 DataAccessException로 변환해줍니다.
메서드 레벨 어노테이션
@RequestMapping
@RequestMapping(value="/", method = RequestMethod.GET)
@RequestMapping(value="/", method = RequestMethod.POST)
@RequestMapping(value="/", method = {RequestMethod.GET, RequestMethod.POST})
Post 및 Get 방식 요청을 받을 수 있습니다.
@PostMapping
@PostMapping("/")
Post 요청을 받을 수 있습니다.
@GetMapping
@GetMapping("/")
Get 요청을 받을 수 있습니다.
URL로 ID 파라미터 받는 방법
@GetMapping("/update/{id}")
public String getUpdatePage(@PathVariable("id") Integer id, @RequestParam Map<String,Object> params) throws Exception {
log.info("아이디 : " + id);
return "content/update";
}
수정 화면 진입 시, 수정할 ID를 파라미터로 받는 예시입니다.
파라미터 어노테이션
@RequestBody
@RequestBody 클래스명 변수
클라이언트가 전송한 JSON 데이터를 Java 객체로 자동 변환합니다.
@RequestParam
@RequestParam("파라미터명") String 변수명
Get 방식으로 받은 파라미터 또는 form input name을 변수에 1:1로 매핑합니다.
HttpServletRequest 객체를 통해 req.getParameter(“파라미터명”) 으로 받는 것과 같습니다.
필수 파라미터 미전달 시 에러
Required request parameter '파라미터명' for method parameter type String is not present
파라미터가 없이 들어와서 요청 자체가 실행되지 않아 try catch 문에서 의도하지 않은 기본 에러 페이지로 이동되는 경우, 아래와 같이 필수 파라미터 지정을 해제하면 됩니다.
필수 파라미터 해제
@RequestParam(value = "파라미터명", required = false)
@ModelAttribute
@RequestMapping(value = "/구분/컨트롤러명.do")
public ModelAndView 컨트롤러명(@ModelAttribute("VO클래스명") VO클래스명 변수명) throws Exception {
}
받은 파라미터 또는 form input name과 같은 이름의 VO 클래스 변수에 모두 자동 바인딩 됩니다.
@ModelAttribute를 사용하면, 모델에 데이터가 자동으로 추가되어 뷰에서 해당 이름으로 접근할 수 있습니다.
컨트롤러 내에서 mav.addObject(“VO클래스명”, 변수명); 을 직접 써주지 않아도 됩니다.
리턴 어노테이션
@ResponseBody
@ResponseBody
@RequestMapping(value = "/cmmn/faq/selectList.do")
public ModelAndView selectList(HttpServletRequest req, HttpServletResponse res, @ModelAttribute("IMFaqVO") IMFaqVO iMFaqVO) throws Exception {
ModelAndView mav = new ModelAndView();
mav.addObject("faqList", faqService.selectList(iMFaqVO));
mav.setViewName("jsonView");
return mav;
}
return하는 java 객체를 json 형태로 변환하여 jsonView로 전달합니다.
return 값이 jsp 페이지명 String이 아닌 경우, @ResponseBody를 쓰지 않으면 URL 404 에러가 발생합니다.
Lombok 어노테이션
@Data (@Getter + @Setter)
import com.intermorph.cmmn.base.BaseVO;
import lombok.Data;
@Data
public class VO명 extends BaseVO {
private String 필드명1;
private String 필드명2;
}
위와 같이, VO 또는 DTO 클래스 위에 @Data 어노테이션을 달아주면 getter, setter를 자동 생성해줍니다.
BaseVO에는 삭제여부, 등록일시, 등록자ID, 수정일시, 수정자ID 등이 필드로 구성됩니다.
Lombok 어노테이션 미사용 시
public String get필드명() {
return 필드명;
}
public void set필드명(String 필드명) {
this.필드명 = 필드명;
}
위와 같이 필드마다 getter, setter 함수를 직접 생성해줘야 해서 번거롭고, 코드가 깔끔하지 않습니다.