Lombok (롬복)
자바 빈즈
자바빈즈(JavaBeans)는 자바로 작성된 소프트웨어 컴포넌트이다.
자바빈즈의 사양은 썬 마이크로시스템에서 다음과 같이 정의되어 있다.
"빌더 형식의 개발도구에서 가시적으로 조작이 가능하고 또한 재사용이 가능한 소프트웨어 컴포넌트이다."
자바빈즈는 많은 측면에서 유사하지만 엔터프라이즈 자바빈즈(EJB)와 혼동하지 말아야 한다.
EJB는 자바 플랫폼, 엔터프라이즈 에디선(Java EE)의 일부로서 서버 계열의 컴포넌트이다.
자바빈즈의 관례
자바빈즈 클래스로서 작동하기 위해서, 객체 클래스는 명명법, 생성법 그리고 행동에 관련된 일련의 관례를 따라야만 한다.
이러한 관례는 (빌더 형식의) 개발 도구에서 자바빈즈와의 연결을 통해 클래스의 재사용 그리고 클래스의 재배치를 가능하게 한다.
지켜야 할 관례는 다음과 같은 것이 있다.
- 클래스는 직렬화되어 있어야 한다.(클래스의 상태를 지속적으로 저장 혹은 복원 시키기 위해)
- 클래스는 기본 생성자를 가지고 있어야 한다.
- 클래스의 속성들은 get, set 혹은 표준 명명법을 따르는 메서드들을 사용해 접근할 수 있어야 한다.
- 클래스는 필요한 이벤트 처리 메서드들을 포함하고 있어야 한다.
자바빈즈의 직렬화
자바빈즈는 반드시 직렬화를 할 필요는 없으나 미리 구현해두는 것이 무난하다.
직렬화가 필요한 경우는 다음과 같다.
- JPA 프로바이더가 제공하는 캐시 기술이 Serializable 인터페이스를 요구하는 경우
- 자바빈즈 객체를 세션 스코프에서 관리하는 경우
- 다수의 서버에서 세션 객체를 공유해야 하는 경우
package com.sjk.domain;
import java.util.Date;
public class Board implements java.io.Serializable{
private static final longserialVersionUID= 1L;
private int boardNo;
private String title;
private String content;
private String writer;
private Date regDate;
//클래스는 기본 생성자를 가지고 있어야 한다.
public Board(){
super();
}
public Board(int boardNo, String title){
super();
this.boardNo = boardNo;
this.title = title;
}
//클래스와 속성들은 get, set 혹은 표준 명명법을 따르는 메서드들을 사용해 접근할 수 있어야 한다.
public int getBoardNo() {
return boardNo;
}
public void setBoardNo(int boardNo) {
this.boardNo = boardNo;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public Date getRegDate() {
return regDate;
}
public void setRegDate(Date regDate) {
this.regDate = regDate;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + boardNo;
return result;
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj == null)
return false;
if(getClass() != obj.getClass())
return false;
Board other = (Board) obj;
if(boardNo != other.boardNo)
return false;
return true;
}
@Override
public String toString() {
return "Board(boardNo=" +boardNo + ", title="+title+", content="+content+
", writer="+writer+", regDate="+regDate+")";
}
}
롬복 어노테이션
롬복(Lombok)을 활용하면 약간의 어노테이션 설정만으로 소스 코드가 컴파일 될 때 자동으로 추가 코드를 만들 수 있다.
- @Getter/@Setter
- 객체의 getter와 setter를 생성한다.
- @ToString
- toString() 메서드를 생성한다.
- @EqualsAndHashCode
- 자바의 equlas() 메서드와 hashCode() 메서드를 생성한다.
- @NoArgsConstructor
- 인자가 없는 기본 생성자를 생성한다.
- @RequiredArgsConstructor
- 객체의 모든 필드값을 인자로 받는 생성자를 생성한다.
- @AllArgsConstructor
- 객체의 모든 필드값을 인자로 받는 생성자를 생성한다.
- @Data
- @ToString, @Getter, @Setter, @EqualsAndHashCode, @RequiredArgsConstructor 어노테이션을 합쳐놓은 어노테이션 이다.
- @Builder
- 빌더 패턴을 사용할 수 있도록 코드를 생성한다.
- @Log
- 자동으로 생기는 log라는 변수를 이용해서 로그를 출력할 수 있다.
롬복 어노테이션 의존성 설정
pom.xml
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
롬복 어노테이션을 적용한 Board
package com.sjk.domain;
import lombok.*;
import java.util.Date;
@NoArgsConstructor
@RequiredArgsConstructor
@Getter
@Setter
@EqualsAndHashCode(of="boradNo")
@ToString
public class Board{
private int boardNo;
@NonNull
private String title;
private String content;
private String writer;
private Date regDate;
}
롬복 어노테이션 Test
package com.sjk;
import com.sjk.domain.Board;
import org.junit.jupiter.api.Test;
public class LombokTests {
@Test
public void testNoArgsConstructor(){
Board board = new Board();
System.out.println(board);
}
@Test
public void testRequiredArgsContructor(){
Board board = new Board("테스트 제목");
System.out.println(board);
}
}
=============================================================
Board(boardNo=0, title=null, content=null, writer=null, regDate=null)
Board(boardNo=0, title=테스트 제목, content=null, writer=null, regDate=null)
@Getter와 @Setter
getter와 setter 어노테이션을 사용하면 getter, setter메서드가 자동으로 만들어진다.
public int getBoardNo() {
return boardNo;
}
public void setBoardNo(int boardNo) {
this.boardNo = boardNo;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public String getWriter() {
return writer;
}
public void setWriter(String writer) {
this.writer = writer;
}
public Date getRegDate() {
return regDate;
}
public void setRegDate(Date regDate) {
this.regDate = regDate;
}
@ToString
자바 객체의 toString() 메서드를 생성한다.
@Override
public String toString() {
return "Board(boardNo=" +boardNo + ", title="+title+", content="+content+
", writer="+writer+", regDate="+regDate+")";
}
@ToString의 exclude에 파라미터를 적용할 수 있다.
package com.sjk.domain;
import lombok.ToString;
//userName 필드를 제외하는 toString()메서드를 생성한다.
@ToString(exclude = "userName")
public class Member {
private String userId;
private String password;
private String userName;
//@ToString에 의해 추가된 코드, exclude 파라미터에 지정된 userName필드값은 출력하지 않는다.
@Override
public String toString(){
return "Member(userId="+userId+", password="+password+")";
}
}
@EqualsAndHashCode
자바의 equals() 메서드와 hashCode() 메서드를 생성한다.
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + boardNo;
return result;
}
@Override
public boolean equals(Object obj) {
if(this == obj)
return true;
if(obj == null)
return false;
if(getClass() != obj.getClass())
return false;
Board other = (Board) obj;
if(boardNo != other.boardNo)
return false;
return true;
}
@NoArgsConstructor
인자가 없는 기본 생성자를 생성한다.
package com.sjk.domain;
import lombok.*;
import java.util.Date;
@ToString
@NoArgsConstructor
@AllArgsConstructor
public class Board{
private int boardNo;
private String title;
private String content;
private String writer;
private Date regDate;
//@NoArgsConstuctor에 의해 추가된 코드
public Member(){
super();
}
//@AllArgsConstructor에 의해 추가된 코드
public Member(String userId, String password, String userName){
super();
this.userId = userId;
this.password = password;
this.userName = usernName;
}
}
@RequiredArgsConstructor
@NonNull 이 적용된 필드값이나 final로 선언된 필드값만 인자로 받는 생성자를 생성한다.
package com.sjk.domain;
import lombok.*;
import java.util.Date;
@ToString
@RequiredArgsConstructor
public class Board{
@NonNull
private Integer boardNo;
private String title;
private String content;
private String writer;
private Date regDate;
//@RequiredArgsConstructor에 의해 추가된 코드
public Board(int boardNo){
super();
this.boardNo = boardNo;
}
}
final을 적용한 필드값
package com.sjk.domain;
import lombok.RequiredArgsConstructor;
import lombok.ToString;
@ToString
@RequiredArgsConstructor
public class Member {
private final String userId;
private final String password;
private String userName;
//@RequiredArgsConstructor에 의해 추가된 코드
public Member(String userId, String password){
super();
this.userId = userId;
this.password = password;
}
}
@AllArgsConstructor
객체의 모든 필드값을 인자로 받는 생성자를 생성한다.
package com.sjk.domain;
import lombok.*;
import java.util.Date;
@ToString
@AllArgsConstructor
public class Board{
private int boardNo;
private String title;
private String content;
private String writer;
private Date regDate;
//@AllArgsConstructor에 의해 추가된 코드
public Board(int boardNo, String title, String content, String writer, Date regDate){
super();
this.boardNo = boardNo;
this.title = title;
this.content = content;
this.writer = writer;
this.regDate = regDate;
}
}
@Data
@ToString, @Getter, @Setter, @EqualAndHashCode, @RequiredArgsConstructor 어노테이션을 합쳐놓은 어노테이션이다.
package com.sjk.domain;
import lombok.*;
import java.util.Date;
//@ToString, @Getter, @Setter, @EqualAndHashCode, @RequiredArgsConstructor 어노테이션을 합쳐놓은 어노테이션이다.
@Data
public class Board{
private int boardNo;
private String title;
private String content;
private String writer;
private Date regDate;
}
@Builder
빌더 패턴을 사용할 수 있도록 코드를 생성한다.
@NoArgsConstructor를 적용하지 않아도 기본적으로 인자가 없는 생성자를 제공한다.
package com.sjk.domain;
import lombok.*;
import java.util.Date;
@ToString
@Builder
public class Board{
private int boardNo;
private String title;
private String content;
private String writer;
private Date regDate;
//@Builder에 의해 추가된 코드
Board(int boardNo, String title, String content, String writer, Date regDate){
super();
this.boardNo = boardNo;
this.title = title;
this.content = content;
this.writer = writer;
this.regDate = regDate;
}
public static BoardBuilder builder(){
return new BoardBuilder();
}
public static class BoardBuilder{
private int boardNo;
private String title;
private String content;
private String writer;
private Date regDate;
private BoardBuilder(){}
pulbic BoardBuilder boardNo(int boardNo){
this.boardNo = boardNo;
return this;
}
public BoardBuilder title(String title){
this.title = title;
return this;
}
public BoardBuilder content(String content){
this.content = content;
return this;
}
public BoardBuilder writer(String writer){
this.writer = writer;
return this;
}
public BoardBuilder regDate(Date regDate){
this.regDate = regDate;
return this;
}
public Board build(){
return new Board(boardNo, title, content, writer, regDate);
}
}
}
====Build Test=====
@Test
public void testBoardBuilder(){
Board board = Board.builder()
.boardNo(1)
.title("titl1")
.content("content")
.writer("writer")
.regDate(new Date())
.build();
System.out.println(board);
}
@Log
자동으로 생기는 log라는 변수를 이용해서 로그를 출력할 수 있다.
package com.sjk.controller;
import lombok.extern.java.Log;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
@Log
@Controller
public class HomeController {
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
@RequestMapping(value = "/")
public String home(Locale locale, Model model){
log.info("Welcome home! The client locale is "+ locale + ".");
Date date = new Date();
DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG, locale);
String formattedDate = dateFormat.format(date);
model.addAttribute("serverTime", formattedDate);
return "home";
}
}
'Back-end' 카테고리의 다른 글
HTTP (0) | 2022.05.18 |
---|---|
프로젝트(Spring Boot & JPA) (0) | 2022.01.23 |
Spring 기본 세팅 (0) | 2021.10.06 |
10. JSTL (0) | 2021.09.11 |
EL(Expression Language) (0) | 2021.09.05 |