Spring - Annoation

우야·2021년 7월 17일
0

Annoation

@Component

  • component-scan을 선언에 의해 특정 패키지 안의 클래스들을 스캔하고, @Component Annotation이 있는 클래스에 대하여 bean 인스턴스를 생성

@Controller, @Service, @Repository

  • @Component —구체화—> @Controller, @Service, @Repository
  • bean으로 등록
  • 해당 클래스가 Controller/Service/Repository로 사용됨을 Spring Framework에 알린다.
  • 참고) @WebServlet vs @Controller

@RequesMpapping

  • HandlerMapping Class가 맵핑정보를 가지고 있으며, Controller에서 요청에 대한 맵핑을 위해 사용
  • @RequestMapping("/home") // 1) Class Level
    • 클래스내의 모든 메서드에 적용
  • @RequestMapping(value = "/employees", method = RequestMethod.GET) // 2) Handler Level
    • 요청 url에 대해 해당 메서드에서 처리할때 사용

@RequestController

  • MVC가 아닌, RestAPI에 Controller를 만들때 사용

  • @Controller + @ResponseBody
    @ResponseBody를 모든 메소드에서 적용한다.
    메소드의 반환 결과(문자열)를 JSON 형태로 반환한다.

  • @Controller 와 @RestController 의 차이

    • @Controller
      • API와 view를 동시에 사용하는 경우에 사용
        대신 API 서비스로 사용하는 경우는 @ResponseBody를 사용하여 객체를 반환한다.
      • view(화면) return이 주목적
    • @RestController
      - view가 필요없는 API만 지원하는 서비스에서 사용 (Spring 4.0.1부터 제공)
      - @RequestMapping 메서드가 기본적으로 @ResponseBody 의미를 가정한다.
      - data(json, xml 등) return이 주목적
      즉, @RestController = @Controller + @ResponseBody

@Autowired

  • org.springframework.beans.factory.annotation.Autowired
  • Type에 따라 알아서 Bean을 주입한다.
  • 필드, 생성자, 입력 파라미터가 여러 개인 메소드(@Qualifier는 메소드의 파라미터)에 적용 가능
  • Type -> Name -> @Quelifier 순서로 검색
  • TIP) Bean을 주입받는 방식 (3가지)
    • @Autowired
    • setter
    • 생성자 (@AllArgsConstructor 사용) -> 권장방식
      • 이유 : 컴파일 타임에 생성 조건을 확인하여, 순환참조를 찾을수 있음, 순환참조는 설계부터 잘못된 것이다.

@Qualifier

  • 같은 타입의 빈이 두 개 이상이 존재하는 경우에 스프링이 어떤 빈을 주입해야 할지 알 수 없어서 스프링 컨테이너를 초기화하는 과정에서 예외를 발생
  • @Qualifier을 @Autowired와 함께 사용하여 정확히 어떤 bean을 사용할지 지정하여 특정 의존 객체를 주입할 수 있도록 한다

@Resource

  • javax.annotation.Resource
  • 표준 자바(JSR-250 표준) Annotation으로, Spring Framework 2.5.* 부터 지원 가능한 Annotation이다.
  • Annotation 사용으로 인해 특정 Framework에 종속적인 어플리케이션을 구성하지 않기 위해서는 @Resource를 사용할 것을 권장한다.
  • @Resource를 사용하기 위해서는 class path 내에 jsr250-api.jar 파일을 추가해야 한다.
  • 필드, 입력 파라미터가 한 개인 bean property setter method에 적용 가능

Data Validation
@Vaild

  • import javax.validation.Valid;
  • @Size(max=10, min=2, message=”errMsg”)
  • @Email(message=”errMsg”)
  • @NotEmpty(message=”errMsg”)

Configuration

@Configuration

  • Configuration에 사용

@EnableWebSecurity

  • Security에 사용

@SpringBootApplication

  • Spring Boot Application에 사용

@EnableWebMvc

  • Spring MVC에 사용

ETC

@RestControllerAdvice
@ExceptionHandler
@ResponseStatus


Parameter에 사용

@RequestParam

  • HTTP GET 요청에 대해 매칭되는 request parameter 값이 자동으로 들어간다.
    url 뒤에 붙는 parameter 값을 가져올 때 사용한다.

@PathVariable

  • HTTP 요청에 대해 매칭되는 request parameter 값이 자동으로 들어간다.
  • uri에서 각 구분자에 들어오는 값을 처리해야 할 때 사용한다.

@RequestBody

  • 반드시 HTTP POST 요청에 대해서만 처리한다.
  • HTTP POST 요청에 대해 request body에 있는 request message에서 값을 얻어와 매칭한다.
  • RequestData를 바로 Model이나 클래스로 매핑한다

@ModelAttribute

  • @RequestParam과 비슷하다.
  • form 값

JPA

@Table

  • 엔티티 클래스에 매핑할 테이블 정보를 알려준다.
  • Ex) @Table(name = "USER")
  • 이 어노테이션을 생략하면 클래스 이름을 테이블 이름 정보로 매핑한다.

