'annotation'에 해당되는 글 6건

  1. 2020.05.06 [Java] Model 객체에서 boolean 변수 사용 시 @Setter, @Geeter 주의 사항.
  2. 2019.09.09 [Spring] Could not find method annotationProcessor()..
  3. 2017.07.11 [Spring] Spring @Autowired Annotation
  4. 2012.03.15 Spring Annotation (java.lang.annotation) 관련 내용 모음.
  5. 2012.02.21 Spring Annotation 참고 글.
  6. 2009.05.12 [펌] Java Annotation

[Java] Model 객체에서 boolean 변수 사용 시 @Setter, @Geeter 주의 사항.

ITWeb/개발일반 2020. 5. 6. 16:58

이건 주의 사항이라기 보다 신경쓰지 않는 것이 더 문제 같습니다.

ㅡ.ㅡ;

 

웹 페이지에서 form post 로 데이터를 넘길 때 삽질을 해서 기록 합니다.

 

- 기본적으로 boolean 변수에 대해서는 is+변수명() 으로 method 를 만들어 줍니다.
- 웹에서 넘기는 변수명에 is 가 붙어 있을 경우 이를 제거 하고 변수명을 만드셔야 합니다.
- 잘못된 예)
  isCreateThing
- 올바른 예)
  bCreateThing or createThing

- 이런 오류를 처음 부터 경험 하고 싶지 않다면, 전통적으로 setter, getter 를 다 만들어서 사용 하시면 됩니다.

제가 변수명을 isCreateThingType 이렇게 작성 했다가 시간 낭비를 많이 했습니다.
(그러고 보니 아주 예전에도 같은 경험을 했던 것 같네요. 역시 몸이 기억 해야 합니다.)

 

:

[Spring] Could not find method annotationProcessor()..

ITWeb/개발일반 2019. 9. 9. 18:23

Intellij 에서 lombok 설정 관련 오류가 난 케이스 입니다.

 

Could not find method annotationProcessor() 이 에러는 gradle 버전 4.6 이상을 사용 하시면 발생 하지 않게 됩니다.

저는 4.4 버전으로 기본 구성을 예전에 해 놓다 보니 이번에 오류가 발생을 했었내요. 

그래서 기록해 둡니다.

 

그 이외는 intellij 설정에서 enable annotation processing 설정을 해주시면 됩니다.

:

[Spring] Spring @Autowired Annotation

ITWeb/개발일반 2017. 7. 11. 10:56

참고문서)

https://www.tutorialspoint.com/spring/spring_autowired_annotation.htm


@Autowired 를 사용하는 방법에 대해서 기술 되어 있습니다.


1. @Autowired on Setter Methods

2. @Autowired on Properties

3. @Autowired on Constructors


3가지 방법 모두 같은 내용이기 때문에 사용하기 제일 편하신 걸로 사용하시면 되겠습니다.

저는 습관적으로 그냥 2번으로 사용하는 것 같습니다.


누구라도 이해하기 쉬운 예를 들자면.


public class HelloWorldModel {

...

}


-----------------------------------------------

// HelloWorldModel 이라는 클래스가 있다고 가정하고.


public class HelloWorldApp {

  private HelloWorldModel helloWorldModel;


  public HelloWorldApp() {

    this.helloWorldModel = new HelloWorldModel();

  }

...

}


// 위와 같이 선언한 부분이 아래와 같이 변경이 됩니다.


public class HelloWorldApp {

  @Autowired

  private HelloWorldModel helloWorldModel;

...

}


그냥 아는 것과 설명을 해줘야 할 때는 눈 높이를 맞춰야 하기 때문에 참 어렵내요.

:

Spring Annotation (java.lang.annotation) 관련 내용 모음.

ITWeb/개발일반 2012. 3. 15. 10:49
[참고문서]

Package org.springframework.beans.factory.annotation

Support package for annotation-driven bean configuration. 
Annotation Types Summary
Autowired Marks a constructor, field, setter method or config method as to be autowired by Spring's dependency injection facilities.
Configurable Marks a class as being eligible for Spring-driven configuration.
Qualifier This annotation may be used on a field or parameter as a qualifier for candidate beans when autowiring.
Required Marks a method (typically a JavaBean setter method) as being 'required': that is, the setter method must be configured to be dependency-injected with a value.
Value Annotation at the field or method/constructor parameter level that indicates a default value expression for the affected argument.

Package org.springframework.context.annotation

