Spring 2.5 annotation
개발/Java2009. 10. 8. 10:22
Spring2.5 annotation 설정
없으면 에러 낼거야
이건 2.5이전부터 있던건데 그냥 한번 짚고 넘어 갑니다.
@Required 가 붙은 setter 메소드는 반드시 XML 설정에 의존성 삽입이 정의 되어 있어야 합니다.
(@Autowired도 안됩니다.)
XML 설정에 명시적인 의존성 삽입이 없다면 런타임 예외가 던져 집니다.
이 애노테이션을 처리하기 위한 후처리기는 다음과 같습니다.
자동으로 묶어 줄게
@Autowried 는 타입에 일치하는 bean을 의존성 삽입 해줍니다.
필드에 사용 할 경우 setter가 존재하지 않아도 됩니다.
여러개의 인자를 가진 메소드에 사용 할 수 있습니다.
@Autowired의 속성인 required의 기본값이 true이기 때문에 발견되는 bean이 없다면 예외가 던져 집니다.
발견 되는 bean이 없더라도 예외가 던져지지 않기를 원하면 required 속성을 fasle로 설정하면 됩니다.
일치하는 타입을 찾기 때문에 발견되는 bean이 여러개인 경우 예외가 던져 집니다.
이를 방지 하기 위해 <bean /> 요소의 추가된 속성인 primary를 설정 합니다.
발견되는 bean이 여러개 일지라도 primary가 설정된 bean이 참조 됩니다.
이 애노테이션을 처리하기 위한 후처리기는 다음과 같습니다.
정확한 이름을 알려줄게
@Autowired을 사용 할 때 타입으로 bean을 찾기 때문에 여러개의 bean이 발견되면 primary로 해결 했습니다. 하지만 @Qualifier를 이용해 찾으려는 bean의 id를 넘길 수 있습니다.
필드에만 사용 가능 하기 때문에 메소드에 적용시 다음과 같이 설정 합니다.
이 애노테이션을 처리하기 위한 후처리기는 @Autowried의 후처리기와 동일 합니다.
JSR-250 애노테이션 지원
-@Resource
-@PostConstruct
-@PreDestroy
위 세가지 애노테이션을 사용하기 위해서는 후처리기를 등록 해야 합니다.
@Resource
JNDI의 리소스 및 Spring 컨테이너의 bean을 찾아 autowring 합니다.
name 속성을 생략 할 경우 해당 필드명으로 찾고 해당 bean이 발견되지 않는다면 타입으로 찾습니다.
필드에 사용 할 경우 setter가 존재하지 않아도 됩니다.
한개의 인자를 가진 setter 메소드만 적용 할 수 있습니다.
타입으로 찾지 않길 원한다면 다음과 같은 설정을 합니다.
JNDI 리소스만 참조 하려면 다음과 같은 설정을 합니다.
@PostConstruct 와 @PreDestroy
기존에는 생명 주기를 다루는 방법이 2가지가 있었습니다.
1.InitializingBean, DisposableBean을 구현하는 방법
2.XML 설정파일에서 <bean /> 요소의 init-method, destroy-method 속성 설정
2.5에서 추가된 두 애노테이션은 기존의 방식과 동일한 결과를 가져 옵니다.
만약 3가지 방식 모두 사용할 경우
우선순위는 애노테이션->XML설정->인터페이스 구현 입니다.
이거 하나면 OK
위에서 나온 애노테이션을 사용하기 위해서는 3가지의 BeanPostProcessor를 등록해야 했습니다.
하지만 이거 하나면 3개가 모두 등록 됩니다.
알아서 찾아줄게
위에서 나온 애노테이션으로 XML설정을 줄이더라도 bean 선언은 반드시 해야 했습니다.
하지만 component-scan 을 이용하면 bean선언 조차 생략 할 수 있습니다.
component-scan의 대상이 되기 위해서는 스테레오타입 애노테이션을 사용해야 합니다.
4개의 스테레오타입 애노테이션
@Component
- 스테레오타입 애노테이션의 조상 입니다.
@Controller
-Spring MVC에서 컨트롤러로 인식 합니다.
@Service
-역할부여 없이 스캔 대상이 되는데 비즈니스 클래스에 사용하면 될 것 같습니다.
@Repository
-DAO에 사용되며 DB Exception을 DataAccessException으로 변환해 줍니다.
간단한 예제 입니다.
테스트에 사용될 2개의 클래스
지정된 패키지의 하위패키지까지 재귀적으로 스테레오타입이 있는 클래스를 찾습니다.
필터를 이용해 제외 검색 대상에서 제외 시킬 수 있으며
<context:annotation-config /> 까지 자동으로 등록됩니다.
테스트는 통과 합니다.
@Scope를 함께 사용 하여 Scope를 설정 할 수 있습니다.
역시 scope문제가 발생 합니다.
이 문제를 해결하기 위해 <context:component-scan /> 요소의 scoped-proxy 속성이 존재 합니다.
scoped-proxy 속성은 <aop:scoped-poxy/> 요소처럼 WebApplicationContext 에서만 유효하며
"session", "globalSession", "request" 이외의 scope는 무시 됩니다.
아래 3가지 값을 지정 할 수 있습니다.
no - 디폴트값, proxy를 생성하지 않습니다.
interfaces - JDK Dynamic Proxy를 이용한 Proxy 생성
targetClass - CGLIB를 이용한 Proxy 생성
Bar는 인터페이스 기반이 아니기 때문에 CGLIB를 이용 했습니다.
만약 스캔된 bean들 중 @Scope의 값이 "session", "request" 일 때
scoped-proxy 속성 값이 "targetClass", "interfaces" 가 아닐경우 예외가 던져지고 초기화에 실패 합니다.
component-scan을 이용하면 method-lookup도 불가능 하므로 참조되는 bean이 web-scope가 아니고
prototype일 경우의 문제는 해결 할수 없을것 같습니다.
출처 : http://blog.daum.net/calmknight/15785980
없으면 에러 낼거야
이건 2.5이전부터 있던건데 그냥 한번 짚고 넘어 갑니다.
@Required 가 붙은 setter 메소드는 반드시 XML 설정에 의존성 삽입이 정의 되어 있어야 합니다.
(@Autowired도 안됩니다.)
XML 설정에 명시적인 의존성 삽입이 없다면 런타임 예외가 던져 집니다.
이 애노테이션을 처리하기 위한 후처리기는 다음과 같습니다.
<bean class="org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor"/>
자동으로 묶어 줄게
@Autowried 는 타입에 일치하는 bean을 의존성 삽입 해줍니다.
필드에 사용 할 경우 setter가 존재하지 않아도 됩니다.
@Autowried
private Foo foo;
private Foo foo;
여러개의 인자를 가진 메소드에 사용 할 수 있습니다.
@Autowried
public void setUp(Foo foo, Bar bar) {
this.foo = foo;
this.bar = bar;
}
public void setUp(Foo foo, Bar bar) {
this.foo = foo;
this.bar = bar;
}
@Autowired의 속성인 required의 기본값이 true이기 때문에 발견되는 bean이 없다면 예외가 던져 집니다.
발견 되는 bean이 없더라도 예외가 던져지지 않기를 원하면 required 속성을 fasle로 설정하면 됩니다.
@Autowried(required=false)
private Foo foo;
private Foo foo;
일치하는 타입을 찾기 때문에 발견되는 bean이 여러개인 경우 예외가 던져 집니다.
이를 방지 하기 위해 <bean /> 요소의 추가된 속성인 primary를 설정 합니다.
발견되는 bean이 여러개 일지라도 primary가 설정된 bean이 참조 됩니다.
<bean id="foo" class="example.Foo" primary="true" />
<bean id="foo2" class="example.Foo"/>
<bean id="foo2" class="example.Foo"/>
이 애노테이션을 처리하기 위한 후처리기는 다음과 같습니다.
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
정확한 이름을 알려줄게
@Autowired을 사용 할 때 타입으로 bean을 찾기 때문에 여러개의 bean이 발견되면 primary로 해결 했습니다. 하지만 @Qualifier를 이용해 찾으려는 bean의 id를 넘길 수 있습니다.
@Autowried
@Qualifier("foo")
private Foo foo;
@Qualifier("foo")
private Foo foo;
필드에만 사용 가능 하기 때문에 메소드에 적용시 다음과 같이 설정 합니다.
@Autowried
public void setUp(@Qualifier("foo") Foo foo, @Qualifier("foo2") Foo foo2) {
this.foo = foo;
this.foo2 = foo2;
}
public void setUp(@Qualifier("foo") Foo foo, @Qualifier("foo2") Foo foo2) {
this.foo = foo;
this.foo2 = foo2;
}
이 애노테이션을 처리하기 위한 후처리기는 @Autowried의 후처리기와 동일 합니다.
JSR-250 애노테이션 지원
-@Resource
-@PostConstruct
-@PreDestroy
위 세가지 애노테이션을 사용하기 위해서는 후처리기를 등록 해야 합니다.
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
@Resource
JNDI의 리소스 및 Spring 컨테이너의 bean을 찾아 autowring 합니다.
name 속성을 생략 할 경우 해당 필드명으로 찾고 해당 bean이 발견되지 않는다면 타입으로 찾습니다.
필드에 사용 할 경우 setter가 존재하지 않아도 됩니다.
@Resource(name="dataSource")
private DataSource dataSource;
private DataSource dataSource;
한개의 인자를 가진 setter 메소드만 적용 할 수 있습니다.
@Resource(name="dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
타입으로 찾지 않길 원한다면 다음과 같은 설정을 합니다.
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="fallbackToDefaultTypeMatch" value="false"></property>
</bean>
<property name="fallbackToDefaultTypeMatch" value="false"></property>
</bean>
JNDI 리소스만 참조 하려면 다음과 같은 설정을 합니다.
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true"/>
</bean>
<property name="alwaysUseJndiLookup" value="true"/>
</bean>
@PostConstruct 와 @PreDestroy
기존에는 생명 주기를 다루는 방법이 2가지가 있었습니다.
1.InitializingBean, DisposableBean을 구현하는 방법
2.XML 설정파일에서 <bean /> 요소의 init-method, destroy-method 속성 설정
2.5에서 추가된 두 애노테이션은 기존의 방식과 동일한 결과를 가져 옵니다.
@PostConstruct
public void init() {
...
}
@PreDestroy
public void preDestroy() {
...
}
public void init() {
...
}
@PreDestroy
public void preDestroy() {
...
}
만약 3가지 방식 모두 사용할 경우
우선순위는 애노테이션->XML설정->인터페이스 구현 입니다.
이거 하나면 OK
위에서 나온 애노테이션을 사용하기 위해서는 3가지의 BeanPostProcessor를 등록해야 했습니다.
하지만 이거 하나면 3개가 모두 등록 됩니다.
<context:annotation-config />
알아서 찾아줄게
위에서 나온 애노테이션으로 XML설정을 줄이더라도 bean 선언은 반드시 해야 했습니다.
하지만 component-scan 을 이용하면 bean선언 조차 생략 할 수 있습니다.
component-scan의 대상이 되기 위해서는 스테레오타입 애노테이션을 사용해야 합니다.
4개의 스테레오타입 애노테이션
@Component
- 스테레오타입 애노테이션의 조상 입니다.
@Controller
-Spring MVC에서 컨트롤러로 인식 합니다.
@Service
-역할부여 없이 스캔 대상이 되는데 비즈니스 클래스에 사용하면 될 것 같습니다.
@Repository
-DAO에 사용되며 DB Exception을 DataAccessException으로 변환해 줍니다.
간단한 예제 입니다.
테스트에 사용될 2개의 클래스
@Component("bar")
public class Bar {
}
@Component("foo")
public class Foo {
@Autowired
private Bar bar;
public Bar getBar() {
return bar;
}
}
public class Bar {
}
@Component("foo")
public class Foo {
@Autowired
private Bar bar;
public Bar getBar() {
return bar;
}
}
지정된 패키지의 하위패키지까지 재귀적으로 스테레오타입이 있는 클래스를 찾습니다.
필터를 이용해 제외 검색 대상에서 제외 시킬 수 있으며
<context:annotation-config /> 까지 자동으로 등록됩니다.
<context:component-scan base-package="example" />
테스트는 통과 합니다.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"Beans.xml"})
public class ScanTest {
@Autowired
private Foo foo;
@Test
public void fooTest() {
assertNotNull(foo.getBar());
}
}
@ContextConfiguration(locations={"Beans.xml"})
public class ScanTest {
@Autowired
private Foo foo;
@Test
public void fooTest() {
assertNotNull(foo.getBar());
}
}
@Scope를 함께 사용 하여 Scope를 설정 할 수 있습니다.
@Scope("request")
@Component("bar")
public class Bar {
}
singleton인 foo에서 request scope인 bar를 사용 하면 어떻게 될 까요?@Component("bar")
public class Bar {
}
역시 scope문제가 발생 합니다.
이 문제를 해결하기 위해 <context:component-scan /> 요소의 scoped-proxy 속성이 존재 합니다.
scoped-proxy 속성은 <aop:scoped-poxy/> 요소처럼 WebApplicationContext 에서만 유효하며
"session", "globalSession", "request" 이외의 scope는 무시 됩니다.
아래 3가지 값을 지정 할 수 있습니다.
no - 디폴트값, proxy를 생성하지 않습니다.
interfaces - JDK Dynamic Proxy를 이용한 Proxy 생성
targetClass - CGLIB를 이용한 Proxy 생성
Bar는 인터페이스 기반이 아니기 때문에 CGLIB를 이용 했습니다.
<context:component-scan base-package="example" scoped-proxy="targetClass"/>
만약 스캔된 bean들 중 @Scope의 값이 "session", "request" 일 때
scoped-proxy 속성 값이 "targetClass", "interfaces" 가 아닐경우 예외가 던져지고 초기화에 실패 합니다.
component-scan을 이용하면 method-lookup도 불가능 하므로 참조되는 bean이 web-scope가 아니고
prototype일 경우의 문제는 해결 할수 없을것 같습니다.
출처 : http://blog.daum.net/calmknight/15785980
'개발 > Java' 카테고리의 다른 글
ckeditor 이미지 업로드시 반환 리턴값 보내기 (0) | 2009.10.26 |
---|---|
ibatis 로그 남기기 (0) | 2009.10.08 |
[java] String 배열을 List에 넣기 (0) | 2009.01.19 |
Cookie를 효율적으로 관리하고 사용하자 (0) | 2008.04.15 |
[jsp browser] jsp파일 소스 보는 프로그램 (1) | 2008.03.10 |