04장. 어노테이션 기반 설정



어노테이션 쉽게 명시하기

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd

<!--RequiredAnnotationBeanPostProcessor @Required 사용시
         AutowiredAnnotationBeanPostProcessor @Autowired 사용시
         CommonAnnotationBeanPostProcessor @Resource, @PoastConstruct, @PreDestroy 사용시
         ConfigurationClassPostProcessor @Configuration 사용시     
         context를 명시하면 context태그 하나로 사용가능     
        <context:annotation-config/> -->



==================================이론======================================

1.1 @Required 어노테이션을 이용한 필수 프로퍼티 검사

@Required : 필수 프로퍼티를 명시하여 값을 넘겨오는것을 강요 안넘겨오면 에러                    
                     number 프로퍼티를 설정하지 않을 경우 예외 발생


Camera
   import org.springframework.beans.factory.annotation.Required;

 //@Required : 필수요소를 체크해줌 : 스프링에서만 사용할수있다.
    @Required
    public void setNumber(int number){
        this.number = number;
    }

applicationContext.xml
    <!-- @Required 어노테이션 사용시 필수적으로 설정 -->
    <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
     <!-- RequiredAnnotationBeanPostProcessor 대신 context를 명시하면 context태그를 사용가능
            <context:annotation-config/> -->
   
    <bean id="camera1" class="madvirus.spring.chap04.homecontrol.Camera">
        <!--
            number 프로퍼티에 @Required 어노테이션 적용
            number 프로퍼티를 설정하지 않을 경우 예외 발생
         -->
         <property name="number" value="1" />
    </bean>

1.2 @Autowired 어노테이션을 이용한 자동 설정

@Autowired : 타입을 이용하여 의존하는 객체를 삽입해준다. 생성자, 필드,메서드 세곳에 적용이 가능하다.
  프로퍼티 설정 메서드에 @Autowired 적용하면  어노테이션 타입을 이용한 프로퍼티 자동 설정 기능을 제공한다.
   
@Required 와 마찬가지로 @Autowired기본적으로  값을 강요하는데 필수여부를 조정해줄수있다.
@Autowired(required=false) 기본값은 true이다

    <!-- @Autowired 어노테이션 사용시 필수적으로 설정 -->
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
    <bean id="monitor" class="madvirus.spring.chap04.homecontrol.SystemMonitor"/>
    <bean id="sender" class="madvirus.spring.chap04.homecontrol.SmsSender"/>

@Autowired 어노테이션은 타입을 기반으로하기 때문에 자동 설정할 타입이 두개 이상 존재할 경우 예외를 발생 시킨다.
그래서 @Qualifier 어노테이션을 이용한 자동 설정 제한 을 이용한다.

@Qualifier
로 레코드를 지정   
    <!-- @Qualifier 어노테이션을 이용한 자동 설정 제한 -->
    <bean id="systemMonitor" class="madvirus.spring.chap04.homecontrol.SystemMonitor2"/>
    <bean id="recorder" class="madvirus.spring.chap04.homecontrol.Recorder">
        <qualifier value="main"/>
    </bean>   


1.3 @Resource 어노테이션을 프로퍼티 설정

어플리케이션에서 필요로 하는 자원을 자동 연결할때 사용된다.
의존하는 빈 객체를 전달할 때 사용한다.
@Resource 어노테이션을 사용 하려면 name 속성에 자동으로 연결할 빈 객체의 이름을 입력 하면된다.

동일한 객체타입인데 객체주소가 다른 여러객체가 들어올때 사용하면 GOOD!!


<!-- @Resource 어노테이션 사용시 필수적으로 설정 -->
<!-- 스프링에서의 singleton id 하나당 객체한개 -->
<bean id="homeController" class="madvirus.spring.chap04.homecontrol.HomeController"/>
<bean id="camera2" class="madvirus.spring.chap04.homecontrol.Camera" p:number="2"/>
<bean id="camera3" class="madvirus.spring.chap04.homecontrol.Camera" p:number="3"/>
<bean id="camera4" class="madvirus.spring.chap04.homecontrol.Camera" p:number="4"/>


1.4 @PostConstruct 어노테이션및 @PreDestory어노테이션과 라이플 사이클

라이프 사이클(생명주기) 초기화 및 제거 과정을 제공한다.
@PostConstruct는 의존하는 객체를 설정한 이후에 초기화 작업을 수행할 메서드에 적용된다.
@PreDestroy는 컨테이너에서 객체를 제거하기 전에 호출될 메서드에 적용된다.
스프링 설정 파일에서 init-method 속성과  destroy-method 속성성을 이용하여 명시한 메서드와 동일한 시점에 실행된다.

*사용후 재사용가능하게 메모리정리를안함
ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
* 작업이끝나고 메모리정리까지함
AbstractApplicationContext context = new ClassPathXmlApplicationContext(configLocations);

        @PostConstruct
        public void init(){
            System.out.println("init 메소드 동작");
        }
       
        @PreDestroy
        public void close(){
            System.out.println("close 메소드 동작");
        }



2.1 어노테이션을 이용한 자동스캔

@Component, @Service, @Controller 는 클래스 선언부분에 붙게된다.

@Component 어노테이션은 클래스에 적용했다면

//스프링이 클래스를 검색할 패키지를 지정.
<context:component-scan base-package="madvirus.spring.chap04.homecontrol"/>
*@Component  어노테이션 적용된 클래스를 검색하여 빈으로 등록하게된다.

<context:annotation-config/>와같이<context:component-scan/>  태그를 쓰면
RequiredAnnotationBeanPostProcessor @Required 사용시
AutowiredAnnotationBeanPostProcessor @Autowired 사용시
CommonAnnotationBeanPostProcessor @Resource, @PoastConstruct, @PreDestroy 사용시
ConfigurationClassPostProcessor @Configuration 사용시    
같은 어노테이션이 함께 적용된다.

* 명시적으로 설정해야하는부분이 많아서 오토스캔만 사용하는경우는 극히적다. 적당히 썩어서 사용

3.1 @Configuration 어노테이션과 @Bean 어노테이션을 이용한 코드 기반 설정
스프링3.0에 새로생김

@Configuration 과 @Bean 을 이용해서 스프링 컨텐이너에 새로운 빈 객체를 제공할 수 있다.

@Configuration
public class SpringConfig{

     @Bean // XML 빈정의 설정시 해당 메소드 이름을 사용한다.
     //@Bean(name="smsAlarmDevice") //메서드 이름이 아닌 다른이름을 사용하고 싶다면 name 속성을 사용
     //@Bean(autowire = Autowire.BY_NAME) 
     //Autowire.BY_NAME:이름을 이용해서 자동연관처리, Autowire.BY_TYPE:타입을 이용하여 자동연관처리, Autowire.NO:자동연관처리 안함
     public AlarmDevice alarmDevice(){
            return new SmsAlarmDevice();
     }
}

@Configuration 적용된 클래스를 설정정보로 이용하는 방법.

@Configuration
public class MainConfig{

     public static void main(String[] args){

            ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

            //한개이상의 @Configuration 적용 클래스로부터 ApplicationContext 를 생성하고 싶다면 @Configuration 목록을 지정
            //ApplicationContext context = new AnnotationConfigApplicationContext
         //                                                   (
ArticleServiceConfig.class,ArticleRepositoryConfig.class);

            HomeController homeController = context.getBean("homeController",HomeController .class);
            ....
     }
}

XML 설정파일에서도 @Configuration 적용된 클래스를 사용할수있다.

<bean class="org.springframework.beans.factory.annotation.ConfigurationClassPostProcessor"/>// @Configuration 사용시 
<bean class="madvirus.spring.chap04.config.SpringConfig"/> 

//<context:component-scan base-package="madvirus.spring.chap04.config.SpringConfig">

반대로 @Configuration 적용된 클래스 XML 설정파일 정보를 사용하기