Annotation support for the Application Context, including JSR-250 "common" annotations, component-scanning, and Java-based metadata for creating Spring-managed objects 
Annotation Types Summary
Bean Indicates that a method produces a bean to be managed by the Spring container.
ComponentScan Configures component scanning directives for use with @Configuration classes.
ComponentScan.Filter Declares the type filter to be used as an include filter or exclude filter.
Configuration Indicates that a class declares one or more @Bean methods and may be processed by the Spring container to generate bean definitions and service requests for those beans at runtime, for example:
 @Configuration
 public class AppConfig {
     @Bean
     public MyBean myBean() {
         // instantiate, configure and return bean ...
DependsOn Beans on which the current bean depends.
EnableAspectJAutoProxy Enables support for handling components marked with AspectJ's @Aspect annotation, similar to functionality found in Spring's <aop:aspectj-autoproxy> XML element.
EnableLoadTimeWeaving Activates a Spring LoadTimeWeaver for this application context, available as a bean with the name "loadTimeWeaver", similar to the <context:load-time-weaver> element in Spring XML.
Import Indicates one or more @Configuration classes to import.
ImportResource Indicates one or more resources containing bean definitions to import.
Lazy Indicates whether a bean is to be lazily initialized.
Primary Indicates that a bean should be given preference when multiple candidates are qualified to autowire a single-valued dependency.
Profile Indicates that a component is eligible for registration when one or more specified profiles are active.
PropertySource Annotation providing a convenient and declarative mechanism for adding a PropertySource to Spring's Environment.
Role Indicates the 'role' hint for a given bean.
Scope When used as a type-level annotation in conjunction with the Component annotation, indicates the name of a scope to use for instances of the annotated type.

Package org.springframework.core.annotation

Core support package for Java 5 annotations 
Annotation Types Summary
Order Annotation that defines ordering.

Package org.springframework.format.annotation

Annotations for declaratively configuring field formatting rules 
Annotation Types Summary
DateTimeFormat Declares that a field should be formatted as a date time.
NumberFormat Declares that a field should be formatted as a number.

Package org.springframework.jmx.export.annotation

JDK 1.5+ annotations for MBean exposure 
Annotation Types Summary
ManagedAttribute JDK 1.5+ method-level annotation that indicates to expose a given bean property as JMX attribute, corresponding to the ManagedAttribute attribute.
ManagedMetric JDK 1.5+ method-level annotation that indicates to expose a given bean property as JMX attribute, with added Descriptor properties to indicate that it is a metric.
ManagedNotification JDK 1.5+ method-level annotation that indicates a JMX notification emitted by a bean.
ManagedNotifications JDK 1.5+ method-level annotation that indicates JMX notifications emitted by a bean, containing multiple ManagedNotifications
ManagedOperation JDK 1.5+ method-level annotation that indicates to expose a given method as JMX operation, corresponding to the ManagedOperation attribute.
ManagedOperationParameter JDK 1.5+ method-level annotation used to provide metadata about operation parameters, corresponding to a ManagedOperationParameter attribute.
ManagedOperationParameters JDK 1.5+ method-level annotation used to provide metadata about operation parameters, corresponding to an array of ManagedOperationParameter attributes.
ManagedResource JDK 1.5+ class-level annotation that indicates to register instances of a class with a JMX server, corresponding to the ManagedResource attribute.

Package org.springframework.scheduling.annotation

JDK 1.5+ annotation for asynchronous method execution 
Class Summary
AbstractAsyncConfiguration Abstract base Configuration class providing common structure for enabling Spring's asynchronous method execution capability.
AsyncAnnotationAdvisor Advisor that activates asynchronous method execution through the Async annotation.
AsyncAnnotationBeanPostProcessor Bean post-processor that automatically applies asynchronous invocation behavior to any bean that carries the Async annotation at class or method-level by adding a corresponding AsyncAnnotationAdvisor to the exposed proxy (either an existing AOP proxy or a newly generated proxy that implements all of the target's interfaces).
AsyncConfigurationSelector Selects which implementation of AbstractAsyncConfiguration should be used based on the value of EnableAsync.mode() on the importing @Configuration class.
AsyncResult<V> A pass-through Future handle that can be used for method signatures which are declared with a Future return type for asynchronous execution.
ProxyAsyncConfiguration @Configuration class that registers the Spring infrastructure beans necessary to enable proxy-based asynchronous method execution.
ScheduledAnnotationBeanPostProcessor Bean post-processor that registers methods annotated with @Scheduled to be invoked by a TaskScheduler according to the "fixedRate", "fixedDelay", or "cron" expression provided via the annotation.
SchedulingConfiguration @Configuration class that registers a ScheduledAnnotationBeanPostProcessor bean capable of processing Spring's @Scheduled annotation.

Package org.springframework.test.annotation

Support classes for annotation-driven tests 
Annotation Types Summary
DirtiesContext Test annotation which indicates that the ApplicationContext associated with a test is dirty and should be closed: after the current test, when declared at the method level after each test method in the current test class, when declared at the class level with class mode set to AFTER_EACH_TEST_METHOD after the current test class, when declared at the class level with class mode set to AFTER_CLASS
ExpectedException Deprecated. as of Spring 3.1 in favor of using built-in support for declaring expected exceptions in the underlying testing framework (e.g., JUnit, TestNG, etc.)
IfProfileValue Test annotation to indicate that a test is enabled for a specific testing profile or environment.
NotTransactional Deprecated. as of Spring 3.0, in favor of moving the non-transactional test method to a separate (non-transactional) test class or to a @BeforeTransaction or @AfterTransaction method.
ProfileValueSourceConfiguration ProfileValueSourceConfiguration is a class-level annotation which is used to specify what type of ProfileValueSource to use when retrieving profile values configured via the @IfProfileValue annotation.
Repeat Test annotation to indicate that a test method should be invoked repeatedly.
Rollback Test annotation to indicate whether or not the transaction for the annotated test method should be rolled back after the test method has completed.
Timed Test-specific annotation to indicate that a test method has to finish execution in a specified time period.

Package org.springframework.transaction.annotation

JDK 1.5+ annotation for transaction demarcation 
Annotation Types Summary
EnableTransactionManagement Enables Spring's annotation-driven transaction management capability, similar to the support found in Spring's <tx:*> XML namespace.
Transactional Describes transaction attributes on a method or class.

Package org.springframework.validation.annotation

Support classes for annotation-based constraint evaluation, e.g 
Annotation Types Summary
Validated Variant of JSR-303's Valid, supporting the specification of validation groups.

Package org.springframework.web.bind.annotation

Annotations for binding requests to controllers and handler methods as well as for binding request parameters to method arguments 
Annotation Types Summary
CookieValue Annotation which indicates that a method parameter should be bound to an HTTP cookie.
ExceptionHandler Annotation for handling exceptions in specific handler classes and/or handler methods.
InitBinder Annotation that identifies methods which initialize the WebDataBinder which will be used for populating command and form object arguments of annotated handler methods.
Mapping Meta annotation that indicates a web mapping annotation.
ModelAttribute Annotation that binds a method parameter or method return value to a named model attribute, exposed to a web view.
PathVariable Annotation which indicates that a method parameter should be bound to a URI template variable.
RequestBody Annotation indicating a method parameter should be bound to the body of the web request.
RequestHeader Annotation which indicates that a method parameter should be bound to a web request header.
RequestMapping Annotation for mapping web requests onto specific handler classes and/or handler methods.
RequestParam Annotation which indicates that a method parameter should be bound to a web request parameter.
RequestPart Annotation that can be used to associate the part of a "multipart/form-data" request with a method argument.
ResponseBody Annotation which indicates that a method return value should be bound to the web response body.
ResponseStatus Marks a method or exception class with the status code and reason that should be returned.
SessionAttributes Annotation that indicates the session attributes that a specific handler uses.

Package org.springframework.web.portlet.bind.annotation

Annotations for binding portlet requests to handler methods 
Annotation Types Summary
ActionMapping Annotation for mapping Portlet action requests onto handler methods.
EventMapping Annotation for mapping Portlet event requests onto handler methods.
RenderMapping Annotation for mapping Portlet render requests onto handler methods.
ResourceMapping Annotation for mapping Portlet resource requests onto handler methods.

Package org.springframework.web.servlet.config.annotation

Annotation-based setup for Spring MVC 
Annotation Types Summary
EnableWebMvc Add this annotation to an @Configuration class to have the Spring MVC configuration defined in WebMvcConfigurationSupport imported:
 @Configuration
 @EnableWebMvc
 @ComponentScan(basePackageClasses = { MyConfiguration.class })
 public class MyWebConfiguration {

 }

Package org.springframework.stereotype

Annotations denoting the roles of types or methods in the overall architecture (at a conceptual, rather than implementation, level) 
Annotation Types Summary
Component Indicates that an annotated class is a "component".
Controller Indicates that an annotated class is a "Controller" (e.g.
Repository Indicates that an annotated class is a "Repository", originally defined by Domain-Driven Design (Evans, 2003) as "a mechanism for encapsulating storage, retrieval, and search behavior which emulates a collection of objects".
Service Indicates that an annotated class is a "Service", originally defined by Domain-Driven Design (Evans, 2003) as "an operation offered as an interface that stands alone in the model, with no encapsulated state."


Package java.lang.annotation

Provides library support for the Java programming language annotation facility.
Annotation Types Summary
Documented Indicates that annotations with a type are to be documented by javadoc and similar tools by default.
Inherited Indicates that an annotation type is automatically inherited.
Retention Indicates how long annotations with the annotated type are to be retained.
Target Indicates the kinds of program element to which an annotation type is applicable.
 
:

Spring Annotation 참고 글.

ITWeb/개발일반 2012. 2. 21. 10:44
내가 이해 하고 있는게 맞는지 확인하기 위해서 관련 글들을 찾아 보던 중..
쉽게 정리된 글이 있어 올려 봅니다.

기초가 중요 하다는건.. 언제봐도 진리 인듯 합니다. ^^;



스프링 2.5가 드디어 릴리즈 되었네요.
좀 천천히 관심 둘 여유있을 줄 알았는데... 플젝 투입되어 있어서 정신이 없습니다.

19일, 인포큐에 스프링 2.5의 새로운  부분에 대한 글이 올라왔었습니다.
 
http://www.infoq.com/articles/spring-2.5-part-1

그냥 이런게 올라왔었구나... 나중에 읽어야지.. 하고 미뤄두었었는데 릴리즈도 된 마당에 대충이라도 읽어봤습니다.

2.0에서 XML 스키마 지원으로 스프링을 즐겁게 쓰도록 만들어 주었었는데... 이번에는 더욱 단순하고 강력한 스프링이 되었다고 하네요. 2.0은 2.5로 가기 위한 맛보기...ㅎㅎ

개인적으로 어노테이션을 통한 설정이 생각 만큼 생산성을 높여줄지에 대해서는 의문이지만 XML를 끔찍하게 여기는 사람들이 많기 때문에 매우 환영할만 하다고 생각합니다.

이왕 글을 쓴거 위 글의 내용을 약간 요약해보겠습니다. infoq에 기고된 글의 저작권이 어찌되는지 모르지만 요약 정도는 상관 없겠죠?

이 글은 총 3회에 나눠서 쓰여질 기고문의 첫번째에 해당합니다. 주로 어노테이션과 관련된 부분에 대해서 설명하고있구요.두번째 글은 Web Tier 쪽을, 마지막 글은 통합과 테스팅에 관련된 기술을 논하려고 한답니다. 아마도 두번째는SpringMVC를 마지막은 JUnit 4 지원과 OSGi가 될 듯 하네요.

JSR-250 어노테이션 지원

스프링 2.5에 새로 지원하는 어노테이션은 다음과 같다고 합니다.
  • @Resource
  • @PostConstruct
  • @PreDestroy
@Resource

DI를 위해서 사용합니다. 
빈 컨테이너 안의 빈들 중에서 지정된 이름의 빈을 찾아서 DI를 해줍니다. 아래 예에서라면 스프링은 관라하는 빈들 중 이름이 dataSource인 놈을 가지고 setDataSource()를 호출하는거죠.
@Resource(name="dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
직접 맴버 변수에 지정할 수도 있는데 이렇게 하면 setter 없이도 DI가 된다네요. 요거 맘에 듭니다. 

@Resource
private DataSource dataSource; // inject the bean named 'dataSource' 

위의 예에서 처럼 이름을 지정하지 않으면 변수 이름이 자동으로 사용되네요. 아래처럼 setter 메소드에 이름 없이 지정 할 수도 있다고 합니다.
private DataSource dataSource;
@Resource
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
이름으로 빈을 찾았는데 없으면 타입으로 찾아서 인젝션 해준답니다. 원하지 않으면 이 기능을 끌 수도 있습니다.

Lifecycle 어노테이션 @PostConstruct와 @PreDestory

기존에 빈 생성시 빈을 초기화하고 소멸시 정리하는 작업을 하려면 InitializingBean과 DesposableBean 인터페이스를 상속하거나 빈설정시 명시적으로 초기화 메소드와 정리 메소드를 지정해 주었어야 합니다.
인터페이스를 사용하면 자동화 되어 좋기는 하지만 스프링 디펜던시가 생기고 - 솔직히 이 빈을 다른 곳에서 쓸 일이 얼마나 있겠냐만 늘 결벽증 때문에 사용안하게 된다죠 - 그래서 설정을 주로 사용하곤 했습니다.

사용은 간단합니다. 초기화 메소드와 정리 메소드 위에 각 어노테이션을 표기만 하면 되는거죠.

public class FilePoller {

@PostConstruct
public void startPolling() {
...
}
...

@PreDestroy
public void stopPolling() {
...
}
...

늘 XML 설정 할 때 마다 빼먹을까봐 신경 썼었는데 좋네요.

정밀한 오토와이어링

2.5 이전에도 여러가지 오토와이어링 방법을 제공했습니다. 컨스트럭터, 셋터의 타입, 셋터의 이름, 자동인식.... 하지만 전체적으로어떤 것을 선택할지 설정 할 수는 있어도 어떤 경우에는 타입으로 찾고 어떤 경우에는 이름으로 찾을지 정밀하게 제어 할 수는 없었습니다.

위에서 말한 것 처럼 2.5에서는 @Resource 어노테이션으로 메소드별 필드별로 이름 기반의오토와이어링을 지정 할 수 있게 되었습니다. 하지만 이건 제약이 있어 스프링 2.5에서는 @Autowired 어노테이션을추가했다고 합니다. 이건 비표준인거죠. 스프링 디펜던시가 생깁니다.

@Autowired 어노테이션은 컨스트럭터, 메소드, 필드에 사용하며 타입으로 오토와이어링 하도록 지정하는 기능을 가지고 있습니다. 그런데 메소드가 꼭 셋터일 필요는 없습니다. 심시어 패러미터가 여러개인 경우도 상관 없답니다. 오호...
@Autowired
public void setup(DataSource dataSource, AnotherObject o) { ... }

기본적으로 이 어노테이션으로 표시된 항목은 필수인 것으로 처리되지만 required 옵션을 false로 하면 빈을 못 찾아도 그냥 넘어갑니다. 예를 들어 다음에서 빈을 못찾으면 그냥 하드코딩한 DefaultStrategy가 사용되는거죠.

@Autowired(required=false)
private SomeStrategy strategy = new DefaultStrategy(); 

이렇게 타입으로 빈을 찾는데 해당 타입의 빈이 하나 이상일 경우 스프링은 오토와이어링이 실패한 것으로 처리합니다. 이 문제를 해결하기 위한 몇가지 방법이 있습니다. 우선 빈 설정에서 primary 속성을 사용하는 방법이 있다.

<bean id="dataSource" primary="true" ... /> 

이번 2.5에는 보다 정밀한 제어가 가능한데 @Qualifier 어노테이션을 사용하면 빈 이름을 지정할 수 있다. 타입이 아닌 이름으로 찾게 됩니다.

@Autowired
@Qualifier("primaryDataSource")
private DataSource dataSource; 

이 어노테이션을 별도로 만든 이유는 다음 처럼 사용할 수 있게 하려는 것이라네요. 머리도 좋아요. 이 어노테이션은 컨스트럭터 매개변수, 필드, 메소드 매개변수 어디에도 쓸 수 있답니다.

@Autowired
public void setup(@Qualifier("primaryDataSource") DataSource dataSource, AnotherObject o) { ... } 

이 뿐 아니라 커스텀 어노테이션을 사용한 인젝션에도 사용될 수 있다는데요. 요건 읽기 귀찮아서 일단 PASS...

스프링 컴포넌트 자동 인식

스프링 2.0부터 스테레오 타입 개념의 어노테이션이 도입되었습니다. @Repository는 데이타 억세스 코드라는 표시를 하는 어노테이션으로 사용된 것이죠.
2.5에는 일반적인 3-Tier 아키택쳐에서의 역활을 표기하기 위해 @Service와 @Controller라는 어노테이션을 추가했습니다. 이와 함께 제너릭 어노테이션인 @Component도 추가...

이들 어노테이션들은 객체에 역할을 부여해서 AOP나 후처리기가 뭔가 추가적인 작업을 하도록 해줍니다.

이 어노테이션들로 사용할 수 있는 새 기능 중 하나가 컴포넌트 자동 인식 기능... 오토와이어링을 쓰더라도 기본적인 빈 설정을 해주었어야 했지만 이 컴포넌트 자동 탐색 기능을 쓰면 이 기본적인 빈 설정 조차 필요없게 됩니다.

2.5의 PetClinic 샘플을 보면 하부구조에 해당하는 컴포넌트들은 XML에 설정이 되어 있지만 Web Tier 컨트롤러들은 자동 인식 기능을 사용하도록 되어 있다는군요. 저도 처음 이 기능을 들었을 때에 Web Tier에 적용하면 좋겠다고 생각되더군요. XML의 명시적이고 중앙집중적인 특징도 무시는 못하죠. 개발할 때에는 편의상 오토와이어링을 쓰더라도 운영환경에서는 XML이 역시... 혹시 새로 생긴 자동 탐색 기능과 오토와이어링 기능으로 구성된 빈 컨테이너의 내용을 XML로 생성해주는 방법이 있다면 좀 알려주세요.

<context:component-scan base-package="org.springframework.samples.petclinic.web"/> 

이렇게 지정된 패키지 안의 클래스들을 탐색해서 스테레오타입이 지정된 클래스들을 찾아냅니다. 예를 들면 이런 Spring MVC 컨트롤러...

@Controller

public class ClinicController {

private final Clinic clinic;

@Autowired
public ClinicController(Clinic clinic) {
this.clinic = clinic;
}
... 

탐색 규칙을 커스터마이제이션 할 수도 있습니다. 다음과 같이 하면 스테레오 타입을 찾는 기본 룰은 사용하지 않고 Stub로 시작하는 클래스들과 Mock 어노테이션이 되어 있는 클래스들을 스프링 객체로 인식하게 할 수 있습니다.

<context:component-scan base-package="example" use-default-filters="false">
<context:include-filter type="aspectj" expression="example..Stub*"/>
<context:include-filter type="annotation" expression="example.Mock"/>
</context:component-scan> 

기본 탐색 규칙을 조정 할 수도 있습니다. 아래 예는 탐색시 @Repository 어노테이션을 제외시킵니다.

<context:component-scan base-package="example">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan> 

 물론 커스텀 어노테이션을 탐색에 사용하게 할 수도 있습니다. @Generic 제넥릭 어노테이션으로 다음과 같이 커스텀 어노테이션에 @Generic 어노테이션을 사용하면

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface BackgroundTask {
String value() default "";


이 어노테이션이 지정된 객체들은 모두 스프링 객체로 인식이 됩니다.

@BackgroundTask
public class FilePoller {

@PostConstruct
public void startPolling() {
...
}

@PreDestroy
public void stopPolling() {
...
}
...


이렇게 자동 인식된 빈들은 클래스 이름으로 등록이 됩니다. 위의 예에 나오는 FilePoller 클래스는 filePoller라는 이름으로 스프링에 등록되는거죠. 만약 다른 이름을 원하면 이렇게 합니다.

@Service("petClinic")
public class SimpleJdbcClinic {
...


기본적으로 스프링은 빈을 싱글톤으로 관리하지만 다른 스코프를 써야 할 경우도 있습니다. 이 경우는 요렇게...

@Component
@Scope("session")
public class ShoppingCart {
...


전 지금 진행중인 프로젝트에 2.5를 적용할 예정입니다. 원래 아발론으로 만들어진 서버 프로그램인데 스프링으로 바꾸고 있거든요. 

프로그래밍이 즐거워지네요. ㅎㅎ

아! 아시겠지만 제가 잘못 이해해서 생긴 오류에 대해서는 책임 안집니다. ;;; 



Introduction

Since its inception the Spring Framework has consistently focused on the goal of simplifying enterprise application development while providing powerful, non-invasive solutions to complex problems. With the release of Spring 2.0 just over a year ago, these themes advanced to a new level. XML Schema support and custom namespaces reduce the amount of XML-based configuration. Developers using Java 5 or greater are able to take advantage of Spring libraries that exploit new language features such as generics and annotations. The close integration with AspectJ's expression language enables the non-invasive addition of behavior across well-defined groupings of Spring-managed objects.

The newly released Spring 2.5 continues this trend by offering further simplifications and powerful new features especially for those who are using Java 5 or greater. These features include annotation-driven dependency injection, auto-detection of Spring components on the classpath using annotations rather than XML for metadata, annotation support for lifecycle methods, a new web controller model for mapping requests to annotated methods, support for Junit 4 in the test framework, new additions to the Spring XML namespaces, and more.

This article is the first of a three-part series exploring these new features. The current article will focus on simplified configuration and new annotation-based functionality in the core of the Spring application context. The second article will cover new features available in the web-tier, and the final article will highlight additional features available for integration and testing. Most of the examples depicted within this article series are based upon the Spring PetClinic sample application. That sample has recently been refactored to serve as a showcase of the latest Spring functionality and is included within the Spring 2.5 distribution available at the Spring Framework Download page. View the 'readme.txt' file within the 'samples/petclinic' directory for instructions on building and deploying the PetClinic application. Experimenting with the showcased features in the PetClinic application is probably the best way to master the new techniques discussed here.

Spring support for JSR-250 annotations

The 'Common Annotations for the Java Platform' were introduced with Java EE version 5 and are also included out-of-the-box beginning with Java SE version 6. In May 2006, BEA Systems announced their collaboration with Interface21 on a project called Pitchfork that provided a Spring-based implementation of the Java EE 5 programming model including support for JSR-250 annotations and EJB 3 annotations (JSR-220) for injection, interception, and transactions. As of version 2.5, the Spring Framework core now provides support for the following JSR-250 annotations:

  • @Resource
  • @PostConstruct
  • @PreDestroy

With Spring these annotations are supported in any environment - with or without an Application Server - and even for integration testing. Enabling this support is just a matter of registering a single Spring post-processor:

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/> 

The @Resource Annotation

The @Resource annotation enables dependency injection of a "named resource". Within a Java EE application, that typically translates to an object bound to the JNDI context. Spring does support this usage of @Resource for resolving objects through JNDI lookups, but by default the Spring-managed object whose "bean name" matches the name provided to the @Resource annotation will be injected. In the following example, Spring would pass a reference to the Spring-managed object with a bean name of "dataSource" to the annotated setter method.

@Resource(name="dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

It is also possible to annotate a field directly with @Resource. By not exposing a setter method, the code is more concise and also provides the additional benefit of enforcing immutability. As demonstrated below, the @Resource annotation does not even require an explicit String value. When none is provided, the name of the field will be used as a default.

@Resource
private DataSource dataSource; // inject the bean named 'dataSource'

When applied to a setter method, the default name would be derived from the corresponding property. In other words, a method named'setDataSource' would also resolve to the property named 'dataSource'.

private DataSource dataSource;
@Resource
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}

When using @Resource without an explicitly provided name, if no Spring-managed object is found for the default name, the injection mechanism will fallback to a type-match. If there is exactly one Spring-managed object matching the dependency's type, then it will be injected. This feature can be disabled by setting the 'fallbackToDefaultTypeMatch' property of the CommonAnnotationBeanPostProcessor to 'false' (it is 'true' by default).

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="fallbackToDefaultTypeMatch" value="false"/>
</bean>

As mentioned above, Spring does provide support for JNDI-lookups when resolving dependencies that are annotated with @Resource. To force direct JNDI lookups for all dependencies annotated with @Resource, set the 'alwaysUseJndiLookup' flag of theCommonAnnotationBeanPostProcessor to 'true' (it is 'false' by default).

<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true"/>
</bean>

Alternatively, to enable lookup based upon global JNDI names specified as 'resource-ref-mappings', provide the 'mappedName' attribute within the@Resource annotation. Even when the target object is actually a JNDI resource, it is the recommended practice to still reference a Spring-managed object thereby providing a level of indirection and hence a lesser degree of coupling. With the namespace additions available since Spring 2.0, a bean definition that delegates to Spring for handling the JNDI lookup is trivial and concise:

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/> 

The advantage of this approach is that the level of indirection provides for greater deployment flexibility. For example, a standalone system test environment should not require a JNDI registry. In such a case, the following alternate bean definition could be provided within the system test configuration:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>

As an aside, in the example above the actual JDBC connection properties are resolved from a properties file where the keys match the provided ${placeholder} tokens. This is accomplished by registering a Spring BeanFactoryPostProcessor implementation calledPropertyPlaceholderConfigurer. This is a commonly used technique for externalizing those properties - often environment-specific ones - that may need to change more frequently than the rest of the configuration.

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>

With the addition of the 'context' namespace in Spring 2.5, a more concise alternative for the property placeholder configuration is available:

<context:property-placeholder location="classpath:jdbc.properties"/> 

Lifecycle Annotations: @PostConstruct and @PreDestroy

The @PostConstruct and @PreDestroy annotations can be used to trigger Spring initialization and destruction callbacks respectively. This feature extends but does not replace the two options for providing such callbacks in Spring versions prior to 2.5. The first option is to implement one or both of Spring's InitializingBean and DisposableBean interfaces. Each of those interfaces requires a single callback method implementation (afterPropertiesSet() and destroy() respectively). The interface-based approach takes advantage of Spring's ability to automatically recognize any Spring managed object implementing those interfaces and therefore requires no additional configuration. On the other hand, a key goal of Spring is to be as non-invasive as possible. Therefore instead of implementing Spring-specific interfaces, many Spring users have taken advantage of the second option which is to provide their own initialization and destruction methods. While less invasive, the drawback of that approach is that it requires explicit declaration of 'init-method' and/or 'destroy-method' attributes on the 'bean' element. That explicit configuration is sometimes necessary, such as when the callbacks need to be invoked on code that is outside of the developer's control. The PetClinic application demonstrates this scenario. When it is run with its JDBC configuration, a third party DataSource is used, and a 'destroy-method' is declared explicitly. Also notice that the standalone connection-pooling DataSource is yet another deployment option for the 'dataSource' and does not require any code changes.

<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>

With Spring 2.5, if an object requires invocation of a callback method upon initialization, that method can be annotated with the @PostConstructannotation. For example, imagine a background task that needs to start polling a file directory upon startup.

public class FilePoller {

@PostConstruct
public void startPolling() {
...
}
...
}

Similarly, a method annotated with @PreDestroy on a Spring-managed object will be invoked when the application context hosting that object is closed.

public class FilePoller {

@PreDestroy
public void stopPolling() {
...
}
...
}

With the addition of support for the JSR-250 annotations, Spring 2.5 now combines the advantages of its two previous lifecycle method alternatives. Adding @PostConstruct and @PreDestroy as method-level annotations is sufficient for triggering the callbacks within a Spring managed context. In other words, no additional XML-based configuration is necessary. At the same time, the annotations are part of the Java language itself (and even included within Java SE as of version 6) and thus require no Spring-specific imports. The annotations have the added benefit of indicating semantics that should be understood within other environments, and over time Java developers can likely expect to see these annotations used more frequently within third-party libraries. Finally, one interesting consequence of the annotation-based lifecycle callbacks is that more than one method may carry either annotation, and all annotated methods will be invoked

To enable all of the behavior as described above for the @Resource@PostConstruct, and @PreDestroy annotations, provide a single bean definition for Spring's CommonAnnotationBeanPostProcessor as shown previously. An even more concise option is possible with the new 'context' namespace in 2.5:

<context:annotation-config/> 

Including that single element will not only register a CommonAnnotationBeanPostProcessor, but it will also enable the autowiring behavior as described in the section that follows. The CommonAnnotationBeanPostProcessor even provides support for @WebServiceRef and @EJBannotations. These will be covered in the third article of this series along with other new Spring 2.5 features for enterprise integration.

Fine-Grained Autowiring with Annotations

Documentation covering Spring's support for autowiring has often been accompanied with caveats due to the coarse granularity of the autowiring mechanism. Prior to Spring 2.5, autowiring could be configured for a number of different approaches: constructor, setters by type, setters by name, or autodetect (where Spring chooses to autowire either a constructor or setters by type). These various options do offer a large degree of flexibility, but none of them offer very fine-grained control. In other words, prior to Spring 2.5, it has not been possible to autowire a specific subset of an object's setter methods or to autowire some of its properties by type and others by name. As a result, many Spring users have recognized the benefits of autowiring for prototyping and testing, but when it comes to maintaining and supporting systems in production, most agree that the added verbosity of explicit configuration is well worth the clarification it affords.

However, Spring 2.5 dramatically changes the landscape. As described above, the autowiring choices have now been extended with support for the JSR-250 @Resource annotation to enable autowiring of named resources on a per-method or per-field basis. However, the @Resource annotation alone does have some limitations. Spring 2.5 therefore introduces an @Autowired annotation to further increase the level of control. To enable the behavior described in this section, register a single bean definition:

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/> 

Alternatively, the 'context' namespace provides a more concise alternative as shown previously. This will enable both post-processors discussed in this article (AutowiredAnnotationBeanPostProcessor and CommonAnnotationBeanPostProcessor) as well as the annotation-based post-processors that were introduced in Spring 2.0: RequiredAnnotationBeanPostProcessor and PersistenceAnnotationBeanPostProcessor.

<context:annotation-config/> 

With the @Autowired annotation, it is possible to inject dependencies that match by type. This behavior is enabled for fields, constructors, and methods. In fact, autowired methods do not have to be 'setter' methods and can even accept multiple parameters. The following is perfectly acceptable:

@Autowired
public void setup(DataSource dataSource, AnotherObject o) { ... }

By default, dependencies marked with the @Autowired annotation are treated as required. However, it is also possible to declare any of them as optional by setting the 'required' attribute to 'false'. In the following example, DefaultStrategy will be used if no Spring-managed object of typeSomeStrategy is found within the context.

@Autowired(required=false)
private SomeStrategy strategy = new DefaultStrategy();

Autowiring by type can obviously result in ambiguities when the Spring context contains more than one object of the expected type. By default, the autowiring mechanism will fail if there is not exactly one bean for a required dependency. Likewise for any optional properties, it will fail if more than one candidate is available (if optional and zero candidates are available, then it will simply skip the property). There are a number of configuration options for avoiding these conflicts.

When there is one primary instance of a given type within the context, the bean definition for that type should contain the 'primary' attribute. This approach works well when other instances may be available in the context, yet those non-primary instances are always explicitly configured.

<bean id="dataSource" primary="true" ... /> 

When more control is needed, any autowired field, constructor argument, or method parameter may be further annotated with a @Qualifierannotation. The qualifier may contain a String value in which case Spring will attempt to match by name.

@Autowired
@Qualifier("primaryDataSource")
private DataSource dataSource;

The main reason that @Qualifier exists as a separate annotation is so that it can be applied at the level of a constructor argument or method parameter while the @Autowired annotation is available on the constructor or method itself.

@Autowired
public void setup(@Qualifier("primaryDataSource") DataSource dataSource, AnotherObject o) { ... }

The fact that @Qualifier is a separate annotation provides even more benefits with regard to customization. User-defined annotations may also play the role of qualifier in the autowiring process. The simplest way to accomplish this is to annotate the custom annotation with @Qualifier itself as a meta-annotation.

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface VetSpecialty { ... }

Custom annotations may optionally include a value for matching by name but more commonly would be used as "marker" annotations or define a value that provides some further meaning to the qualifier process. For example, the excerpt below depicts a field that should be autowired with a qualified candidate among those that match by type.

@Autowired
@VetSpecialty("dentistry")
private Clinic dentistryClinic;

When using XML configuration for the target of this dependency resolution, 'qualifier' sub-elements may be added to the bean definition. In the next section on component-scanning, a non-XML alternative will be presented.

<bean id="dentistryClinic" class="samples.DentistryClinic">
<qualifier type="example.VetSpecialty" value="dentistry"/>
</bean>

To avoid any dependency on the @Qualifier annotation whatsoever, provide a CustomAutowireConfigurer bean definition within the Spring context and register any custom annotation types directly:

<bean class="org.springframework.beans.factory.annotation.CustomAutowireConfigurer">
<property name="customQualifierTypes">
<set>
<value>example.VetSpecialty</value>
</set>
</property>
</bean>

Now that the custom qualifier has been explicitly declared, the @Qualifier meta-annotation is no longer required.

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface VetSpecialty { ... }

On a related note, it is even possible to replace the @Autowired annotation itself when configuring theAutowiredAnnotationBeanPostProcessor.

<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor">
<property name="autowiredAnnotationType" value="example.Injected"/>
</bean>

In a majority of cases, the ability to define custom "marker" annotations combined with the options of matching by name or other semantic value should be sufficient for achieving fine-grained control of the autowiring process. However, Spring also provides support for any number of arbitrary attributes on qualifier annotations. For example, the following is a hypothetical example of a very fine-grained qualifier.

@SpecializedClinic(species="dog", breed="poodle")
private Clinic poodleClinic;

The custom qualifier implementation would define those attributes.

@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface SpecializedClinic {

String species();

String breed();

}

The custom qualifier's attributes can then match against 'attribute' sub-elements of the 'qualifier' annotation within the XML of a bean definition. These elements are used to provide key/value pairs.

<bean id="poodleClinic" class="example.PoodleClinic">
<qualifier type="example.SpecializedClinic">
<attribute key="species" value="dog"/>
<attribute key="breed" value="poodle"/>
</qualifier>
</bean>

All of the autowiring demonstrated so far has been for single instances, but collections are supported as well. Any time it's necessary to get all Spring-managed objects of a certain type within the context, simply add the @Autowired annotation to a strongly-typed Collection.

@Autowired
private List<Clinic> allClinics;

One final feature that is worth pointing out in this section is the use of autowiring in place of Spring's "Aware" interfaces. Prior to Spring 2.5, if an object requires a reference to the Spring context's ResourceLoader, it can implement ResourceLoaderAware thereby allowing Spring to provide this dependency via the setResourceLoader(ResourceLoader resourceLoader) method. This same technique applies for obtaining a reference to the Spring-managed MessageSource and even the ApplicationContext itself. For Spring 2.5 users, this behavior is now fully supported through autowiring (note that the inclusion of these Spring-specific dependencies should always be carefully considered and typically only used within "infrastructure" code that is clearly separated from business logic).

@Autowired
private MessageSource messageSource;

@Autowired
private ResourceLoader resourceLoader;

@Autowired
private ApplicationContext applicationContext;

Auto-Detection of Spring Components

Beginning with version 2.0, Spring introduced the concept of "stereotype" annotations with the @Repository annotation serving as a marker for data access code. Spring 2.5 adds two new annotations - @Service and @Controller - to complete the role designations for a common three-tier architecture (data access objects, services, and web controllers). Spring 2.5 also introduces the generic @Component annotation which the other stereotypes logically extend. By clearly indicating application roles, these stereotypes facilitate the use of Spring AOP and post-processors for providing additional behavior to the annotated objects based on those roles. For example, Spring 2.0 introduced thePersistenceExceptionTranslationPostProcessor to automatically enable data access exception translation for any object carrying the@Repository annotation.

These same annotations can also be used in conjunction with another new feature of Spring 2.5: auto-detection of components on the classpath. Although XML has traditionally been the most popular format for Spring metadata, it is not the only option. In fact, the Spring container's internal metadata representation is pure Java, and when XML is used to define Spring-managed objects, those definitions are parsed and converted to Java objects prior to the instantiation process. One significant new capability of Spring 2.5 is the support for reading that metadata from source-level annotations. The autowiring mechanisms described thus far make use of annotation metadata for injecting dependencies but still require registration of at least a minimal "bean definition" in order to provide the implementation class of each Spring-managed object. The component scanning functionality can remove the need for even that minimal bean definition in XML.

As seen above, Spring's annotation-driven autowiring can significantly reduce the amount of XML without sacrificing fine-grained control. The component detection mechanism takes this even further. It is not necessary to completely supplant configuration in XML, rather the component scanning can operate alongside XML metadata to simplify the overall configuration. This possibility of combining XML and annotation-driven techniques can lead to a well-balanced approach as demonstrated by the 2.5 version of the PetClinic sample application. There, the infrastructural components (data source, transaction manager, etc) are defined in XML along with externalized properties as described above. The data access tier objects are also defined partially in XML, but their configuration also takes advantage of the @Autowired annotations to simplify the injection of dependencies. Finally, the web tier "controllers" are not explicitly defined in XML at all. Instead the following configuration is used to trigger the auto-detection of all web controllers:

<context:component-scan base-package="org.springframework.samples.petclinic.web"/> 

Notice that the 'base-package' attribute is provided. The default matching rules for component-scanning will recursively detect any of Spring's stereotype annotations on classes within that package (multiple packages can be provided in a comma-separated list). Therefore, the various controller implementations for the PetClinic sample application are all annotated with @Controller (one of Spring's built-in stereotypes). Here is an example:

@Controller
public class ClinicController {

private final Clinic clinic;

@Autowired
public ClinicController(Clinic clinic) {
this.clinic = clinic;
}
...

Auto-detected components are registered with the Spring container just as if they had been defined in XML. As depicted above, those objects can in turn make use of annotation-driven autowiring.

The component scanner's matching rules can also be customized with filters for including or excluding components based on type, annotation, AspectJ expression, or regular expressions for name patterns. The default stereotypes can also be disabled. For example, a test configuration may ignore the default stereotypes and instead auto-detect any class whose name starts with Stub or which includes the @Mock annotation:

<context:component-scan base-package="example" use-default-filters="false">
<context:include-filter type="aspectj" expression="example..Stub*"/>
<context:include-filter type="annotation" expression="example.Mock"/>
</context:component-scan>

Type matching restrictions can be controlled with exclusion filters as well. For example, to rely on the default filters except for the @Repositoryannotation, then add an exclude-filter.

<context:component-scan base-package="example">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Repository"/>
</context:component-scan>

Clearly it is possible to extend the component scanning in a number of ways to register your own custom types. The stereotype annotations are the simplest option, so the notion of stereotype is therefore extensible itself. As mentioned earlier, @Component is the generic stereotype indicator that the @Repository@Service, and @Controller annotations "logically" extend. It just so happens that @Component can be provided as a meta-annotation (i.e. an annotation declared on another annotation), and any custom annotation that has the @Component meta-annotation will be automatically detected by the default matching rules of the scanner. An example will hopefully reveal that this is much simpler than it sounds.

Recall the hypothetical background task that was described in the section above covering the @PostConstruct and @PreDestroy lifecycle annotations. Perhaps an application has a number of such background tasks, and those task instances would typically require XML bean definitions in order to be registered with the Spring context and have their lifecycle methods invoked at the right time. With component scanning, there is no longer a need for those explicit XML bean definitions. If the background tasks all implement the same interface or follow a naming convention, theninclude-filters could be used. However, an even simpler approach is to create an annotation for these task objects and provide the @Componentmeta-annotation.

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface BackgroundTask {
String value() default "";
}

Then provide the custom stereotype annotation in any background task's class definitions.

@BackgroundTask
public class FilePoller {

@PostConstruct
public void startPolling() {
...
}

@PreDestroy
public void stopPolling() {
...
}
...
}

The generic @Component annotation could just as easily have been provided instead, but the custom annotation technique provides an opportunity for using meaningful, domain-specific names. These domain-specific annotations then provide further opportunities such as using an AspectJ pointcut expression to identify all background tasks for the purpose of adding advice that monitors the activity of those tasks.

By default, when a component is detected, Spring will automatically generate a "bean name" using the non-qualified class name. In the previous example, the generated bean name would be "filePoller". However, for any class that is annotated with one of Spring's stereotype annotations (@Component@Repository@Service, or @Controlleror any other annotation that is annotated with @Component as a meta-annotation (such as @BackgroundTask in the above example), the 'value' attribute can be explicitly specified for the stereotype annotation, and the instance will then be registered within the context with that value as its "bean name". In the following example the name would be "petClinic" instead of the default generated name of "simpleJdbcClinic".

@Service("petClinic")
public class SimpleJdbcClinic {
...
}

Likewise, the bean name generated for the following revised version of the FilePoller would be "poller" instead of "filePoller".

@BackgroundTask("poller")
public class FilePoller {
...
}

While all Spring-managed objects are treated as singleton instances by default, it is sometimes necessary to specify an alternate "scope" for an object. For example, in the web-tier a Spring-managed object may be bound to 'request' or 'session' scope. As of version 2.0, Spring's scope mechanism is even extensible so that custom scopes can be registered with the application context. Within an XML configuration, it's simply a matter of including the 'scope' attribute and the name of the scope.

<bean id="shoppingCart" class="example.ShoppingCart" scope="session">
...
</bean>

With Spring 2.5, the same can be accomplished for a scanned component by providing the @Scope annotation.

@Component
@Scope("session")
public class ShoppingCart {
...
}

One final topic to address here is the simplification of qualifier annotations when using component-scanning. In the previous section, the following object was used as an example of autowiring with a custom qualifier annotation:

@VetSpecialty("dentistry")
private Clinic dentistryClinic;

That same example then featured use of a 'qualifier' element within the XML on the intended target bean definition for that dependency. When using component-scanning, the XML metadata is not necessary. Instead, the custom qualifier may be included as a type-level annotation in the target class definition. An alternative example with a scanned @Repository instance as the dependency would thus appear as follows:

@Repository
@VetSpecialty("dentistry")
public class DentistryClinic implements Clinic {
...
}

Finally, for the previous example that featured custom qualifier annotations with attributes, the non-XML equivalent for that dependency's target would be:

@Repository
@SpecializedClinic(species="dog", breed="poodle")
public class PoodleClinic implements Clinic {
...
}

Conclusion

Spring 2.5 offers significant new functionality in a number of areas. The primary focus of this article has been on simplifying configuration by harnessing the power of Java annotations. Spring supports 'Common Annotations' as defined in JSR-250 while providing additional annotations for even more fine-grained control of the autowiring process. Spring 2.5 also extends the 'stereotype' annotations that began with Spring 2.0's@Repository, and all of these stereotypes can be used in conjunction with the new component-scanning functionality. XML-based configuration is still fully supported, and Spring 2.5 introduces a new 'context' namespace that offers more concise syntax for common configuration scenarios. In fact, the support for seamlessly combining XML and annotation-based configuration enables a well-balanced overall approach. Complex configuration of infrastructure can be defined in modular XML files while the progressively higher layers of an application stack can benefit from more annotation-based techniques - all within the same Spring 2.5 application context.

Stay tuned for the next article in this series, which will cover powerful new annotation-based functionality in the Spring web tier.



:

[펌] Java Annotation

ITWeb/개발일반 2009. 5. 12. 20:08

[원본 글]
http://java.sun.com/j2se/1.5.0/docs/guide/language/annotations.html
http://java.sun.com/docs/books/tutorial/java/javaOO/annotations.html

기본적으로 알고 계셔야 하는 annotation 이지요... :)

@Deprecated

The @Deprecated (in the API reference documentation) annotation indicates that the marked method should no longer be used. The compiler generates a warning whenever a program uses a deprecated method, class, or variable. When an element is deprecated, it should be documented using the corresponding @deprecated tag, as shown in the preceding example. Notice that the tag starts with a lowercase "d" and the annotation starts with an uppercase "D". In general, you should avoid using deprecated methods — consult the documentation to see what to use instead.

@Override

The @Override (in the API reference documentation) annotation informs the compiler that the element is meant to override an element declared in a superclass. In the preceding example, the override annotation is used to indicate that the getPreferredFood method in the Horse class overrides the same method in the Animal class. If a method marked with @Override fails to override a method in one of its superclasses, the compiler generates an error.

While it's not required to use this annotation when overriding a method, it can be useful to call the fact out explicitly, especially when the method returns a subtype of the return type of the overridden method. This practice, called covariant return types, is used in the previous example: Animal.getPreferredFood returns a Food instance. Horse.getPreferredFood (Horse is a subclass of Animal) returns an instance of Hay (a subclass of Food). For more information, see Overriding and Hiding Methods (in the Learning the Java Language trail).

@SuppressWarnings

The @SuppressWarnings (in the API reference documentation) annotation tells the compiler to suppress specific warnings that it would otherwise generate. In the previous example, the useDeprecatedMethod calls a deprecated method of Animal. Normally, the compiler generates a warning but, in this case, it is suppressed.

Every compiler warning belongs to a category. The Java Language Specification lists two categories: "deprecation" and "unchecked". The "unchecked" warning can occur when interfacing with legacy code written before the advent of generics. To suppress more than one category of warnings, use the following syntax:

@SuppressWarnings({"unchecked", "deprecation"})

위 원문에 대한 번역이 잘된 글 링크 넣습니다.
원본 글 : http://decoder.tistory.com/21

 

: