아래의 내용은 최범균의 스프링3.0 책과 인터넷 내용등을 찾아서 만든것임을 밝힌다.
1. @Component
클래스의 상단에 적용하는것으로 해당 어노테이션을 적용하면 <context:component-scan> 태그를 이용해서 해당 적용된 클래스들을 빈으로 자동 등록하게 된다.
원래 해당 클래스의 첫 문자를 소문자로 만들어서 빈이름으로 쓰는데 뒤에("xxx") 를 주면 "xxx" 로 이름을 정하게 된다.
2. @Resource
말그대로 리소스를 가져오는 역할이다.
@Resource(name = "camera3") 같은 경우는 xml에 id 가 camera3 의 것을 가져온다.
메소드에 선언하면 해당 메소드의 파라미터에 전달될 자원을 가져와서 대입해주는게 된다.
3. @Autowired
의존관계를 자동으로 설정할때 사용한다.
생성자,필드,메소드 3곳에 적용 가능하다. (프로퍼티 setXxxx에도 가능)
메소드에 정의하면 메소드의 아규먼트 값의 타입을보고 해당 빈을 생성해서 파라미터에 전달한다. (즉 파라미터에 적용됨)
멤버필드에 직접 적용하면 역시 해당 타입의 빈을 생성해서 할당한다. (선언에 대해 new 해서 할당하는 꼴임)
해당 어노테이션을 쓰려면 xml에 클래스빈을 등록해줘야하는데 (설정)
AutowiredAnnotationBeanPostProcessor ...
그냥 <context:annotation-config /> 태그를 해도 된다. (알아서 관련 빈이 등록됨)
만약 (required = false) 를 선언하면 해당 타입의 빈 객체가 없어도 예외를 발생하진 않는다.
4. @Qualifier
3번의 오토와이어드는 타입을 기반으로 하므로 자동설정할 타입이 두개 이상 존재하면 예외가 발생된다.(즉 등록빈중 타입이 같지만 이름이 다르게 된거... 가 여러개 있을때)
이때 @Qualifier("test3") 를 붙여주면 해당 빈을 가져온다.
물론 xml에
<bean id=' recorder ' calss='.,..'>
<qualifier value='test3'//>
</beawn>
라고 정의되어있다고 가정하고 말이다.
@Autowired
@Qualifier(" test3 ")
private Recorder recorder;
단 만약 여러개의 빈에 같은 qualifier 가 정의되어있으면 그거 모두 를 참조하게 된다.. 어떻게? 담기는게 .. List 로 되어있으면 List로 담기더라.
다른건 안해봐서 모르겠다 ㅠㅜ
-----------------------------------------------------------------------------------
2,3,4 추가 설명
@Resource 는 자바6에서 추가된것으로
@Resource : 어플리케이션에서 필요로 하는 자원을 자동 연결할때 사용된다.
이걸 스프링에서는 의존하는 빈 객체를 전달할때 사용된다.
즉 스프링에서는 객체 전달임 (생성되어있는 객체를... 지정하는 할당)
(name="xxx1") 식으로 빈 지정이 가능하다.
@Autowired 는 의존관계를 자동으로 설정할때 사용한다.
생성자, 필드, 메소드(e.g setXxx) 3군데 적용 가능하다.
메소드에 할때는 해당 파라미터를 자동 연결하는것이다.
멤버필드에 할때는.. 그전에 알아야 하는것이 Autowired 는 타입을 기준으로 연결한다.
즉
@Autowired
public void setDisplay(DisplayStrategy displayStrategy) { ... }
되어있으면 DisplayStrategy타입의 빈 객체를 전달하는것이다.
해당 어노테이션을 배열에 적용하면 해당 타입의 모든 빈객체를 가져오게된다. (배열이니까)
이건 메소드도 마찬가지다.(메소드에서 받는 파라미터가 배열이면 역시 다 가져온다)
Autowired는 타입을 이용해서 자동연결하므로 타입에 해당하는 빈이 존재하지 않거나 두개이상이면 에러가 난다.
해서 필수 속성을 줄 수 있다.
@Autowired (requied=false)
이러면 해당빈이 없어도 예외가 발생되진 않는다.(기본값은 true임)
만약 생성자에 해당 어노테이션을 적용할때는 하나의 생성자는 required=true 이어야하고 나머지는 false이어야 한다.
@Qualifier
오토와이어드 어노테이션은 해당 타입의 빈이 두개 이상 존재하면 에러가 난다.
이때 특정 빈과 연결되도록 해주는 어노테이션이다 (오토와이어드와 함께 사용??)
------------------------------------------------------------------------
5. @Configuration
1번의 Component 는 스캔과 같이 사용하여 이미 정해진 대상중 가져오는것이지만
이번 2개의 어노테이션은 새로운 빈객체를 그냥 등록할 수 있는 기능이다.
즉 자바코드를 이용해서 xml에 정의한 효과를 내는것이다.
해서 ... 원한다면 xml 없이 해당 어노테이션만으로 빈등록하여 구동이 가능하다.
@Bean
@Configuration
public class SpringConfig {
@Bean
public AlarmDevice alarmDevice() {
return new SmsAlarmDevice();
}
}
외와 같은 경우
<bean id = 'alarmDevice' class='xxx.xxx.xxx.SmsAlramDevice" />
라고 등록한것과 같은 의미가 된다.
물론 Bean 뒤에 (name="smsAlarmDevice") 처럼 정의하면 이름을 정할 수 도 있다.
그리고 Bean 을 이용한 생성시에도 autowired 속성을 이용하여 자동 연관 여부를 설정할 수 있다.
@Bean(autowired= Autowired.BY_NAME)
이는 <bean id='xxxx' class='xxxxx' autowired='byName'/> 과 같다.
근데 막상 위의 5번을 이용하려면 .. 우선 빈으로 만들 내용이 담긴 클래스(Configuration 과 Bean 어노테이션으로 정의된) 와
이를 자원화할 할 수 있는 클래스를 이용해야한다.
2가지 방법이 있는데, AnnotationConfigApplicationContext 클래스를 이용한(new 생성) .. 생성저에 빈등록내용클래스를 넣어줘서 자원을 꺼내오는 방법과
xml에 ConfigurationClassPostProcessor 를 이용하는방법이 있다.
@Configuration
public class SpringConfig {
@Bean
public Camera camera1() {
return new Camera();
}
@Bean
public Camera camera2() {
return new Camera();
}
... 이런 설정 클래스를 만들고
이를...
ApplicationContext context =new AnnotationConfigApplicationContext(SpringConfig.class);
HomeController homeController = context.getBean("homeController",HomeController.class);
이렇게 말이다.
XML 에서는
<bean class='org.spring..... ConfigurationClassPostProcessor"/>
<bean class="....SpringConfig"/>
하면된다.
참고로 <bean class='org.spring..... ConfigurationClassPostProcessor"/> 선언은 따로 할 필요 없이 그냥
<context:annotation-config/> 를 해줘도 위의 빈등록이 자동으로 된다 (추가적으로 몇개 더 된다)
@Import( { ArticleServiceConfig.class, ArticleRepositoryConfig.class })
Bean 말고 Import도 있다. 위와 같이 설정클래스를 별도로 가져와서 등록한다.
@Configuration
public class ArticleServiceConfig {
@Autowired
private ArticleRepositoryConfig repositoryConfig;
@Bean
public ArticleService articleService() {
return new ArticleServiceImpl(repositoryConfig.articleRepository());
}
}
@Configuration
public class ArticleRepositoryConfig {
@Bean
public ArticleRepository articleRepository() {
return new ArticleRepositoryImpl();
}
}
6. @PostConstruct , @PreDestory
PostConstruct 은 의존객체를 설정한 이후에 호출되는 메소드이고
PreDestroy 는 컨테이너에서 객체를 제거하기 전에 호출되는 메소드이다.
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
BeanDefinition 몇가지
1. (initMethod='init')
: 빈이 생성되고 DI를 마친 뒤에 실행할 초기화 메소드의 이름 , 예에서는 init 메소드가 호출됨
이때... Config... Bean... 으로 빈을 등록하게 하는 구조이고, Bean 설정에 이를 추가했다면?
해당 리턴될 자원의 클래스(현재의 설정클래스가 아니라) 에 초기화메소드라고 선언한 init 메소드가 있어야한다.
해당 초기화 선언없이 알아서 호출하는 자원의 특정 메소드에 @PostConstruct 를 해서 초기과정 진행하도록 해도 된다.