@Configuration
@ImportResource("classpath:/article-repository.xml")
//두개이상사용시 배열형태로
@ImportResource({"classpath:/article-repository.xml", "
classpath:/article-datasource.xml"})
public class SpringConfig{

     @Bean
   
public AlarmDevice alarmDevice(){
            return new SmsAlarmDevice();
     }
}

@Configuration 클래스 간의 의존 설정

@Configuration
public class ArticleServiceConfig{

     @Autowired
     private ArticleRespositoryConfig respositoryConfig;

     @Bean
   
public ArticleService articleService(){
            return new ArticleServiceImpl(respositoryConfig.articleRepository());
     }
}

@Import를 이용한 @Configuration 클래스의 조합

@Configuration
@Import({"ArticleServiceConfig.class, ArticleRepositoryConfig.class"})
public class SpringConfig{

     @Bean
   
public AlarmDevice alarmDevice(){
            return new SmsAlarmDevice();
     }
}



===============================프로젝트===================================
예제.
madvirus.spring.chap04.homecontrol
      AlarmDevice (@Resource)
      Camera (@Required)
      Homecontrolloer (@Resource)
      Homecontrolloer2 (@PostConstruct,@PreDestroy)
      Main (@Required)
      Main02 (@Autowired)
      Main03 (@Autowired - @Qualifier)
      Main04 (@Resource)
      Main05 (@PostConstruct,@PreDestroy)
      Main06 (@Component )
      MessageSender (@Autowired)
      Recorder (@Autowired - @Qualifier)
      SmsSender (@Autowired)
      SystemMonitor (@Autowired)
      SystemMonitor2 (@Autowired - @Qualifier)
      Viewer (@Resource)

applicationContext.xml
applicationContext02.xml

==================================코드======================================
예제.
madvirus.spring.chap04.homecontrol
      AlarmDevice (@Resource)
package madvirus.spring.chap04.homecontrol;

public interface AlarmDevice {
   
    void alarm(String name);
}

       Camera (@Required)
package madvirus.spring.chap04.homecontrol;

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

public class Camera {
   
    private int number;
   
    public Camera() {
    }

    //@Required : 필수요소를 체크해줌 : 스프링에서만 사용할수있다.
    @Required
    public void setNumber(int number){
        this.number = number;
    }

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

      Homecontrolloer (@Resource)
package madvirus.spring.chap04.homecontrol;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;

@Component("homeController")
public class HomeController {

   
        private AlarmDevice alarmDevice;
        private Viewer viewer;

        //@Resource 프로퍼티 설정
        //결과적으론 private Camera camera1 에보관.
        @Resource(name = "camera1")
        private Camera camera1;

        @Resource(name = "camera2")
        private Camera camera2;

        @Resource(name = "camera3")
        private Camera camera3;       

        private Camera camera4;

        public void setCamera1(Camera camera1) {
            this.camera1 = camera1;
        }

        public void setCamera2(Camera camera2) {
            this.camera2 = camera2;
        }

        public void setCamera3(Camera camera3) {
            this.camera3 = camera3;
        }

        //메소드에도 명시할수있음
        @Resource(name = "camera4")
        public void setCamera4(Camera camera4) {
            this.camera4 = camera4;
        }

        @Override
        public String toString() {
            return "Homecontrolloer [camera1=" + camera1 + ", camera2="
                    + camera2 + ", camera3=" + camera3 + ", camera4=" + camera4
                    + "]";
        }       
}

      Homecontrolloer2 (@PostConstruct,@PreDestroy)
package madvirus.spring.chap04.homecontrol;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;

public class HomeController2 {

   
        private AlarmDevice alarmDevice;
        private Viewer viewer;

        //@Resource 프로퍼티 설정
        //결과적으론 private Camera camera1 에보관.
        @Resource(name = "camera1")
        private Camera camera1;

        @Resource(name = "camera2")
        private Camera camera2;

        @Resource(name = "camera3")
        private Camera camera3;       

        private Camera camera4;

        public void setCamera1(Camera camera1) {
            this.camera1 = camera1;
        }

        public void setCamera2(Camera camera2) {
            this.camera2 = camera2;
        }

        public void setCamera3(Camera camera3) {
            this.camera3 = camera3;
        }

        //메소드에도 명시할수있음
        @Resource(name = "camera4")
        public void setCamera4(Camera camera4) {
            this.camera4 = camera4;
        }

        @PostConstruct
        public void init(){
            System.out.println("init 메소드 동작");
        }
       
        @PreDestroy
        public void close(){
            System.out.println("close 메소드 동작");
        }
}

      Main (@Required)
package madvirus.spring.chap04.homecontrol;

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

public class Main {
   
    public static void main (String[] args){
        String[] configLocations = new String[] {"applicationContext.xml"};
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        Camera camera = context.getBean("cameara1", Camera.class);
        System.out.println(camera);
    }
}

      Main02 (@Autowired)
package madvirus.spring.chap04.homecontrol;

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

public class Main02 {
   
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        SystemMonitor monitor = context.getBean("monitor",SystemMonitor.class);
       
        System.out.println(monitor.getSender());
    }
}

      Main03 (@Autowired - @Qualifier)
package madvirus.spring.chap04.homecontrol;

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

public class Main03 {
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        SystemMonitor2 monitor = context.getBean("systemMonitor",SystemMonitor2.class);

        System.out.println(monitor.getSender());
        System.out.println(monitor.getRecorder());
    }
}

      Main04 (@Resource)
package madvirus.spring.chap04.homecontrol;

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

public class Main04 {
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        HomeController home = context.getBean("homeController" , HomeController.class);
       
        System.out.println(home);
    }   
}

      Main05 (@PostConstruct,@PreDestroy)
