Annotation

From JCFWiKi

Jump to: navigation, search

그림:check.gif

  • Spring Annotation 관련 참고 문서와 링크를 올려놓는 방

목차

[편집] 개요

  • spring2.1과 함께 annotation-driven configuration의 장르도 많이 확장되고 계속 진보되고 있습니다.
  • 그 결과 annotions을 통해 Spring's depnendency injection이 가능해졌습니다.
  • 즉, 기존에 applicationContext.xml 파일에서 bean으로 설정했던 사항들을 자바파일에서 간단한 annotation 처리로 대신할 수 있습니다.

[편집] 환경설정

1. 다음 주소를 클릭하여 중간에 this direct link에서 spring-framework-2.1-m3-with-dependencies.zip을 다운로드를 받습니다.

2. 압축을 풀고 적용하려는 프로젝트의 lib 폴더에 다음 jar 파일들을 찾아서 추가합니다.

  • spring.jar
  • spring-aspects.jar
  • spring-mock.jar
  • asm-all-2.1.jar
  • aspectjweaver.jar
  • aspectjrt.jar
  • common-logging.jar
  • log4j.jar
  • junit.jar
    • (NOTE: Java 6을 쓰지 않는다면, common-annotations.jar도 추가합니다.)

4. 사용하려는 프로젝트의 속성> JAVA Build path 에 3에서 추가했던 파일들을 추가합니다.

그림:forbidden.gif

만약에 기존에 파일이 있다고 하더라도 덮어써야합니다. 기존에 있던 파일들은 버전업이 안된 것일 수도 있습니다.

[편집] 프로젝트에 Annotiation 적용하기

[편집] applicationContext.xml

  • applicationContext-user.xml 파일을 만들어 다음을 넣습니다.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:context="http://www.springframework.org/schema/context"
	xsi:schemaLocation="http://www.springframework.org/schema/beans
           http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-2.1.xsd">
 <context:annotation-config />
  • 설명
    • annotiation을 적용하려면 context를 읽어야되므로 http://www.springframework.org/schema/context 를 추가합니다.
    • <context:annotation-config />는 annotiation으로 의존성을 해결한다는 것을 스프링에게 알려 주기 위한 선언문으로 AutowiredAnnotationBeanPostProcessor, CommonAnnotationBeanPostProcessor, RequiredAnnotationBeanPostProcessor 세개의 BeanPostProcessor를 bean으로 등록한 것과 같은 것입니다.

[편집] autowired 적용하기

  • autowired는 말 그대로 자동으로 묶어준다는 뜻으로 클래스 간에 의존성을 나타낼 때 쓰입니다.
  • 보통 Service에서 Dao를 호출하는 경우에 XML 파일에 property name, ref로 의존성을 나타냅니다.
  • 하지만 autowired을 사용하면 XML에서 처리하는 것이 아니라 Service에서 Dao를 호출할 때 위에 @autowired라고 선언만 해주면 됩니다.

[편집] edu 프로젝트에 적용

  • 기존의 applicationContext-user.xml 파일에서
<bean id="userService" class="jcf.showcase.user.service.UserService" >
<property name="userDao" ref="userDao"/>
</bean>
<bean id="userDao" class="jcf.showcase.user.dao.UserDao" >
 <property name="sqlMapClient" ref="sqlMapClient"/>
</bean>
  • 위 부분을 다음과 같이 수정합니다.
<bean id="userService" class="jcf.showcase.user.service.UserService" autowire="byType"/>
 <bean id="userDao" class="jcf.showcase.user.dao.UserDao" autowire="byType"/>
  • autowire="byType" 을 해주는 이유
    • userService bean에서 autowire="byType"를 해주지 않으면 "userDao"를 불러올 때 에러가 발생합니다. (Service가 DAO를 불러올 수 없습니다.)
    • userDao bean에서 autowire="byType"를 해주지 않으면 sqlMapClient가 필요하다는 에러가 발생합니다.(userDao이 sqlMapClient을 참조하므로..)
  • userService.java 파일에 @Autowired을 선언합니다.
    • @Autowired는 필드 또는 생성자 또는 메소드(보통 setter 메소드) 위에 붙일 수 있습니다.
  • 필드에 @Autowired 적용
