[ annoation이 나온 배경 ]
메타 데이터 (meta-data)
: 데이터의 데이터
ex) 택배 상자위에 붙어 있는 택배 안 내용물에 대한 상품 정보를 생각하면 된다!
메타 데이터는 설정정보의 역할을 하고 이는 xml에 기재해둔다.
⇒ 즉, xml은 설정정보를 처리하며, 이를 메타데이터라고 부른다.
그런데 점점 설정정보가 많아지며, xml에 기재하기 복잡해졌다. (xml에 모두 기재하기는 방대해졌다.)
이를 해결하기 위해 나온 기술이 'annotaiton(어노테이션)'이다.
xml | annotation (어노테이션) | |
메타데이터로 설정정보를 저장하기 위해 쓰인다. | ||
코드와 설정을 분리 | 코드에 설정을 명시 | |
이후에 변경 가능한 것일 때 xml 방식 사용 | 초기에 설정하여 변경하지 않는 것은 annotaion 방식 사용 | |
유지보수성에 초점 | 생상성에 초점 |
annotation(어노테이션)
: 주석이 선언적 프로그래밍 모델을 지원하는 기술
즉, 의미있는 주석으로, 컴파일과 런타임(실행)에 영향을 준다.
⇒ Annotaion(ex. @Controller)은 컴파일과 런타임 시에 영향을 주는 주석이다
Spring Annotation
→ 설정 정보의 역할
> Spring Configuration(스프링 설정) 방법
→ XML + Annoataion + properties + Java Config
> Spring IOC Annotation 종류
- @Component 컴포넌트 계열 어노테이션 : 스프링 컨테이너에 해당 클래스의 객체를 생성하도록 명시
- @Repository : 영속성 계층에서 사용 (ex. MemerDAO) - 데이터 연동 로직
- @Service : 비즈니스(서비스) 계층에서 사용 (ex. MemberService) - 비즈니스 로직
- @Controller : 프레젠테이션 계층에서 사용 (ex. MemberController)
- @Component : 모든 컴포넌트에 대한 제너릭 스테레오 타입
- 위 세가지 경우에 해당하지 않는 기타 자원 클래스에 사용 (ex. IOC/DI다 되지만 세밀한 제어X) - @DI(Dependency Injection) 계열 어노테이션 : 스프링 컨테이너로부터 의존성(의존대상객체)를 주입받고자 할 때 사용
- @AutoWired : 의존 대상 객체를 타입으로 검색해 주입
(단, 동일한 인터페이스의 구현 객체가 여러 개 있을 경우 Exception 발생
- 이를 해소하기 위해 @Quelifier("bean name")이 필요 )
- @Resouce : 의존 대상 객체를 타입으로 검색 + name을 통해 주입 - 주로 많이 사용!
(추가적으로 @Resource(name="beanId")를 명시하면 bean id로 검색해 주입)
< Component 계열의 Annotation >
maven pom 설정
/pom.xml
<dependencies>
<!-- Spring Framework -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.14.RELEASE</version>
</dependency>
</dependencies>
Spring configure 설정
* namespace에서 component를 체크해준다!
<context:component-scan base-package="org.kosta">
<context:component-scan>은 base-package에서 설정한 "org.kosta"의 하위 패키지의 모든 클래스를 탐색해서,
1) 컴포넌트 계열의 어노테이션(@Component, @Repository, @Service, @Controller) 이 명시된 클래스들을 객체로 만든다.
2) DI 계열 어노테이션이 명시된 대상에 대해 해당 객체를 주입하는 역할을 한다.
/spring-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<!--
<context:component-scan>은 base-package에서 설정한
"org.kosta"의 하위 패키지의 모든 클래스를 탐색해서,
컴포넌트 계열의 어노테이션(@Component, @Repository, @Service, @Controller)이
명시된 클래스들을 객체로 만든다.
-->
<context:component-scan base-package="org.kosta"></context:component-scan>
</beans>
Model
@Component 계열 annotation
@DI(Dependency Injection) 계열 어노테이션
@Repository
- 영속성 계층에 적용하는 컴포넌트 계열 어노테이션
/ProductDAO.java <<interface>>
package org.kosta.model;
public interface ProductDAO {
public void register(String info);
}
/ProductDAOImpl.java
package org.kosta.model;
import org.springframework.stereotype.Repository;
/*@Repository
* : @Component 계열의 어노테이션
* - 영속성 계층에 적용하는 컴포넌트 계열 어노테이션
*/
@Repository
public class ProductDAOImpl implements ProductDAO{
@Override //오버라이드 규칙은 컴파일 시 체크하는 어노테이션
public void register(String info) {
System.out.println("ProductDAOImpl register");
}
}
/ProductDAOImplVer2.java
package org.kosta.model;
import org.springframework.stereotype.Repository;
@Repository
public class ProductDAOImplVer2 implements ProductDAO{
@Override //오버라이드 규칙은 컴파일 시 체크하는 어노테이션
public void register(String info) {
System.out.println("ProductDAOImpl register");
}
}
@Service
- 비즈니스 계층(서비스 계층)에 적용하는 어노테이션
/ProductService.java <<interface>>
package org.kosta.model;
public interface ProductService {
public void register(String info);
}
@Autowired : Spring Container로부터 아래 객체를 주입받음 (생성자DI와 같은 역할)
BUT ! Autrowired 어노테이션은 타입으로 검색해 주입하므로,
동일한 인터페이스 타입의 구현체가 여러개일 경우에는 적합하지 않다. 그래서 대체제로 @Resouce를 사용한다.
@Resource (name="id") : 직접 구현체 id를 명시해 주입받는다.
/ProductServiceImpl.java
package org.kosta.model;
import javax.annotation.Resource;
import org.springframework.stereotype.Service;
/*
* @Service
* : 컴포넌트 계열 어노테이션
* - 비즈니스 계층(서비스 계층)에 적용하는 어노테이션
*/
@Service
public class ProductServiceImpl implements ProductService{
// @Autowired : Spring Container로부터 아래 객체를 주입받음 (생성자DI와 같은 역할)
//@Autowired
// 위 Autrowired 어노테이션은 타입으로 검색해 주입하므로,
// 동일한 인터페이스 타입의 구현체가 여러개일 경우에는 적합하지 않다.
@Resource(name = "productDAOImpl")
private ProductDAO productDAO;
@Override
public void register(String info) {
// -- 상품 등록에 관련한 처리 --
productDAO.register(info);
}
}
Test
/TestAnnotation.java
package test;
import org.kosta.model.ProductService;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestAnnotation {
public static void main(String[] args) {
ClassPathXmlApplicationContext factory
= new ClassPathXmlApplicationContext("spring-config.xml");
/*DL방식으로 객체 생성 여부 확인
* -> Component 방식 annotaion으로 생성된 빈의 id는
* 소문자로 시작하는 자신의 클래스명이 된다.
*/
// 1. repository(영속성 계층) 어노테이션 객체 반환
System.out.println(factory.getBean("productDAOImpl"));
//출력값 : org.kosta.model.ProductDAOImpl@371a67ec
// 2. 서비스 계열 어노테이션 객체 반환
System.out.println(factory.getBean("productServiceImpl"));
//출력값 : org.kosta.model.ProductServiceImpl@5ed828d
// 3. @Autowired된 비즈니스(서비스) 계층에 주입된
// 영속성 계층의 객체를 반환하여 함수 실행
ProductService service
= (ProductService) factory.getBean("productServiceImpl");
service.register("딸기");
//출력값 : ProductDAOImpl register
factory.close();
}
}
ProductDAO dao = (ProductDAO) factory.getBean("productDAOImpl");
→ DL방식으로 객체 생성 여부 확인
→ Component 방식 annotaion으로 생성된 빈의 id는 소문자로 시작하는 자신의 클래스명이 된다.
'Java Web Programming > 6. Spring | MyBatis' 카테고리의 다른 글
[SpringMVC] Annotation 어노테이션 기반의 SpringMVC 연습! (2) | 2020.11.05 |
---|---|
[Spring] 스프링 AOP Annotation 어노테이션 (0) | 2020.11.05 |
[SpringMVC] xml 기반으로 SpringMVC 패턴 적용해보기 (0) | 2020.11.04 |
[Spring/MyBatis] Spring MVC Pattern 적용해보기 (0) | 2020.11.04 |
[Spring/MyBatis] has a (aggregation) 관계 시, 구현방법 연습 (0) | 2020.11.03 |