package madvirus.spring.chap04.homecontrol;

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

public class Main05 {
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext.xml" };
        //사용후 재사용가능하게 메모리정리를안함
        //ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        //작업이끝나고 메모리정리까지함
        AbstractApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        context.registerShutdownHook();
       
        HomeController2 home = context.getBean("homeController2" , HomeController2.class);       
    }   
}

      Main06 (@Component )
package madvirus.spring.chap04.homecontrol;

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

public class Main06 {
    public static void main(String[] args){
        String[] configLocations = new String[] { "applicationContext02.xml" };
        ApplicationContext context = new ClassPathXmlApplicationContext(configLocations);
       
        HomeController home = context.getBean("homeController" , HomeController.class);
       
        System.out.println(home);
    }   
}

      MessageSender (@Autowired)
package madvirus.spring.chap04.homecontrol;

public interface MessageSender {

}

      Recorder (@Autowired - @Qualifier)
package madvirus.spring.chap04.homecontrol;

public class Recorder {

}

      SmsSender (@Autowired)
package madvirus.spring.chap04.homecontrol;

public class SmsSender implements MessageSender {
    public SmsSender (){}
   
    public SmsSender(boolean value){}
}

      SystemMonitor (@Autowired)
package madvirus.spring.chap04.homecontrol;

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

public class SystemMonitor {

    private int periodTime;
    private MessageSender sender;
   
   
    public SystemMonitor() {}
   
    public SystemMonitor(int period) {
        this(period, null);
    }
   
    public SystemMonitor(int period, MessageSender sender) {
        this.periodTime = period;
        this.sender = sender;
    }

    public int getPeriodTime() {
        return periodTime;
    }

    public void setPeriodTime(int periodTime) {
        this.periodTime = periodTime;
    }

    public MessageSender getSender() {
        return sender;
    }
   
    @Autowired
    public void setSender(MessageSender sender) {
        this.sender = sender;
    }   
}

      SystemMonitor2 (@Autowired - @Qualifier)
package madvirus.spring.chap04.homecontrol;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class SystemMonitor2 {

    private MessageSender sender;

    @Autowired
    @Qualifier("main")
    private Recorder recorder;
   

    public SystemMonitor2(MessageSender sender){
        this.sender = sender;
    }
   
    public SystemMonitor2() {}

    public MessageSender getSender() {
        return sender;
    }
   
    @Autowired
    public void setSender(MessageSender sender) {
        this.sender = sender;
    }

    public Recorder getRecorder() {
        return recorder;
    }
   
    public void setRecorder(Recorder recorder) {
        this.recorder = recorder;
    }
}

      Viewer (@Resource)
package madvirus.spring.chap04.homecontrol;

public interface Viewer {

        void add (Camera camera1);
       
        void draw();
}

applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <!--RequiredAnnotationBeanPostProcessor @Required 사용시
         AutowiredAnnotationBeanPostProcessor @Autowired 사용시
         CommonAnnotationBeanPostProcessor @Resource, @PoastConstruct, @PreDestroy 사용시
         ConfigurationClassPostProcessor @Configuration 사용시    
        context를 명시하면 context태그 하나로 사용가능    
        <context:annotation-config/> -->
     
    <!-- @Required 어노테이션 사용시 필수적으로 설정 -->
    <bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
    <bean id="camera1" class="madvirus.spring.chap04.homecontrol.Camera">
        <!--
            number 프로퍼티에 @Required 어노테이션 적용
            number 프로퍼티를 설정하지 않을 경우 예외 발생
         -->
         <property name="number" value="1" />
    </bean>
   
    <!-- @Autowired 어노테이션 사용시 필수적으로 설정 -->
    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
    <bean id="monitor" class="madvirus.spring.chap04.homecontrol.SystemMonitor"/>
    <bean id="sender" class="madvirus.spring.chap04.homecontrol.SmsSender"/>
   
    <!-- @Qualifier 어노테이션을 이용한 자동 설정 제한 -->
    <bean id="systemMonitor" class="madvirus.spring.chap04.homecontrol.SystemMonitor2"/>
    <bean id="recorder" class="madvirus.spring.chap04.homecontrol.Recorder">
        <qualifier value="main"/>       
    </bean>   
   
    <!-- @Resource 어노테이션 사용시 필수적으로 설정 -->
    <!-- 스프링에서의 singleton id 하나당 객체한개 -->
    <bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
    <bean id="homeController" class="madvirus.spring.chap04.homecontrol.HomeController"/>
    <bean id="camera2" class="madvirus.spring.chap04.homecontrol.Camera" p:number="2"/>
    <bean id="camera3" class="madvirus.spring.chap04.homecontrol.Camera" p:number="3"/>
    <bean id="camera4" class="madvirus.spring.chap04.homecontrol.Camera" p:number="4"/>
   
    <!-- @PostConstruct 어노테이션 및    @PreDestroy 어노테이션 사용 -->
    <bean id="homeController2" class="madvirus.spring.chap04.homecontrol.HomeController2"/>    
   
   
</beans>

applicationContext02.xml
<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop"
    xmlns:context="http://www.springframework.org/schema/context"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
       http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-3.0.xsd">


    <context:component-scan base-package="madvirus.spring.chap04.homecontrol"/>
   
    <bean id="camera1" class="madvirus.spring.chap04.homecontrol.Camera" p:number="1"/>
    <bean id="camera2" class="madvirus.spring.chap04.homecontrol.Camera" p:number="2"/>
    <bean id="camera3" class="madvirus.spring.chap04.homecontrol.Camera" p:number="3"/>
    <bean id="camera4" class="madvirus.spring.chap04.homecontrol.Camera" p:number="4"/>
   
</beans>

==================================결과값=====================================

1.@Required

  @Required에 값을 안넣어주는경우.


2.@Autowired

3.@Autowired - @Qualifier


4.@Resource

5.@PostConstruct,@PreDestroy

6.@Component


'스프링3.0' 카테고리의 다른 글

Spring 3.0 AOP  (0) 2012.05.14
Spring3.0 DI 3  (0) 2012.05.14
Spring3.0 message&event  (1) 2012.05.14
Spring3.0 Di 2  (0) 2012.05.14
Spring3.0 DI AOP  (0) 2012.05.14
Posted by 사라링
BLOG main image
.. by 사라링

카테고리

사라링님의 노트 (301)
JSP (31)
J-Query (41)
JAVA (24)
VM-WARE (0)
디자인패턴 (1)
스크랩 (0)
스트러츠 (3)
안드로이드 (11)
오라클 (45)
우분투-오라클 (1)
이클립스메뉴얼 (6)
스프링3.0 (23)
자바스크립트 (10)
HTML5.0 (17)
정보처리기사 (1)
기타(컴퓨터 관련) (1)
문제점 해결 (3)
프로젝트 (2)
AJAX (4)
하이버네이트 (3)
트러스트폼 (11)
Jeus (2)
재무관리(회계) (5)
정규식 (5)
아이바티스 (8)
취미 (2)
소프트웨어 보안 관련모음 (0)
정보보안기사 (6)
C언어 베이직 및 프로그램 (3)
보안 관련 용어 정리 (2)
넥사크로 (6)
Total :
Today : Yesterday :