스프링 컨테이너는 base-package의 클래스를 검색해서 자동으로 자바빈으로 등록하는데 이에 해당하는것이 @Component, @Repository, @Service, @Contoroller, @RestController 어노테이션이다.
자동스캔을 위해서는 <context:component-scan /> 과 같이 base-package를 기술하며, 패키지가 여럿인 경우, 콤마로 구분하여
기술한다.
2. Spring Framework_Spring Ioc & DI
Spring IoC & DI
4. DI와 관련된 어노테이션
1) Auto-Scanning Component
• 스프링 컨테이너는 base-package의 클래스를 검색해서 자동으로 자바빈으로 등록
하는데 이에 해당하는것이 @Component, @Repository, @Service, @Contoroller,
@RestController 어노테이션이다.
• 자동스캔을 위해서는 <context:component-scan base-package="onj.edu.spring"
/> 과 같이 base-package를 기술하며, 패키지가 여럿인 경우, 콤마로 구분하여
기술한다.
3. Spring Framework_Spring Ioc & DI
1) Auto-Scanning Component
@Component
//하나의 Bean 정의에 대해서 다수의 객체가 존재하며 생략하면 Singleton으로 생성된다.
@Scope("prototype")
publicclassStudent{
.....
}
@Component :
일반적인 용도의 컴포넌트들을 표시하는 기본 스테레오타입, 멤버 변수와 getter,
Setter만 가지고 있는 DTO 같은 컴포넌트를 지칭한다. 스프링이 @Component 붙은 자바클래스를
클래스패스 경로에서 자동으로 찾아 Application Context안에 이름을 부여하고 빈으로 등록한다.
빈의 기본 Scope는 songleton이며 @Scope 어노테이션으로 변경 가능하다.
@Repository :
퍼시스턴스 레이어의 DAO 컴포넌트에 부여하는 어노테이션, @Compone의 역할과 유사하며
DAO 메소드가 던지는 예외(Unckecked Exception)를 스프링의 DataAccessException으로 변환한다.
@Repository
publicclassEmpRepositoryImpl implements EmpRepository{
.....
}
4. Spring Framework_Spring Ioc & DI
@Service
publicclassEmpServiceImpl implements EmpService{
.....
@Autowired
EmpRepository empRepository;
}
@Service :
비즈니스 로직을 담고 있는 서비스 레이어의 서비스 컴포넌트를 가리키며 @Component
어노테이션과 동작은 같지만 서비스 계층의 클래스들은 @Service 어노테이션을 부여하는 것이
코드 가독성이좋다.
@Controller:
프리젠테이션 레이어의 컨트롤러 컴포넌트
@Controller
public class BoardMultiController{
@Autowired
private SpringBoardService springBoardService;
...
}
5. Spring Framework_Spring Ioc & DI
2) Context Configuration
Singleton – IoC 컨테이너당하나의빈을리턴
Prototype – 요구가있을때마다새로운빈을만들어리턴
Request - HTTP request 객체당하나의빈을리턴
Session - HTTP session 당하나의빈을리턴
globalSession - 전체모든세션에대해하나의빈을리턴
@Component
@Scope("prototype") //요구시마다 하나의 새로운 빈을 리턴
class Ojc {
……
}
<bean id="ojc" class="oraclejava.edu.Ojc"scope="prototype"/>
@Scope :
일반적으로 @Component, @Service, @Repository 등으로 자동 스캐닝한 자바빈은 싱글톤
형태로 하나만 생성하는 데 이를 변경하려면 @Scope 어노테이션을 사용하면 된다. 즉, 빈의
범위를 설정한다.
6. Spring Framework_Spring Ioc & DI
@Autowired:
Spring Framework에 종속적인 어노테이션이다. 빈의 id, name로 아무거나 맞으면 적용 (Type
Driven Injection). 여러 개의 빈이 검색 될 경우 @Qualifier(name="xxx") 어노테이션으로구분한다.
기본적으로 @Autowired된 속성은 모두 빈이 주입되어야 한다. (주입될 빈이 없는 경우가 있다면
required=false로 하면 오류는 발생하지 않는다.) 멤버변수, setter 메소드, 생성자, 일반 메소드에
적용 가능
빈을 주입받는 경우 아래의 어노테이션이 사용가능하다.
@Resourse:
Spring2.5 이상에서 사용 가능하며. Spring Framework에 비종속적으로 권장하는 방식이다.
빈의 name으로 주입 될 빈을 찾는다. 멤버 변수, setter 메소드에 적용가능.
사용하기 위해서는 jsr250-api.jar가 클래스패스에 추가 되어야한다.
[MAVEN 설정]
<dependency>
<groupId>javax.annotation</groupId>
<artifactId>jsr250-api</artifactId>
<version>1.0</version>
</dependency>
}
7. Spring Framework_Spring Ioc & DI
@Inject:
Spring3.0 이상에서 사용 가능하다. 특정 Framework에 종속되지 않은 어플리케이션을 구성하기
위해서는 @Inject를 사용할 것을 권장한다. JSR.330 라이브러리인 javax.inject-x.x.x.jar 파일이 추가
되어야 한다. 멤버변수, setter 메소드, 생성자, 일반 메소드에 적용 가능하다.
[MAVEN 설정]
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
8. Spring Framework_Spring Ioc & DI
@Required:
Setter 메소드 위에 기술하여 필수 프로퍼티를 설정하는 용도로 사용된다.
package day1;
public class Emp {
private String ename;
@Required
public void setEname(String ename) { this.ename = ename; }
public String getEname() { return this.ename; }
}
XML설정에서(Beans.xml)…
<context:annotation-config/>
<bean id="emp" class="day1.Emp">
<!--아래프로퍼티를설정하지않으면오류-->
<!--<property ename="ename" value="홍길동"/> -->
</bean>
main에서…
ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");
Emp emp = (Student) context.getBean("emp");
System.out.println(“Ename : " + emp.getEname() );
오류메시지 → Property 'ename' is requiredfor bean 'emp'
@Required 어노테이션이 사용되기 위해서는 RequiredAnnotationBeanPostProcessor 클래스를 빈으로 등록하
거나 <context:annotation-config> 설정을 추가하면 된다.
9. Spring Framework_Spring Ioc & DI
@Named:
JSR-330의 어노테이션이며 Spring의 @Component, @Qualifier와 동일하다.
@Repository @Named
public classEmpDAO { …} public class EmpDAO { …}
@Service @Named
public class EmpService { …} public class EmpService { …}
@Component @Named
public class EmpVO { …} public class EmpVO { …}
@Autowired
public void setEmp(@Qualifier(“programmer") Emp emp) { …}
→ 아래와동일
@Inject
public void setEmp(@Named(“programmer") Emp emp) { …}
[MAVEN 설정]
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
11. Spring Framework_Spring Ioc & DI
@Order:
Spring4에서 새로 소개된 @Order 어노테이션은 같은 타입의 빈이 컬렉션(List등)에 Autowired 될
때 그 순서를 지정한다. (낮은 숫자가 우선 순위가 높다.)
먼저 @Order를 사용하지 않은 예제를 작성해 보자. (스프링 버전은 4이상으로)
package ojc;
public interface Emp {
public void work();
}
[Emp.java]
[Programmer.java]
package ojc;
import org.springframework.stereotype.Service;
@Service
public class Programmer implements Emp {
public void work() {
System.out.println("Programmer Working...");
}
}
12. Spring Framework_Spring Ioc & DI
package ojc;
import org.springframework.stereotype.Service;
@Service
public class Designer implements Emp {
public void work() {
System.out.println("Designer Working...");
}
}
[Designer.java]
[OrderTest.java]
@Service
public class OrderTest {
@Autowired
List<Emp> emps;
public static void main(String[] args) {
ApplicationContext context = new
ClassPathXmlApplicationContext("order.xml");
OrderTest test = (OrderTest) context.getBean("orderTest");
for(Emp e : test.emps) {
e.work();
}
}
}
13. Spring Framework_Spring Ioc & DI
<?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-4.2.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.2.xsd">
<context:component-scan base-package="ojc"/>
</beans>
[/src/main/resources/order.xml]
[실행결과]
Designer Working…
Programmer Working…
OrderTest를 실행하면 다음과 같이 결과가 나타난다. (Designer가 List에 먼저 주입됨)
14. Spring Framework_Spring Ioc & DI
@Service
@Order(value=2)
public class Designer implements Emp { … }
[Designer.java]
이제는 Programmer가 우선 순위가 높아 먼저 출력될 것이다.
그러나 emps 리스트에 주입되는 빈에 순서가 정의되지 않는다. 이 때, 주입되는 순서를 주기
위해 @Order를 사용하면 된다. 물론 XML설정을 이용하여 Programmer, Designer를 빈으로
등록해 놓고 List<Emp> emps의 setter를 이용하여 Collection 형태로 빈을 주입한다면 기술된
빈의 순서대로 List에 들어가게 된다. 앞의 예제를 수정해 보자.
@Service
@Order(value=1)
public class Programmer implements Emp { … }
[Programmer.java]
15. Spring Framework_Spring Ioc & DI
class Hello {
String name = null;
Hello(String name) {
this.name = name;
}
@PostConstruct
public initObj() {
if (name == null) {
name = "홍길동";
}
}
}
@PostConstruct :
객체가 생성된 후 별도의 초기화 작업을 위해 실행하는 메소드를 선언한다.
CommonAnnotationBeanPostProcessor 클래스를 빈으로 등록시키거나 <context:annotation-
config> 태그를 사용하면 된다.
@PreDestroy:
스프링 컨테이너에서 객체(빈)를 제거하기 전에 해야 할 작업이 있다면 메소드 위에 사용하는
어노테이션이다. 이 어노테이션을 사용하기 위해서는 CommonAnnotationBeanPostProcessor
클래스를 빈으로 등록하거나 <context:annotation-config> 태그를 사용하면 된다.