개발(합니다)/Java&Spring

Spring 어노테이션 정리

otrodevym 2018. 12. 15. 13:44
반응형

Spring에 JWT를 pom.xml에 추가하고 context.xml에서 설정을 하려고 했습니다.

관련 자료를 찾아보니 Spring boot로 어노테이션 설정 내용이 많았습니다.

xml 설정과 어노테이션 설정을 정리합니다.





어노테이션이란

클래스, 메소드 등에 '@'로 선언하여 컴파일러에게 알립니다.


1. Java 어노테이션
: 빌트 인 어노테이션이라고 합니다.

@Override, @Deprecated, @SuppressWarinings 등이 있습니다.


- @Override : 메소드를 오버라이드 되었는지를 검증하고 부모 클래스나 인터페이스에서 해당 메소드를 찾을 수 없으면 컴파일 오류가 납니다.


- @Deprecated : 메소드를 사용하지 않도록 권고하고 사용 시 컴파일 경고가 납니다.


- @SuppressWarinings : 컴파일에서 경고를 내면 무시하라고 합니다.


- @SafeVarargs : 제너릭 같은 가변인자를 사용 할 때 경고를 무시합니다.(JDK 7이상)


- @FunctionalInterface : 람다 함수 등과 같은 인터페이스를 지정하고 메소드가 없거나 두개 이상이면 컴파일 오류가 납니다. (JDK 8 이상) -> 람다, 함수형 프로그래밍 공부 필요

-> 일급 함수를 지향하기 위해 나왔고 interface에 하나의 메소드를 선언해야 합니다.



2. 매타 어노테이션 
: 커스텀 어노테이션을 만들어 낼 수 있습니다.

@Controller, @Service, @ReqeustMapping 등이 있습니다.


- @Retention : 어노테이션이 언제부터 어디까지 영향을 유지할지를 정합니다.


- @Documented : java doc 문서에 표시합니다.


- @Target : 어노테이션을 적용 할 위치를 정합니다.

 ElementType.ANNOTATION_TYPE

 어노테이션에 적용 

 ElementType.CONSTRUCTOR 

 생성자 선언 시  적용

 ElementType.FIELD

 enum 상수를 포함한 필드 또는 프로퍼티에 적용

 ElementType.LOCAL_VARIABLE

 지역 변수 선언 시 적용

 ElementType.METHOD

 메소드 레벨 선언 시 적용

 ElementType.PACKAGE

 패키지 선언 시 적용

 ElementType.PARAMETER

 메소드 파라미터에 적용

 ElementType.TYPE 

 클래스, 인터페이스, enum 등 선언 시 적용


- @Inherited : 자식 클래스가 어노테이션을 상속 받을 수 있도록 한다.

 RententionPolicy.SOURCE

 소스에서만 사용됨 / 컴파일시 없어짐

 RententionPolicy.CLASS

 소스, 클래스에서 사용됨 / 컴파일러에 의해 참조 되지만 가상 머신에서 삭제 됨

 RententionPolicy.RUNTIME

 소스, 클래스, 실행시에 사용됨 / 가상머신에 의 참조 됨


- @Repeatable : 반복적으로 두 번 이상 선언 할 수 있게 합니다.(JDK 8 이상)




3. 커스텀 어노테이션

@interface : 인터페이스에 @를 추가 하는것으로 커스텀 어노테이션을 선언합니다.

리플렉션 : 어노테이션 정보를 분석하는 클래스
getAnnotation(), getAnnotations(), getDeclaredAnnotations()가 있습니다.
-> 객체를 통해 클래스의 정보를 분석하는 프로그래밍 기법

package annotation_test;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface AnnotationTest {
    public int num();
    public String text() default "This is first annotation";

}



package annotation_test;

import java.lang.reflect.Method;

@AnnotationTest(num=0)
public class UserAnnotationTest {
    @AnnotationTest(num=1)
    public static void main(String args[]) {
        UserAnnotationTest ano = new UserAnnotationTest();
        ano.checkAnnotation(UserAnnotationTest.class);
    }
    
    @AnnotationTest(num=2)
    public void annotationSample1() {
        
    }
    
    @AnnotationTest(num=3, text="second")
    public void annotationSample2() {
        
    }
    
    public void checkAnnotation(Class userAnno) {
        Method[] methods = userAnno.getDeclaredMethods();
        for(Method tempMethod : methods) {
            AnnotationTest annotation = tempMethod.getAnnotation(AnnotationTest.class);
            if(annotation != null) {
                int num = annotation.num();
                String text = annotation.text();
                System.out.println(tempMethod.getName() + "() : number = " + num +
" text = " + text);
            }else {
                System.out.println(tempMethod.getName() + "() : annotation is null");
            }
        }
    }
}


4. Spring 어노테이션

@Bean과 @Component 차이


- @Bean : 개발자가 생성 하지 않은 외부 라이브러리 객체를 사용 할 때/ 반환하는 객체를 빈으로 등록