@Entity

  • 실제 DB의 테이블과 매칭될 클래스임을 명시한다.
  • 테이블과 링크될 클래스임을 나타냅니다.
  • 클래스 이름을 언더스코어 네이밍(_)으로 테이블 이름을 매칭한다.
    • Ex) SalesManage스.java -> sales_manager table
  • TIP)
    • Controller에서 쓸 DTO 클래스란 Request와 Response용 DTO는 View를 위한 클래스로, 자주 변경이 필요한 클래스이다.
    • Entity 클래스와 DTO 클래스를 분리하는 이유
      View Layer와 DB Layer를 철저하게 역할 분리를 하는게 좋다.
    • 테이블과 매핑되는 Entity 클래스가 변경되면 여러 클래스에 영향을 끼치게 되는 반면 View와 통신하는 DTO 클래스(Request/ Response 클래스)는 자주 변경되므로 분리해야 한다.
    • 그래서 Entity는 Getter만 선언하고,Setter를 두지 않고, 생성자에서만 모든값을 받아서 만들게 하는게 좋다. (Builder 사용, 기본생성자는 protected)

@Id

  • 해당 테이블의 PK 필드를 나타낸다.

@GeneratedValue

  • PK의 생성 규칙을 나타낸다.
  • TIP) 가능한 Entity의 PK는 Long 타입의 Auto_increment를 추천한다.
  • 기본값은 AUTO로, MySQL의 auto_increment와 같이 자동 증가하는 정수형 값이 된다

@Column

  • 테이블의 컬럼을 나타내면, 굳이 선언하지 않더라도 해당 클래스의 필드는 모두 컬럼이 된다.
  • @Column을 생략하면 필드명을 사용해서 컬럼명과 매핑하게 된다.
    • Ex) @Column(name = "username")
  • 이 Annotation을 사용하는 이유는, 기본값 외에 추가로 변경이 필요한 옵션이 있을 경우 사용한다.
  • Ex) 문자열의 경우 VARCHAR(255)가 기본값인데, 사이즈를 500으로 늘리고 싶거나(ex: title), 타입을 TEXT로 변경하고 싶거나(ex: content) 등의 경우에 사용된다.

@Enumerated

  • 열거형 맵핑
  • EnumType.ORDINAL: 순서를 저장(기본값)
  • EnumType.STRING: 열거형 이름을 그대로 저장, 가급적 이 것을 사용

@Lob

  • CLOB, BLOB 매핑
  • CLOB : String, char[], java.sql.CLOB
  • BLOB : byte[], java.sql.BLOB

@Transient

  • DB와 맵핑하지 않는 필드

Lombok

@NoArgsConstructor

  • 기본생성자를 자동으로 추가한다.
  • access = AccessLevel.PROTECTED
    • 기본생성자의 접근 권한을 protected로 제한
    • 생성자로 protected Posts() {}와 같은 효과
    • Entity 클래스를 프로젝트 코드상에서 기본생성자로 생성하는 것은 막되, JPA에서 Entity 클래스를 생성하는것은 허용하기 위해 추가한다.

@AllArgsConstructor

  • 모든 필드 값을 파라미터로 받는 생성자를 추가한다.

@RequiredArgsConstructor

  • final이나 @NonNull인 필드 값만 파라미터로 받는 생성자를 추가한다.
  • final: 값이 할당되면 더 이상 변경할 수 없다.

@Getter

  • 클래스 내 모든 필드의 Getter 메소드를 자동으로 생성한다.

@Setter

  • Controller에서 @RequestBody로 외부에서 데이터를 받는 경우엔 기본생성자 + set메소드를 통해서만 값이 할당된다. 그래서 이때만 setter를 허용한다.

@ToString

  • @ToString(exclude = "password")
  • 특정 필드를 toString() 결과에서 제외한다.
    • 클래스명(필드1명=필드1값, 필드2명=필드2값, …) 식으로 출력된다

@EqualsAndHashCode

  • equals와 hashCode 메소드 오버라이딩
  • EqualsAndHashCode(callSuper = true)
    • callSuper 속성을 통해 equals와 hashCode 메소드 자동 생성 시 부모 클래스의 필드까지 감안할지 안 할지에 대해서 설정할 수 있다.
    • 즉, callSuper = true로 설정하면 부모 클래스 필드 값들도 동일한지 체크하며, callSuper = false로 설정(기본값)하면 자신 클래스의 필드 값들만 고려한다.

@Builder

  • 어느 필드에 어떤 값을 채워야 할지 명확하게 정하여 생성 시점에 값을 채워준다.
    • 생성자에서 변수 위치가 바뀔때, 문제가 발생할 여지를 없앨수 있음
  • TIP) 생성자와 빌더의 차이
    -생성 시점에 값을 채워주는 역할은 똑같다.
    하지만 빌더를 사용하면 어느 필드에 어떤 값을 채워야 할지 명확하게 인지할 수 있다.
    해당 클래스의 빌더 패턴 클래스를 생성
    생성자 상단에 선언 시 생성자에 포함된 필드만 빌더에 포함된다.

