ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring Annotation 훑어보기.
    Spring 2018. 4. 16. 21:05




    @Configurable


    도메인 객체는 bean이 아니지만, 도메인 객체에 DAO나 Repository를 주입시켜주어야 하는 경우가 있다.

    하지만 Dependency Injection을 사용하려면 스프링이 관리하는 Bean 이여야 한다. 

    도메인 객체들의 생성을 스프링 컨테이너가 관리할 수 없다. 이 객체들은 애플리케이션 동작 중에 생성 되기 때문에, 스프링이 생명주기를 관리할 bean으로 등록하여 사용할 수 없다. 


    이럴 때 사용하는 것이 @Configurable 애노테이션이다. 이 애노테이션이 붙어있는 클래스를 스프링에 등록해두면, 스프링은 객체가 생성될 때 그 객체가 필요로 하는 Bean들을 주입해준다. 



    @Resource


    @Resource 애노테이션은 bean name 으로 의존 주입을 하고자 하는 경우 사용된다. @Autowired와의 차이점은 타입으로 참조할 빈을 찾았을 때 Injection이 일어난다는 것이다.



    @Target


    애노테이션의 타입을 지정, 해당 애노테이션을 Field에 붙이는 경우 Field, Class나 Enum 등의 타입에 붙일 때는 TYPE 등으로 어떤 대상을 위한 애노테이션인지를 설정한다.



    @Retention 


    @Target 애노테이션과 함께 사용되며 애노테이션의 지속기간을 지정한다. 소스코드에서 단순 주석으로 사용할지, 컴파일시기 까지 유지할지, 런타임까지 유지할 것인지 결정할 수 있다. 



    @Value


    xml에 선언된 프로퍼티를 Controller 에서 사용할 때 @Value 사용



    @Override


    super class나 interface의 method를 override 하고 있음을 명시한다. 실수로 override가 구현되지 않는 경우에 런타임 runtime level에서 오작동 등으로 드러나게 되므로 원인을 찾기 어렵다. 이를 방지하기 위해 @Override Annotation을 사용해 Compile 레벨에서 상위 메소드를 정확히 구현하고 있는지 체크할 수 있다.




    JPA 관련 Annotation  ( Java Persistent API - ORM 을 위한 표준 인터페이스


    @Entity- 테이블에 매핑할 클래스에 붙임. 

    @Id - 기본키(Primary Key) 매핑

    @Column - 테이블의 컬럼명 매핑. 지정안하는 경우 객체 필드명과 동일하게 지정

    @ManyToOne - 다대일 관계 매핑

    @OneToMany - 일대다 관계 매핑 

    @OneToOne - 일대일 관계 매핑

    @ManyToMany - 다대다 관계 매핑

    @JoinColumn(name='') - 외래키 매핑시 사용

    @JoinTable - 다대다 관계를 풀기위해 연결테이블을 사용시 별도 엔티티 생성없이 매핑

    @AttributeOverride - 상속받은 엔티티의 필드명과 테이블의 컬럼 명이 다른 경우 컬럼명을 직접 지정



    @PrePersist - Entity Listener 콜백옵션


    manager persist 의해 처음 호출될 때 실행된다.



    @GenerateValue (strategy=GenerationType.AUTO)


    기본키를 자동생성한다 GenerateValue에 원하는 키 생성전략을 선택한다 (IDENTITY, SEQUENCE, TABLE, AUTO) 

    주키 생성 전략으로 JPA가 지원하는 것은 아래의 네가지이다.

    AUTO - 특정 DB에 맞게 자동 선택

    IDENTITY - DB의 IDENTITY 컬럼을 이용

    SEQUENCE - DB의 시퀀스 컬럼 이용

    TABLE - 유일성이 보장된 데이터베이스 테이블을 이용



    @Enumerated(EnumType.STRING)


    Enum을 사용해 DB에 값을 저장할때 enum의 ordinal() 메소드가 반환하는 integer가 아닌 String을 저장하고 싶을 때 사용



    @EmbeddedId 


    이 애노테이션이 붙은 멤버에 식별자로써 포함된다는 의미, 식별자 클래스는 @Embededable 어노테이션으로 다른 엔티티에 포함된다고 선언해야 하며 이 클래스는 @id를 가질 수 없고 앤티티 객체와 같은 테이블에 저장된다.



    @Embeddable


    식별자 클래스임을 선언하며 이 애노테이션이 붙은 클래스의 멤버는 Primary Key(PK, 식별자)로서 포함된다. 주로 복합키인 경우에 주로 사용한다. 



    @Transient


    DB 테이블에는 존재하지 않지만, 엔티티 클래스에는 등록되어 같이 사용하는 경우 이용한다. @Entity 애노테이션이 붙은 클래스의 모든 속성들은 기본으로 모두 테이블의 필드로 생성하게 되는데. 만약 어떤 속성을 테이블의 필드로 만들고 싶지 않다면 @Transient 애노테이션을 붙여주면 된다. 예를들어 회원가입시 패스워드를 제대로 입력했는지 확인하기 위해 한번 더 입력하는데, 이러한 속성은 DB에 저장할 필요가 없기 때문에 @Transient로 설정해 줄 수 있다. 



    @MapsId


    MapsId는 복합키(Embedable)의 일부만 관계에서 사용될 때 value에서 해당 property를 명시한다. 명시하지 않으면 전체가 사용된다. 

    Hibernate에서 @MapsId로 OneToOne 매핑시에 자식측에 @JoinColumn이 필요하다

    <주의> 양방향 매핑시 부모에 자식값을 설정하고, 자식에도 부모값을 설정해야, 부모를 저장하면 정상적으로 자식도 저장된다.



    @Lock


    동시성 제어를 위해 Table을 Lock 시키는것 같긴한데... 내일 물어봐야겠다.

    LockModeType

    • OPTIMISTIC
    • OPTIMISTIC_FORCE_INCREMENT
    • PESSIMISTIC_READ
    • PESSIMISTIC_WRITE
    • PESSIMISTIC_FORCE_INCREMENT



    @Query


    레파지토리 메서드에 직접 쿼리를 정의하는 경우 @Query 애노테이션을 사용. 실행 시점에 문법 오류를 발견할 수 있는 장점이 있다.





    Declare Custom Annotation



    import java.lang.annotation.*;


    @Inherited

    @Documented

    @Retention(RetentionPolicy.RUNTIME) // 컴파일 이후에도 JVM에 의해서 참조가 가능합니다.

    //@Retention(RetentionPolicy.CLASS) // 컴파일러가 클래스를 참조할 때까지 유효합니다.

    //@Retention(RetentionPolicy.SOURCE) // 어노테이션 정보는 컴파일 이후 없어집니다.

    @Target({

           ElementType.PACKAGE, // 패키지 선언시

           ElementType.TYPE, // 타입 선언시

           ElementType.CONSTRUCTOR, // 생성자 선언시

           ElementType.FIELD, // 멤버 변수 선언시

           ElementType.METHOD, // 메소드 선언시

           ElementType.ANNOTATION_TYPE, // 어노테이션 타입 선언시

           ElementType.LOCAL_VARIABLE, // 지역 변수 선언시

           ElementType.PARAMETER, // 매개 변수 선언시

           ElementType.TYPE_PARAMETER, // 매개 변수 타입 선언시

           ElementType.TYPE_USE // 타입 사용시

    })

    public @interface MyAnnotation {

       /* enum 타입을 선언할 수 있습니다. */

       public enum Quality {BAD, GOOD, VERYGOOD}

       /* String은 기본 자료형은 아니지만 사용 가능합니다. */

       String value();

       /* 배열 형태로도 사용할 수 있습니다. */

       int[] values();

       /* enum 형태를 사용하는 방법입니다. */

       Quality quality() default Quality.GOOD;

    }




    @Required


    Bean에 필수 Property를 표시하는 것으로 필수 Property가 없을 경우 BeanInitializationException이 발생한다. 


    <bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine">

        <property name="templateResolver" ref="templateResolver"/>

    </bean>



    @Documented


    Documented 애노테이션이 지정된 대상의 JavaDoc에 이 애노테이션의 존재를 표기하도록 지정한다. 


    java.lang.annotation.Documented

    @Documented

        public @interface MyAnnotation {

    }



    @MyAnnotation

    public class MySuperClass { ... }



    @Service 


    @Service를 적용한 Class는 비즈니스 로직이 들어가는 Service로 등록된다. 



    @Inherited


    서브 클래스가 부모 어노테이션을 상속받도록 한다.



    @Transactional


    트랜잭션 AOP 적용을 위해 애노테이션을 이용하는 방법이다. 

    <tx:annotation-driven> 태그는 등록된 빈 중에서 @Transactional 이 붙은 클래스나 인터페이스 또는 메소드를 찾아 트랜잭션 어드바이스를 적용해준다.


    @Transactional(propagation=Propagation.SUPPORTS)

    • 이미 시작된 트랜잭션이 있으면 참여하고 그렇지 않으면 트랜잭션 없이 진행하게 만든다. 트랜잭션이 없긴 하지만 경계 안에서 Connection이나 하이버네이트 Session 등을 공유할 수 있다.



      @Component vs @Bean


      Bean을 생성할 때 사용하는 애노테이션, @Bean의 경우 개발자가 컨트롤이 불가능한 외부 라이브러리들을 Bean으로 등록하고 싶은 경우에 사용한다.

      반대로 개발자가 직접 컨트롤이 가능한 Calss들의 경우엔 @Component를 사용한다.



      @PersistenceContext


      DAO가 컨테이너로부터 EntityManger를 직접 주입받으려면 JPA @PersistenceContext 애노테이션을 사용해야 한다. 

      하나의 오브젝트를 고융하는 듯하지만 사실은 각 스레드가 자신의 컨텍스트에 따라서 만들어진 독립적인 오브젝트를 사용하도록 연결해주는 기능을 가진 프록시를 이용하는 것이다. EntityManager 오브젝트는 현재 스레드와 연결된 트랜잭션에 따라서 독립적으로 만들어지고 그 범위 안에서 존재하다가 제거된다. DAO 코드에서는 마치 하나의 EntityManager를 독점적으로 사용하듯이 접근하지만 실제로는 트랜잭션마다 다른 EntityManger 오브젝트를 사용하게 된다.



      EntityManager


      스프링에서는 템플릿 방식의 JpaTemplate뿐 아니라 JPA API를 직접 사용해 DAO를 작성할 수도 있다. JPA의 핵심 프로그래밍 인터페이스는 EntityManager 이다. EntityManager 오브젝트를 가져올 수 있으면 JPA의 모든 기능을 이용할 수 있다.




      @Aspect AOP


      <aop:aspectj-autoproxy /> 선언을 XML 설정파일에 넣어주면 빈으로 등록된 클래스 중에서 클래스 레벨에 @Aspect가 붙은 것을 모두 애스펙트로 자동 등록해준다. 



      @Order 


      @Aspect에 @Order로 값을 지정해 주면 호출순서가 정렬이 된다. 프록시로 감쌀 때 가장 작은 값을 주면 @Around를 기준으로 가장 바깥을 감싸게 된다. 가장 먼저 호출되고, 가장 마지막에 호출되는 것이다. 



      [출처] 


    Designed by Tistory.