웹 : Spring : Annotation기반 : 0406(2)
스프링 처음 나왔을 때 자바에 어노테이션 없었다.
스프링은 하위버전 호환성이 좋아 2점대 버전도 지금도 쓸 수 있다. 그러니까 어노테이션을 지금 프렘임웍구조에서 쓸거야 라는 postprocessor가 필요하다. 근데 잘 모르기도 함 왜냐하면 블랙박싱해놓아서 .... 우리는 이것들을 한꺼번에 등록해주는 설정만 찾으면 된다.
<context:annotation-config/> 짜잔~ 이거임...!!
이거 쓰려면 네임스페이스 xmlns:context="http://www.springframework.org/schema/context" 추가해줘야함.
javax.annotaion에 있는 @PostConstruct 어노테이션을 쓸 수 있게 된다.
위에 context를 주석걸어버리면
1개가 loaded되긴 했지만 init이 실행되지 않아서 내용이 나오지 않음.
<context:annotation-config />
<bean id="bar" class="kr.or.ddit.container.obj.Bar"/>
<bean id="baz" class="kr.or.ddit.container.obj.Baz"/>
<bean class="kr.or.ddit.container.obj.Foo">
<constructor-arg ref="bar" />
</bean>
bar는 생성자로 생성되기에 안생성될수없다.
baz는 주입이 되진 않지만 생성은 된다. lazy없다. foo와 baz는 관계가 없는 상태.
setterInjection 이라서 오류도 없다.
우리는 등록안하려고 어노테이션 사용한다. 등록 싹 지워버리고 해보자.
context:component-scan :
This tag implies the effects of the 'annotation-config' tag,
<context:component-scan base-package="kr.or.ddit.container.obj"></context:component-scan>
@Component
public class Bar { //이렇게 등록한다.
@Repository
public class Baz { // 이건뭐지?
@Service
public class Foo { // 이것두 있네?
bar는 이미 생성자에 있어서 호출된다.
@Autowired
public void setBaz(Baz baz) { // 바즈는 셋터에 오토를 걸어서 기본으로 설정된 required에 의해 true되어서 그냥 setter가 된다.
==> 명확하게 관계를 파악하려면 수동으로 등록하는 경우도 있
.No qualifying bean of type 'kr.or.ddit.container.obj.Baz' ==> baz가 컨테이너에 2개 등록되어있다면? 오류.
우리는 아이디를 등록하지 않았다 그렇다면 어떻게 등록되었을까? CoC로 등록되었다.
: 클래스 이름에서 첫문자만 소문자로 바꿨다.
<bean id="baz2" class="kr.or.ddit.container.obj.Baz" />
바즈를 2개 등록한 상황. @Autowired로 주입받으려고 한다면?
>> 결과 : Foo - setter를 통해 kr.or.ddit.container.obj.Baz@5e600dd5 주입 >> Type을 통해 구분하여 주입한다.
>>둘중에 누구일까? 알 수 없다. >> @Autowired의 한계점....!
POJO를 지향하는 Spring. Autowired는 Spring에 속해있다.
대신 Resource 어노테이션을 쓸 수 있다. 이것은 javax. >> Creating shared instance of singleton bean 'baz2'
👑정리
컨테이너에 빈을 등록하고, 의존관계를 형성할때 사용되는 어노테이션.
context:annotation-config : @AutoWired, @PostContruct, @PreDestroy 어노테이션을 활성화시킴 (BeanPostProcessor 설정 완료됨).
@PostContruct : init-method 설정
@PreDestroy : destroy-method 설정
@AutoWired : 의존성 주입 설정, 주입의 대상이 type 으로 선택됨.
@Resource : 의존성 주입 설정. 주입할 대상을 선택하는 조건을 명시할 수 있음. ex) name, type...
context:component-scan : context:annotation-config 를 포함함.
@Componunt
@Repository
@Service
@Controller
@Configuration : Java config 방식에 사용
<web에서 사용. >
@RestController
@controllerAdvice
@RestControllerAdvice
component의 어노테이션을 쪼개놓았다. 왜?
1. 사람에게 명확하게 어떤 역할을 하는 빈인지 알려주기 위해
2. 필터링
**xml이 없는 상태에서 config를 등록하는 것 : java config방식
@Autowired
@Qualifier("mariaDB") 스프링방식
@Resource(name="mariaDB") 자바방식
@Inject
@Named("mariaDB") 자바방식 ( dependency 추가해야한다. ) -- single일때 더 편함.
destroy확인해보자.
try(
ConfigurableApplicationContext context =
new GenericXmlApplicationContext("classpath:kr/or/ddit/sample/auto/conf/Sample-Auto.xml");
){
context.registerShutdownHook();
}