@Data

  • @Getter @Setter @EqualsAndHashCode @AllArgsConstructor 을 포함한 Lombok에서 제공하는 필드와 관련된 모든 코드를 생성한다.

공용 생성일/수정일

@EnableJpaAuditing

  • JPA Auditing을 활성화한다.

@MappedSuperclass

  • JPA Entity 클래스들이 BaseTimeEntity을 상속할 경우 필드들(createdDate, modifiedDate)도 컬럼으로 인식하도록 한다.

@EntityListeners(AuditingEntityListener.class)

  • BaseTimeEntity 클래스에 Auditing 기능을 포함한다.

@CreatedDate

  • Entity가 생성되어 저장될 때 시간이 자동으로 저장된다.

@LastModifiedDate

  • 조회한 Entity의 값을 변경할 때 시간이 자동으로 저장된다.

@Transactional

  • 메소드 내에서 Exception이 발생하면 해당 메소드에서 이루어진 모든 DB 작업을 초기화한다.
  • 즉, save 메소드를 통해서 10개를 등록해야 하는데 5번째에서 Exception이 발생하면 앞에 저장된 4개 까지 모두 롤백한다.
  • (정확히 얘기하면, 이미 넣은걸 롤백시키는건 아니며, 모든 처리가 정상적으로 됐을때만 DB에 커밋하며 그렇지 않은 경우엔 커밋하지 않는 것이다.)
  • 비지니스 로직과 트랜잭션 관리는 모두 Service에서 관리한다.
  • 따라서 일반적으로 DB 데이터를 등록/수정/삭제 하는 Service 메소드는 @Transactional를 필수적으로 가져간다.

AOP

@EnableAspectJAutoProxy

  • import org.springframework.context.annotation.EnableAspectJAutoProxy;
    aop

@Aspect

  • import org.aspectj.lang.annotation.Aspect;

@PointCut

  • execution
  • xml에서의 id: method 이름 // signature

@Before (이전)

  • 어드바이스 타겟 메소드가 호출되기 전에 어드바이스 기능을 수행

@After (이후)

  • 타겟 메소드의 결과에 관계없이(즉 성공, 예외 관계없이) 타겟 메소드가 완료 되면 어드바이스 기능을 수행

@Around (메소드 실행 전후)

  • 어드바이스가 타겟 메소드를 감싸서 타겟 메소드 호출전과 후에 어드바이스 기능을 수행

@AfterReturning (정상적 반환 이후)

  • 타겟 메소드가 성공적으로 결과값을 반환 후에 어드바이스 기능을 수행

@AfterThrowing (예외 발생 이후)

  • 타겟 메소드가 수행 중 예외를 던지게 되면 어드바이스 기능을 수행

@Order

  • Aspect 우선 순위

호출 순서(오류 없을 때)
Before -> Around의 앞 -> target -> Around의 뒤 -> After -> AfterReturning

호출 순서(오류 났을 때)
Before -> Around의 앞 -> target (Error) -> After -> AfterThrowing

@Aspect
public class TestAspect2 {

 @Before("within(com.sist.dao.*)")
 public void aaa(JoinPoint p){
  System.out.println("==Before==");
 }
 @After("within(com.sist.dao.*)")
 public void bbb(JoinPoint p){
  System.out.println("==After==");
 }
 @Around("within(com.sist.dao.*)")
 public Object ccc(ProceedingJoinPoint p) throws Throwable{
  Object obj=null;
  try{
    // Around 앞 코드
   System.out.println("==Around start==");
   
   //target의 point cut에 해당하는 function 호출
   obj=p.proceed();//getBoardName()
   
   // Around 뒤 코드
   System.out.println("==Around end==");
  }catch(Exception ex){System.out.println(ex.getMessage());}
  return obj;
 }
 @AfterReturning(pointcut="within(com.sist.dao.*)",returning="ret")
 public void ddd(JoinPoint p,Object ret){
  System.out.println("==AfterReturning==");
  System.out.println("return Value:"+ret.toString());
 }
 @AfterThrowing(pointcut="within(com.sist.dao.*)",throwing="ex")
 public void eee(JoinPoint p,Throwable ex){
  System.out.println("==AfterThrowing==");
 }
}

Json

@JsonManagedReference
@JsonBackReference
@JsonProperty
@JsonIgnore


Java Config

@Configuration

  • import org.springframework.context.annotation.Configuration;
    @EnableTransactionManagement
    @PropertySource(“classpath:application-properties.xml”)

Jackson

@JsonIgnoreProperties

  • 무시할 속성이나 속성 목록을 표시할 때 사용한다.

@JsonIgnore

  • 필드 레벨에서 무시할 속성을 표시할 때 사용한다.

@JsonIgnoreType

@JsonInclude

  • 어노테이션 속성을 제외할 때 사용한다.

@JsonInclude(JsonInclude.Include.NON_NULL)

  • NON_NULL 사용 시 name이 null인 경우에 제외된다.

@JsonAutoDetect

profile
Fullstack developer

0개의 댓글