- @Component : 개발자가 직접 생성한 클래스를 사용 할 때 / 선언 된 객체를 빈으로 등록



기본 Bean 설정 

- @Controller : MVC 컨트롤러 임을 명시합니다.


- @Service : 비즈니스 로직을 처리하는데 사용합니다.


- @Repository : DAO, 퍼시스턴스로써 DB를 처리하는데 사용합니다.


- @RestController : @RespnseBody를 기본으로 하는 컨트롤러(@Contoller)임을 선언합니다.


DI(Dependency Injection) 처리

- @Autowired : Spring framework 전용이며 타입에 맞춰서 연결합니다.


- @Inject : 자바(JSR)의 기존 어노테이션으로 타입에 맞춰서 연결합니다.


- @Resource : 자바(JSR)의 기존 어노테이션으로 이름에 맞춰서 연결합니다.


- @Qualifier : 같은 이름의 빈을 지시자를 넣어 특정한 빈 만들어 연결합니다.


JSR : 자바 표준 어노테이션



기타 Bean 설정

- @Required : 설정 상의 프로퍼티를 필수로 설정해야 합니다.


- @Scope : 스프링은 싱글톤이 기본인데 범위를 변경하고 싶을 때 사용합니다.


- @PostConstruct : 스프링에서 객체 생성 후 호출 전 수행으로 사용합니다.


- @PreDesTroy : 스프링에서 객체 제거 전 수행으로 사용합니다.


- @RequestMapping : URL을 매핑 할 수 있습니다.

value(path) : URL을 매핑합니다.

method : 요청 method를 매핑합니다.

params : 요청 파라미터를 매핑합니다.

headers : 특정 헤더 값에 매핑합니다.


- @RequestParam : key, value에 따라 파라미터를 매핑합니다.


- @SessionAttribues : Session정보의 model 값을 유지합니다.


- @RequestBody : request body 정보를 받습니다.


- @ResponseBody : json 형태로 전송할 때 사용합니다.


- @PathVariable : URL의 일부를 파싱합니다.


- @CookieValue : 현재 사용자의 존재하는 쿠키 값 추출



5. Spring 설정

- 필드 생성자는 생성하지 않아야 합니다.
스프링에서 객체를 생성하고 set을 실행합니다.
- 어노테이션 명칭과 클래스, 인터페이스 명칭이 같으면 안됩니다.
@Controller / public class Controller 하면 안됩니다.

1. xml 설정

Java.bean
package com.spring.mvc.beans;

public class JavaBean {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "JavaBean [name=" + name + "]";
    }
}


servlet-context.xml

    <beans:bean id="TestBean" class="com.spring.mvc.beans.JavaBean">
        <beans:property name="name" value="Hello"></beans:property>
    </beans:bean>


TestBean.java

package com.spring.mvc;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestBeans {
    public static void main(String args[]) {
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml");
        System.out.println(ac.getBean("TestBean"));
        System.out.println(ac.getBean("TestBean").getClass().getName());
            try {
                System.out.println(ac.getBean("TestBean").getClass().getDeclaredField("name").getName());
            } catch (BeansException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (SecurityException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
    }
}



출력

JavaBean [name=Hello]

com.spring.mvc.beans.JavaBean

name



2. 어노테이션 설정


TestBeans2.java

package com.spring.mvc.beans;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component(value="MyTestBeans2")
public class TestBeans2 {
    private String name;
    
    
    @Value("getName")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public String toString() {
        return "TestBeans2 [name=" + name + "]";
    }
    
}



servlet-context.xml

<context:component-scan base-package="com.spring.*" />



TestBeans2Run.java

package com.spring.mvc;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class TestBeans2Run {
    public static void main(String args[]) {
        ApplicationContext ac = new ClassPathXmlApplicationContext(
                "file:src/main/webapp/WEB-INF/spring/appServlet/servlet-context.xml");
        System.out.println(ac.getBean("MyTestBeans2"));
    }
}



3. 자바 설정

spring 3.x버전에서 한다면 CGLIB를 추가해야합니다.


TesdtBeans3.java

package com.spring.mvc.beans;

import org.springframework.beans.factory.annotation.Value;

public class TestBeans3 {
    private String name;

    @Value("configBean")
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


JavaConfigureation.java

package com.spring.mvc.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.spring.mvc.beans.TestBeans3;

@Configuration
public class JavaConfiguration {
    
    @Bean(name="JavaTestBean")
    public TestBeans3 TestBeansCall() {
        return new TestBeans3();
    }
}


TestBeans3.java

package com.spring.mvc;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.spring.mvc.config.JavaConfiguration;

public class TestBeans3 {
    public static void main(String args[]) {
        ApplicationContext ac = new AnnotationConfigApplicationContext(JavaConfiguration.class);
        System.out.println(ac.getBean("JavaTestBean"));
        try {
            System.out.println(ac.getBean("JavaTestBean").getClass().getDeclaredField("name"));
        } catch (BeansException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (NoSuchFieldException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SecurityException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
}


반응형