@Autowired
private UserDao userDao;
  • 메소드에 @Autowired 적용
@Autowired
public void setUserDao(UserDao dao) {
    this.userDao = dao;
}


그림:information.gif

Autowired을 적용하면 xml 파일에서 property name과 ref를 설정하지 않아도 되므로 훨씬 간단해집니다.

[편집] Repository와 Component적용하기

  • Repository
    • 스테레오타입 애노테이션으로 DAO 역할을 하는 클래스 위에 선언해줍니다.
    • 기능 : 해당 클래스에서 발생하는 DB관련 예외를 Spring DAOException으로 전환해주는 일을 합니다
  • Component
    • service역할을 하는 클래스 위에 선언해줍니다.
    • 기능: 스테레오 타입이 붙은 클래스(@Repository가 붙은 클래스)를 모두 찾아서 ApplicationContext의 BeanDefinition 객체로 만들어줍니다.

[편집] edu 프로젝트에 적용

  • UserService 위에 @Component라고 선언
@Component
public class UserService implements IUserService {
  • UserDao 위에 @Repository라고 선언
@Repository
public class UserDao extends BaseSqlMapClientDAO {
  • applicationContext-user.xml 파일 수정
    • 설정파일(ApplicationContext_user.xml)에서 bean으로 userService"와 "userDao"를 정의했던 사항들을 아래와 같이 component-scan tag를 써서 간단히 정의할 수 있습니다.
<context:component-scan base-package="jcf.showcase.user.*"/>

[편집] PostConstruct와 PreDestroy적용하기

[편집] PostConstruct

  • PostConstruct는 bean이 생성된 이후에 수행해야 할 작업(초기화 작업)들을 선언해주는 역할을 합니다.
  • 초기화 작업을 할 method 위에 @PostConstruct라고 선언하거나
  • applicationContext-xml에서 init_method를 사용해서 적용할 수 있습니다.

[편집] PreDestroy

  • 인스턴스가 삭제되기 전에 수행해야 할 작업들을 선언(destruction callback 기능)해주는 역할을 합니다.
  • postconstruct 콜백 메서드에서 얻은 자원이 있다면 여기에서 해제됩니다.
  • applicationContext-xml에서 destroy-method를 사용해서 적용할 수 있습니다.

[편집] 예제

  • 예제소스 : media:sample.zip ((edu프로젝트에는 딱히 초기화나 destruction callback를 적용할 부분이 없어 샘플 예제를 만들어보았습니다.))
  • 방법1: 메소드 위에 다음과 같이 선언하거나
 @PostConstruct
    public void postConstuct(){
        System.out.println("bean이 생성된 이후에 수행됩니다.");
    }
 
 @PreDestroy
 public void PreDestroy(){
     System.out.println("인스턴스가 삭제되기 전에 수행됩니다.");
 }
  • 방법2: applicationContext 파일에 다음과 같이 선언을 합니다.
<bean name="simple" class="sample.Simple"  init-method="postConstuct" destroy-method="initMethod"/>
  • 결과값
sample예제의 console
sample예제의 console


  • 위와 같이 postConstuct 메소드가 PreDestroy보다 먼저 실행되었음을 알 수 있습니다.
  • 즉, postConstuct 메소드는 bean이 생성된 이후에 수행되었고 PreDestroy메소드는 인스턴스가 삭제되기 전에 수행되었습니다.


  • 참조 문서
  1. http://sannotations.sourceforge.net/
  2. Annotation-based configuration http://whiteship.tistory.com/1032
  3. Spring 2.0을 2.0 답게 쓰기 2 : Annotation을 사용해 AOP 설정하기. http://chanwook.tistory.com/190
  4. http://chanwook.tistory.com/384 Annotation-Driven Dependency Injection in Spring 2.1
  5. http://blog.interface21.com/main/2007/05/14/annotation-driven-dependency-injection-in-spring-21/
  6. http://sourceforge.net/project/downloading.php?group_id=73357&use_mirror=jaist&filename=spring-framework-2.1-m1-with-dependencies.zip&11570288
  7. 3.10. Annotation-based configuration
  8. 3.11. Classpath scanning for beans
  9. @Component and @Repository