전자정부 프레임웍을 사용하기에 앞서 전자정부 프레임웍이 Spring 기반으로 되어 있으나, 어노테이션을 많이 사용한다고 하여 어노테이션에 대해 간략하게 정리를 해보려고 한다.
어노테이션은 Spring 2.0 & java 5 부터 제공하고 있다.
1. @Required 어노테이션을 이용한 필수 프로퍼티 검사
# Camera.java 파일
import org.springframework.beans.factory.annotation.Required;
public class Camera {
public Camera() {
}
<< 스샷 >>public class Camera {
private int number;
public Camera() {
}
@Required
public void setNumber(int number) {
this.number = number;
}
}
#방식1 ApplicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<bean id="camera1" class="madvirus.spring.chap04.homecontrol.Camera">
<property name="number" value="1" />
</bean>
</beans>
xmlns:p="http://www.springframework.org/schema/p" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
<bean id="camera1" class="madvirus.spring.chap04.homecontrol.Camera">
<property name="number" value="1" />
</bean>
</beans>
@Required 어노테이션을 추가했다고 해서 해당프로퍼티를 인식하지 않기 때문에 ApplicationContext.xml 파일에 프로퍼티를 위와 같이 명시해 주어야 한다.
applicationContext.xml 에는 2가지 방식이 있는데 하나느 위 처럼
1. CommonAnnotationBeanPostProccessor 클래스를 bean 으로 명시해 주는 방식이 있고 또 하나는
2. <context:annotation-config> 태그를 사용하는 방식이 있다.
#방식 2 ApplicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<beans>
<context:annotation-config /> 태그는 BeanPostProcessor 를 함께 등록해 주므로
- RequiredAnnotationBeanPostProcessor : @Required 어노테이션 처리
- AytowiredAnnotationBeanPostProcessor : @Autowired 어노테이션 처리
- CommonAnnotationBeanPostProcessor : @Resource, @PostConstruct, @PreDestroy 어노테이션 처리
- ConfigurationClassPostProcessor : @Configuration 어노테이션 처리
특별히 특정 기능을 사용하지 않아야 하는 경우가 아니라면
<context:annotation-config> 태그를 사용하는 것이 설정파일을 단순하게 만들어 준다.
- RequiredAnnotationBeanPostProcessor : @Required 어노테이션 처리
- AytowiredAnnotationBeanPostProcessor : @Autowired 어노테이션 처리
- CommonAnnotationBeanPostProcessor : @Resource, @PostConstruct, @PreDestroy 어노테이션 처리
- ConfigurationClassPostProcessor : @Configuration 어노테이션 처리
특별히 특정 기능을 사용하지 않아야 하는 경우가 아니라면
<context:annotation-config> 태그를 사용하는 것이 설정파일을 단순하게 만들어 준다.
2. @Autowired 어노테이션을 이용한 자동설정
: @Autowired 어노테이션은 의존관계를 자동으로 설정할 때 사용 한다.
(Spring2.5 추가된 기능으로 의존하는 객체를 삽입)
생성자, 필드, 메서드 세곳에 적용이 가능하다.
#Viewer.java (Interface 생성)
public interface Viewer {
void add(Camera camera1);
void draw();
void draw();
}
#MonitorViewer.java
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component("viewer")
public class MonitorViewer implements Viewer {
@Autowired
private DisplayStrategy displayStrategy;
public void setDisplayStrategy(DisplayStrategy displayStrategy) {
this.displayStrategy = displayStrategy;
}
@Override
public void draw() {
System.out.println("DisplayType "
+ displayStrategy.getDisplayType().name() + "로 카메라 이미지 출력");
}
@Override
public void add(Camera camera) {
System.out.println("MonitorViewer에 " + camera + " 영상 추가");
}
}
import org.springframework.stereotype.Component;
@Component("viewer")
public class MonitorViewer implements Viewer {
@Autowired
private DisplayStrategy displayStrategy;
public void setDisplayStrategy(DisplayStrategy displayStrategy) {
this.displayStrategy = displayStrategy;
}
@Override
public void draw() {
System.out.println("DisplayType "
+ displayStrategy.getDisplayType().name() + "로 카메라 이미지 출력");
}
@Override
public void add(Camera camera) {
System.out.println("MonitorViewer에 " + camera + " 영상 추가");
}
}
<<스샷 Viewer.java 와 MonitorViwer.java>>
Viewer.java
MonitorViewer.java
# 방식1 ApplicationContext.xml
<bean
class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<beans>
위와 마찬가지로 2가지 방식이 사용되나 <context:annotation-config/> 를 쓰는것이 간편하다.
제네릭이 적용된 컬렉션 타입을 사용하는 경우 java.util.List 타입이나 java.util.Set 타입을 이용해서 특정 타입의 빈 객체 목록을 전달 받을 수 있다.
2-1. @Autowired 어노테이션 적용 프로퍼티의 필수 여부 지정
: 타입을 이용해서 자동적으로 프로퍼티 값을 설정하기 때문에, 해당 타입의 빈 객체가 존재하지 않거나 또는 빈 객체가 두 개 이상 존재할 경우 스프링은 @Autowired 어노테이션이 적용된 빈 객체를 생성할 때 예외를 발생 시킨다.
프로퍼티를 반드시 설정할 필요가 없는경우도 있는데 이럴땐 @Autowired 어노테이션에 required 속성의 값을 false 로 지정해 주면 된다.
#HomeController.java
import java.util.List;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component("homeController")
public class HomeController {
private AlarmDevice alarmDevice;
private Viewer viewer;
@Resource(name = "camera1")
private Camera camera1;
@Resource(name = "camera2")
private Camera camera2;
@Resource(name = "camera3")
private Camera camera3;
private Camera camera4;
private List<InfraredRaySensor> sensors;
@Autowired
@Qualifier("main") //@Qualifier 어노테이션을 사용 - bean 객체의 수식어를 값으로 가짐
private Recorder recorder;
private DisplayStrategy displayStrategy;
@Autowired //메서드에 Autowired 적용
public void prepare(AlarmDevice alarmDevice, Viewer viewer) {
this.alarmDevice = alarmDevice;
this.viewer = viewer;
}
@Autowired(required = false) //required속성값을 false
@Qualifier("intrusionDetection")
public void setSensors(List<InfraredRaySensor> sensors) {
this.sensors = sensors;
for (InfraredRaySensor sensor : sensors) {
System.out.println("센서 등록: " + sensor);
}
}
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;
}
public void setRecorder(Recorder recorder) {
this.recorder = recorder;
}
@Resource(name = "displayStrategy")
public void setDisplayStrategy(DisplayStrategy displayStrategy) {
this.displayStrategy = displayStrategy;
}
@PostConstruct
public void init() {
viewer.add(camera1);
viewer.add(camera2);
viewer.add(camera3);
viewer.add(camera4);
}
@PreDestroy
public void close() {
}
public void checkSensorAndAlarm() {
for (InfraredRaySensor sensor : sensors) {
if (sensor.isObjectFounded()) {
alarmDevice.alarm(sensor.getName());
}
}
}
public void showCameraImage() {
viewer.draw();
}
}
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.annotation.Resource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
@Component("homeController")
public class HomeController {
private AlarmDevice alarmDevice;
private Viewer viewer;
@Resource(name = "camera1")
private Camera camera1;
@Resource(name = "camera2")
private Camera camera2;
@Resource(name = "camera3")
private Camera camera3;
private Camera camera4;
private List<InfraredRaySensor> sensors;
@Autowired
@Qualifier("main") //@Qualifier 어노테이션을 사용 - bean 객체의 수식어를 값으로 가짐
private Recorder recorder;
private DisplayStrategy displayStrategy;
@Autowired //메서드에 Autowired 적용
public void prepare(AlarmDevice alarmDevice, Viewer viewer) {
this.alarmDevice = alarmDevice;
this.viewer = viewer;
}
@Autowired(required = false) //required속성값을 false
@Qualifier("intrusionDetection")
public void setSensors(List<InfraredRaySensor> sensors) {
this.sensors = sensors;
for (InfraredRaySensor sensor : sensors) {
System.out.println("센서 등록: " + sensor);
}
}
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;
}
public void setRecorder(Recorder recorder) {
this.recorder = recorder;
}
@Resource(name = "displayStrategy")
public void setDisplayStrategy(DisplayStrategy displayStrategy) {
this.displayStrategy = displayStrategy;
}
@PostConstruct
public void init() {
viewer.add(camera1);
viewer.add(camera2);
viewer.add(camera3);
viewer.add(camera4);
}
@PreDestroy
public void close() {
}
public void checkSensorAndAlarm() {
for (InfraredRaySensor sensor : sensors) {
if (sensor.isObjectFounded()) {
alarmDevice.alarm(sensor.getName());
}
}
}
public void showCameraImage() {
viewer.draw();
}
}
required 속성값을 flase 로 지정할 경우 해당 타입의 빈 객체가 존재하지 않더라도 스프링은 예외를 발생하지 않는다.
@Autowired 어노테이션의 required 속성의 기본값은 true 이다.
여러개의 생성자에 @Autowired 어노테이션을 적용할 때에는
한 개의 생성자에 적용된 @Autowired 어노테이션만 required 속성값이 true 여야 하며
나머지 생성자에 적용되는 @Autowired 어노테이션의 required 속성값은 false 여야 한다.
2-2. @Qualifier 어노테이션을 이용한 자동설정 제한
@Autowired 어노테이션과 함께 사용되며 @Qualifier 어노테이션은 자동 연결될 빈 객체의 수식어를 값으로 갖는다.
위의 HomeController 소스를 보면 주석을 달아 놓았다
#HomeController.java
public class HomeController {
....
@Autowired
@Qualifier("main")
private Recorder recorder;
....
}
....
@Autowired
@Qualifier("main")
private Recorder recorder;
....
}
=> recorder 멤버필드에 Recorder 타입의 빈 객체를 자동 연결하는데, 수식어가 "main" 인 빈 객체를 연결한다는 것을 의미한다.
빈 객체의 수식어는 설정파일에서 <qualifier> 태그를 이용하여 설정 할 수 있다.
#ApplicationContext.xml
<bean id="recorder" class="madvirus.spring.chap04.homecontrol.Recorder">
<qualifier value="main" />
</bean>
<qualifier value="main" />
</bean>
<qualifier> 태그의 value 속성의 값을 @Qualifier 어노테이션의 값으로 사용 하게 된다.
3. @Resource 어노테이션을 사용한 프로퍼티 설정
: @ Resource 어노테이션은 자바 6 버전 및 JEE 5 버전에 추가된 어노테이션으로서
어플리케이션에서 필요로 하는 자원을 자동 연결할 때 사용 한다.
마찬가지로 HomeController.java 파일의 한 부분을 보면
#HomeController.java
public class HomeController {
.......
@Resource(name = "camera2")
private Camera camera2;
@Resource(name = "camera3")
private Camera camera3;
......
}
.......
@Resource(name = "camera2")
private Camera camera2;
@Resource(name = "camera3")
private Camera camera3;
......
}
name 속성에 자동으로 연결할 빈 객체의 이름을 입력하면 된다.
#방식 1 ApplicationContext.xml
<bean
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" />
#방식 2 ApplciationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<beans>
만약 @Resource 어노테이션에서 지정한 빈 객체가 존재하지 않으면,
스프링은 컨테이너를 초기화 하는 과정에서 NoSuchBeanDefinitionException 예외를 발생 시킨다.
스프링은 컨테이너를 초기화 하는 과정에서 NoSuchBeanDefinitionException 예외를 발생 시킨다.
4. @PostConstruct 어노테이션 & @PreDestory 어노테이션과 라이프 사이클
: 라이프 사이클의 초기화 및 제거 과정을 제공한다.
@PostConstruct : 의존하는 객체를 설정한 이후에 초기화 작업을 수행할 메서드에 적용
@PreDestory : 컨테이너에서 객체를 제거하기 전에 호출 될 메서드에 적용
스프링 설정 파일에서 init-method 속성과 destroy-method 솔석을 이용하여 명시한 메서드와 동일한 시점에 실행된다.
위와 마찬가지로 HomeController.java 파일을 보면
#HomeController.java
public class HomeController {
@PostConstruct
public void init() {
viewer.add(camera1);
viewer.add(camera2);
viewer.add(camera3);
viewer.add(camera4);
}
@PreDestroy
public void close() {
}
}
@PostConstruct
public void init() {
viewer.add(camera1);
viewer.add(camera2);
viewer.add(camera3);
viewer.add(camera4);
}
@PreDestroy
public void close() {
}
}
#방식1 ApplicationContext.xml
<bean
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor" />
#방식2 ApplicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:p="http://www.springframework.org/schema/p" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<beans>
xmlns:p="http://www.springframework.org/schema/p" 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/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:annotation-config />
<beans>
다시한번 요약 하자면,
<context:annotation-config /> 태그는 BeanPostProcessor 를 함께 등록해 주므로
- RequiredAnnotationBeanPostProcessor : @Required 어노테이션 처리
- AytowiredAnnotationBeanPostProcessor : @Autowired 어노테이션 처리
- CommonAnnotationBeanPostProcessor : @Resource, @PostConstruct, @PreDestroy 어노테이션 처리
- ConfigurationClassPostProcessor : @Configuration 어노테이션 처리
특별히 특정 기능을 사용하지 않아야 하는 경우가 아니라면
<context:annotation-config> 태그를 사용하는 것이 설정파일을 단순하게 만들어 준다.
- RequiredAnnotationBeanPostProcessor : @Required 어노테이션 처리
- AytowiredAnnotationBeanPostProcessor : @Autowired 어노테이션 처리
- CommonAnnotationBeanPostProcessor : @Resource, @PostConstruct, @PreDestroy 어노테이션 처리
- ConfigurationClassPostProcessor : @Configuration 어노테이션 처리
특별히 특정 기능을 사용하지 않아야 하는 경우가 아니라면
<context:annotation-config> 태그를 사용하는 것이 설정파일을 단순하게 만들어 준다.
'FrameWork > Spring 3.0' 카테고리의 다른 글
[Spring 3.0] CH06.MVC Hello World (0) | 2010.10.28 |
---|---|
[Spring 3.0] CH04-2.어노테이션 기반 빈 객체 스캔 (1) | 2010.10.27 |
[Spring 3.0] DI & AOP 개념 (0) | 2010.10.27 |
[Spring 3.0] CH01.스프링 프레임워크란? (1) | 2010.10.27 |
[Spring 3.0] 스프링 3.0 Library 를 다운 받아 보자! (0) | 2010.10.06 |