Spring 설치- 서론 spring 설치
서론...
작년에 한 것도 없고 요즘 재미도 없고 해서
올해는 spring을 알아보려 합니다.
아는 것도 없는데 저의 취미생활로 하니까 돌은 던지기 말아주시면 감사합니다. ^^*
얼마 전에 회사에서 Spring in action 이라는 책을 신청해서 나와서
책보면서 작성해 보려 합니다.
spring 설치
전 myeclipse를 사용합니다.
Visit http://www.myeclipseide.com/
여기서 받으시면 됩니다.
이 툴을 사용하는 이유는 플러그가 자동으로 설치되고
spring 개발을 쉽게 도와주기 때문입니다.
위 그림에서 Add Spring Capabilities… 를 클릭하시면
(주의 할 점 : 반드시 프로젝트를 하나 만들고 해야 합니다.)
위 그림이 나타나고 finish 하죠
그런 다음 http://www.springframework.org 에서 spring 최신 버젼을 받습니다.
책에서는 1.2.7 기준이라고 하는데 홈페이지에서는 벌써
2.0.2 이네요 걍~~~ 2.0.2로 하려 합니다.
다운을 하려고 보면 파일이 두 개 입니다.
윗 파일은 큰것으로 보아 서드파티 라이브러리가 포함된것이고 아래는 코아만 들어 있다고 하네요
걍 윗것으로 다운 받습니다
물론 myeclipse에서 1.2 버전을 지원하는데 2.0을 다운 받아 수동으로 라이브러리 추가하려고 합니다.
근데 아마도 책은 1.2 버전 기준이기때문에 나중에 2.0을 사용하지 않을까 하네요 ^^*
Spring 라이브러리
Jar 파일 |
용도 |
의존대상 |
Spring-core.jar |
스프링 핵심 컨테이너와 유틸리티 |
커먼스 로깅, 선택사항:Log4J |
Spring-aop.jar |
스프링 aop 프레임워크 및 메타데이터 지원 |
Spring-core.jar, AOP 연맹 선택사항:cglib, 커먼스 어트리뷰츠 |
Spring-context.jar |
애플리케이션 컨텍스트, 유효성 검증 프레임워크, 템를릿 지원 (벨로시티, 프리마커), 리모팅(jax-rpc, hessian, burlap), EJB 지원, 스케쥴링 |
Spring-core.jar 선택사항:벨로시티,프리마커,javamail, Ejb,jax-rpc,hessian, burlap,쿼츠 |
Spring-dao.jar |
Jdbc 및 dao 지원 , 트랜잭션 기반구조 |
Spring-core.jar 선택사항:spring-aop.jar, jta |
Spring-orm.jar |
하이버네이트, jdo, 아이바티스를 포함한 orm 프레임워크 지원 |
Spring-core.jar 선택사항:하이버네이트,jdo,아이바티스 |
Spring-web.jar |
웹 애플리케이션 컨텍스트 및 유틸리티, 멀티파트 파일 업로드지원 |
Spring-cotext.jar, 서블릿 선택사항:커먼스 파일업로드,cos |
Spring-webmvc.jar |
스프링 mvc 프레이워크 |
Spring-web.jar 선택사항:jsp,jstl,타일즈,itext, poi |
Spring.jar |
다른 jar 파일들을 포함한 스프링 프레임워크 전체 |
위의 모든 사항들을 포함 |
사실 나도 모르는 용어들이 많다 사용해본 것도 몇 개정도 있다.
앞으로 알아가면 재미(?)을 것 같다. ㅎㅎㅎㅎㅎ
------------------------------------------------------------------------------------------------------------------------
Spring은 로드존슨이 만든 오픈소스 프레임 워크이며, 그의 책인 Expert one-on-one : j2ee design and development에 처음 소개 되었다 한다. 어라...나 이책 봤는데..왜 몰랐지…
이 책에서 스프링의 원래 이름은 interface21이 었다.
스프링에 대한 감을 잡기 위한 설명은…
1.경량
크기와 부하의 측면에서 경량이고 1MB 크기의 jar파일로 배포된다. 그리고 스프링은 침입적이지 않다고 한다. 무슨말인지..쩝 스프링을 도입한 애플리케이션의 객체가 보통의 경우 스프링의 특정 클래스에 대한 의존성을 갖지 않는다는 의미라고 한다. 그냥 ejb에 비해 의존성이 없다는 얘기로 이해하고 넘어가야 겠다
2.제어역행
제어역행(IoC, Inversion of Control)이라는 기술을 통해 애플리케이션의 느슨한 결합을 도모한다.
이 말은 기본개념은 객체를 생성하거나 찾는 대신, 구현되는 방법을 기술하는 것이다. 컴포넌트와 서비스들을 코드에 직접 연결하지는 않지만, 설정 파일에서 어떤 컴포넌트가 어떤 서비스를 요구하는지를 기술한다. 컨테이너(이 경우, Spring 프레임웍, IOC 컨테이너)는 이 모든 것을 연결한다.
3.관점지향
관점지향 프로그래밍(AOP, Aspect-Oriented Programming)을 위한 풍부한 지원을 한다. 여기서 관점지향 프로그래밍이란 비즈니스 로직을 프로그램밍하게만 한다는 것이다. 트랜잭션과 시스템 감시같은 것은 관련 모듈을 이용하면 된다.
http://aopalliance.soureforge.net 참고하면 된다.
4.컨네이너
어플리케이션 객체의 생명주기와 설정을 포함하고 관리한다는 점에서 스프링은 일종의 컨테이너이고, 빈을 생성, 빈의 연관 설정등 할 수 있다고 한다.
5.프레임워크
스프링에서는 틔 파일내에 선언적으로 구성하여 애플리케이션 객체를 생성하며 어플리케이션 로직 개발은 개발자에게 맡기고 그 이외는 기능은 모듈로서 제공한다.
Spring 프레임웍을 구성하는 각 모듈(또는 컴포넌트)은 독립적이거나, 다른 모듈들과 함께 구현된다. 각 컴포넌트의 기능은 다음과 같다.
- 코어 컨테이너(core container): Spring 프레임웍의 핵심 기능을 제공한다. 코어 컨테이너의 주요 컴포넌트는 BeanFactory(Factory 패턴의 구현)이다. BeanFactory는 Inversion of Control (IOC) 패턴을 사용하여 애플리케이션의 설정 및 의존성 스팩을 실제 애플리케이션 코드에서 분리시킨다.
- Spring 컨텍스트(Spring context): Spring 프레임웍에 컨텍스트 정보를 제공하는 설정 파일이다. Spring 컨텍스트에는 JNDI, EJB, 국제화, 밸리데이션, 스케줄링 같은 엔터프라이즈 서비스들이 포함된다.
- Spring AOP 모듈(Spring AOP): 설정 관리 기능을 통해 aspect 지향 프로그래밍 기능을 Spring 프레임웍과 직접 통합시킨다. 따라서 Spring 프레임웍에서 관리되는 모든 객체에서 AOP가 가능하다. Spring AOP 모듈은 Spring 기반 애플리케이션에서 객체에 트랜잭션 관리 서비스를 제공한다. Spring AOP에서는 EJB 컴포넌트에 의존하지 않고도 선언적 트랜잭션 관리를 애플리케이션과 결합할 수 있다.
- Spring DAO: Spring JDBC DAO 추상 레이어는 다른 데이터베이스 벤더들의 예외 핸들링과 오류 메시지를 관리하는 중요한 예외 계층을 제공한다. 이 예외 계층은 오류 핸들링을 간소화하고, 예외 코드의 양도 줄여준다. Spring DAO의 JDBC 예외는 일반 DAO 예외 계층에 순응한다.
- Spring ORM: 프레임웍은 여러 ORM 프레임웍에 플러그인 되어, Object Relational 툴 (JDO, Hibernate, iBatis SQL Map)을 제공한다. 이 모든 것은 Spring의 일반 트랜잭션과 DAO 예외 계층에 순응한다.
- Spring Web module: 웹 컨텍스트 모듈은 애플리케이션 컨텍스트 모듈의 상단에 구현되어, 웹 기반 애플리케이션에 컨텍스트를 제공한다. Spring 프레임웍은 Jakarta Struts와의 통합을 지원한다. 웹 모듈은 다중 요청을 핸들링하고, 요청 매개변수를 도메인 객체로 바인딩하는 작업을 수월하게 한다.
- Spring MVC framework: MVC 프레임웍은 완전한 기능을 갖춘 MVC 구현이다. MVC 프레임웍은 전략 인터페이스를 통해 설정할 수 있으며, JSP, Velocity, Tiles, iText, POI 같은 다양한 뷰 기술을 허용한다.
Pasted from <http://www-128.ibm.com/developerworks/kr/library/wa-spring1/>
------------------------------------------------------------------------------------------------------------------------
먼저 Hello World 라는 예제를 한번 해본다.
GreetingService.java인 인터페이스
: 여기에서 인터페이스로 만들어서 구현하는 이유는 특별히 없다.
GreeringServiceImpl.java
: 위 인터페이스를 구현한 인사말을 출력하는 클래스이다.
여기서 주목할것은 setGreeting()가 있다는 것이다. 소스를 다 보게되면 setGreeting()이 누가 호출했는지 자세히 알아보는것이다 이것이 spring의 힘이 아닐까 한다.
applicationContext.xml
: 위 파일은 spring 컨테이너에게 클래스에 대한 정보와 설정방법을 알려준다.
<bean> </beam>의 내용은 아래의 코드와 같다.
GreetingServiceImpl greetingService = new GreetingServiceImpl();
greetingService.setGreeting("Buenos Dias!");
HelloApp.java 메인 클래스
: BeanFactory 클래스가 스프링 컨테이너이다.
위 그림은 출력물이다.
아주 간단한 예제 프로그램이다. 내 생각은 spring의 힘은 ejb에서 lookup으로 찾아서 실행하는 것이 아니라
Xml를 이용하여 빈들을 실행하고 제어 , 컨트롤을 하는 것이다. 이것이 역행제어를 말하는 것 같다.
Ejb보다는 쉽게(?) 할 수 있고 Ejb에서 트랜잭션을 보장 해주는 것을 spring에서도 해주고 비즈니스 로직만 프로그래밍하면 그 이외 기능은 기타의 모듈로서 해결할 수 있을 거라 생각한다.
그럼 앞으로 알아야 할 것은 빈들을 어떻게 컨트롤하는가 와 spring과 다른 기능의 모듈과 어떻게 연결하는가만
배우면 될 것 같다.
------------------------------------------------------------------------------------------------------------------------
Spring 은 EJB에서 구현되는 것을 좀더 쉽게 구현 할 수 있다.(spring이 다른 것과 결합하여) 제어 역행이라는 개념을 이용하여 인터페이스를 통해 서로 협업하는 간단한 자바 객체들(빈)을 사용해 엔터프라이즈 애플리케이션을 개발할 수 있다. 이들 빈은 런타임에 spring 컨테이너에 의해 함께 묶인다.
결국 spring은 적은 비용으로 느슨하게 결합된 코드를 유지할 수 있게 해준다.
또 spring은 제어 역행의 상부에 AOP를 제공한다. 이 AOP는 애플리케이션 전체에 걸쳐 흩어져 있는 코드를 한곳(aspect)에 위치하도록 해 준다. 런타임에 빈들이 함께 묶이면 애스펙트들이 그에 엮임으로써, 빈은 새로운 작동을 하게 된다.
엔터프라이즈 개발을 지원하다는 명목하에, spring은 다양한 퍼시스턴스 기술과 통합할 수 있다. JDBC, 하이버네이트, JDO, 등 어떤 것을 사용하든, 스프링의 DAO 프레임워크는 각 퍼시스턴스 프레임워크에 있어서 에러 처리와 자원관리를 위한 일관된 모델을 제공함으로써 개발 편의성을 도모한다.
퍼시스턴스 기술과의 동합을 보와하는것은 spring의 트랜잭션 지원 기능이다. EJB를 사용하지 않고도 AOP를 통해 애플리케이션에 선언적으로 트랜잭션 지원을 추가할수 있다.또한 분산 트랜잭션을 위한 JTA 트랜잭션과의 통합을 포함하여 다양한 트랜잭션을 지원한다.
Spring은 여러지원 가능한 기능으로 메일,EJB,웹 서비스, JNDI등 다양한 J2EE 서비스와의 통합기능도 제공한다. 또 제어역행을 통해 이들 서비스를 쉽게 설정하며, 애플리케이션 객체에 단순한 인터페이스를 제공한다.
Spring은 프리젠테이션 계층을 우해 다중 뷰기술을 지원한다. 벨로시티나 JSP와 같은 웹 프리젠테이션 기술뿐만 아니라 마이크로소프트 엑셀, PDF 파일을 생성할 수 있다. 또 프리젠테이션의 상부에는 내장된 MVC 프레임워크가 존재하고 스트럿츠나 웹워크(webwork)와 같은 다른 웹프레임워크의 대안을 제시하며, spring의 모든 서비스와 좀더 쉽게 통합 될 수 있다.
내 생각을 덧붙이자면,
Spring은 CBD로 개발된 컴포넌트인 것 같다. 이 spring에 트랜잭션을 지원하기 위해 AOP 컴포넌트를 붙이고, 데이터 베이스와의 연결은 JDBC, 하이버네이트, JDO 등의 컴포넌트로 사용하면 되고, 프리젠테이션은 태피스트리나 벨로시티 컴포넌트를 이용하면 될 것 같다.
즉, 내가 구현 가능한 기능이 있으면 가져다가 spring에 붙이고 사용하면 가능하다는 뜻이다.
근데 그러기 위해서는 이 많은 컴포넌트를 알아야 하고 spring에 붙이기 위해서는 붙이는 방법 등을 학습해야 한다. 알고 나면 쉬운 것이지만 처음부터 알기란 매우 힘들 것 같다.
만약 이것을 학습하고 있는데 또 다른 좋은 무엇가가 나타나면 어떻게 되는 것일까….쩝.
------------------------------------------------------------------------------------------------------------------------
Spring에서는 어떤 컴포넌트가 다른 컴포넌트와의 연관관계를 관리할 책임이 없다.
즉 어떤 컴포넌트에서 다른 컴포넌트를 호출하는 것을 말하는 것 같다.
그 대신, 컨테이너에 의해 컴포넌트 간의 협업을 위한 참조가 주어진다.
이렇듯 애플리케이션 컴포넌트 간의 연관관계를 만드는 행위를 묶기(wiring)라고 하며, 이번 장에서 다룰 주제이다.
Spring의 묶기는 단순히 두 객체간의 연관관계를 성립시키는 작업 이상의 것이다.
또한 spring을 사용해 빈의 특성을 설정하는 방법, 별도 파일로 배치(deployment) 설정을 외부화 하는 방법, 빈의 생명주기를 관리하는 방법 등을 알게 된다.
비즈니스를 묶는 것과 관련된 내용이 spring의 핵심이 아닐까 한다.
Spring 프레임워크를 사용하기 위해 빈을 설정 할 때에는, 항상 spring 컨테이너에 어떤 지시사항을 기술해야 한다. 따라서 컨테이너를 알면, 빈이 어떻게 관리되는지를 이해하는데 도움이 되기때문에 컨테이너를 알아보자.
컨테이너는 spring 프레임워크의 핵심이다. Spring 컨테이너는 제어역행(IOC)을 사용해 애플리케이션을 구성하는 컴포넌트를 관리한다. 여기서 협력하는 컴포넌트간의 연관관계를 생성하는 것을 포함한다. 이는 객체는 좀더 명확하게 이행 할 수 있고, 재사용이 가능해지며, 단위 테스트가 쉬워진다고 한다.
Spring은 기본 컨테이너 2개
org.springframework.beans.factory.BeanFactory 인터네이스로 정의된 빈팩토리
: 기본적인 의존성 주입 지원
org.springframework.context.ApplicationContext 인터네이스로 정의되는 애플리케이션 컨텍스트
: 프로퍼티 파일의 텍스트 메시지 해석, 애플리케이션 프레임워크 서비스 제공
그 외에 다수 존재한다. 그리고 빈팩토리와 애플리케이션 컨텍스트를 모두 컨테이너라 용어 한다.
1. 빈 팩토리
- 빈을 생성하고 분배하는 책임을 지는 클래스이고 팩토리 디자인 패턴을 구현한 것이다.
( 팩토리 패턴은 객체를 생성하고 분배하는 패턴이고 자세한것은 스스로…^^)
빈팩토리는 애플리케이션내의 많은 객체에 대해 알고 있기 때문에 객체들을 인스턴스화할때 협업하는 객체 간의 연관관계를 생성시키는 것이 가능하다.(이 말은 객체들간의 관계를 정의하는 무엇가가 필요하는 말이다.)
이렇게 하는 이유는 빈 자신과 빈의 클라이언트로부터 설정이라는 작업이 없다. 그로 인하여 빈팩토리가 객체를 분배하는 시점에서는 그 객체들이 완전히 설정된 상태이며, 협업하는 객체들끼리 인식하고 있고 곧바로 사용할 수 있는 상태인 것이다. 또 빈팩토리는 커스텀 초기화 메소드와 소멸 메소드를 호출함으로써 빈의 생명주기에 개입할 수 있다.
Spring의 다양한 BeanFactory 구현 클래스 중 가장 유용한 것은 org.springframework.beans.factory.xml.XmlBeanFactory 로서 xml 파일에 기술되어 있는 정의를 바탕으로 빈을 로딩한다.
BeanFactory factory = new XmlBeanFactory(new FileSystemResource("beans.xml"));
위 코드는 빈 팩토리에게 XML 파일로부터 빈에 대한 정의를 읽어오라고 알려준다. 그러나 빈 팩토리가 빈을 인스턴스화하는 것은 아니다. 빈은 빈 팩토리에 "늦게 로딩"(lazy loading)되는데, 이 말은 빈 팩토리가 빈의 정의(빈과 그 특성에 대한 설명)는 즉시 로딩하는 반면, 빈 자체가 필요하기 되기 전까지는 인스턴스화하지 않는다는 의미다.
빈 팩토리로부터 빈을 언어오기 위해서는 아래와 같다.
MyBean myBean = (MyBean) factory.getBean("myBean");
getBean(); 이 호출되면, 팩토리는 의존성 주입을 이용해 빈을 인스턴스화하고 빈의 특성(빈의 set 메소드)을 설정하기 시작한다. 이렇게 해서 스프링컨테이너 안에서의 빈의 일생이 시작된다.
2. 애플리케이션 컨텍스트
표면적으로는 ApplicationContext는 BeanFactory와 상당히 비슷하다. 둘 다 빈을 로딩하고 빈들을 묶어주며, 요청에 따라 빈을 분배한다. 즉, ApplicationContext 인터페이스가 BeanFactory 인터페이스를 확장한 것이다. 또한 getBean() 메소드를 사용해 ApplicationContext 로부터 빈을 얻을 수 있다.
차이점은 빈 팩토리는 모든 빈을 늦게 로딩(lazy loading)하는데, 애플리케이션 컨텍스트는 컨텍스트를 시작시킬때 모든 싱클톤 빈을 미리 로딩(preloading)함으로써 그 빈이 필요할때 즉시 사용될수 있도록 보장해 준다. 즉, 빈이 생성되기를 기다릴 필요가 없다는 것이다.
하지만 모든 객체를 싱클톤으로 생성해 놓는다지만 객체가 많아지면 무거울꺼라는 생각이 든다. 해보지 않아서 추측임.
(싱클톤은 디자인패턴의 일종이다 스스로…. ^^)
ApplicationContext는 다음과 같은 추가기능을 제공한다.
-.국제화(I18N) 지원을 포함해 텍스트 메시지를 해석하는 수단 제공
-.이미지 등과 같은 자원을 로딩하는 범용적인 방법 제공
-.리스너로 등록되어있는 빈에 이벤트를 발생할 수 있음.
BeanFactory는 자원이 제약이 따르는 이동통신기기 같은 상황이 아니면 ApplicationContext를 사용한다고 한다.
ApplicationContext의 다양한 구현 클래스 중 일반적인 것
-.ClasspathXmlApplicationContext : 클래스 패스에 있는 XML 파일로부터 컨텍스트 정의를 로딩하며, 컨텍스트 정의를 클래스 패스에 있는 자원으로 취급한다.
-.FileSystemXmlApplicationContext : 파일 시스템에 있는 XML 파일로부터 컨텍스트 정의를 로딩한다.
-.XmlWebApplicationContext : 웹 애플리케이션에 포함되어있는 XML 파일로부터 컨텍스트 정의를 로딩한다.
예) ApplicationContext context = new FileSystemXmlApplicationContext("c:/foo.xml");
: 특정한 위치에서 foo.xml을 찾음.
ApplicationContext context = new ClassPathXmlApplicationContext("c:/foo.xml");
: 클래스 패스에 있는 foo.xml를 찾음.
------------------------------------------------------------------------------------------------------------------------
1. 빈의 일생
전통적인 자바 애플리케이션에서의 빈의 생명주기는 new 키워드를 통해 인스턴스화 되거나 역직렬화(deserializatino) 되며, 사용할 수 있는 상태가 된다.
Spring이 빈의 생성방법을 커스터마이징 할 수 있는 기회를 제공하기 때문에 spring 컨테이너에서의 빈의 생명주기를 이해하는 것이 중요하다.
다음 그림은 spring의 애플리케이션 컨텍스트 안에서의 빈의 생명주기이다.
빈의 생성
a. 컨테이너는 빈의 정의(빈에 대한 정보를 어딘가에 있겠죠)를 알아낸 다음, 빈을 인스턴스화 한다.
b. 의존성 주입을 이용해 빈의 정의에 지정되어 있는 모든 특성에 값을 채운다.
c. 빈이 BeanNameAware 인터페이스를 구현한다면, 팩토리는 빈의 ID를 setBeanName()에 전달하여 호출한다.
d. 빈이 BeanFactoryAware 인터페이스를 구현한다면, 팩토리는 자신의 인스턴스를 setBeanFactory()에 전달하여 호출한다.
e. 빈이 ApplicationContextAware 인터페이스를 구현했다면 setApplicationContext() 메소드가 호출된다.
f. 빈과 연관되어 있는 하나 이상의 BeanPostProcessor가 존재한다면, 각각의 모든 postProcessBeforeInitialization() 메소드가 호출된다.
g. 빈이 재정되어 있는 init-method가 있으면 호출된다.
h. 마지막으로 빈과 연관되어 있는 하나 이상의 BeanPostProcessor가 존재하다면, 모든 postProcessAfterInitialization()메소드가 호출된다.
i. 빈은 애플리케이션에 의해 즉시 사용 될 수 있는 상태이며, 더 이상 필요하지 않을때까지 빈 팩토리 안에 남아 있게 된다.
빈의 소멸
a. 빈이 DisposableBean 인터페이스를 구현하고 있다면, destroy() 메소드가 호출된다.
b. 커스텀 destroy-method가 지정되어 있다면 그 메소드가 호출된다.
------------------------------------------------------------------------------------------------------------------------
Spring 컨테이너 안에서 빈들(컴포넌트)끼리 사용하거나 사용되어지는 것을 묶기라고 한다. 빈을 묶을 때 에는 어떤 빈들이 사용 될 지와 그 빈들을 묶기 위해서 어떻게 의존성 주입을 사용할지를 컨테이너에게 알려줘야 한다. 이때 컨테이너에게 알려 줄 때는 xml를 이용하여 알려준다.
간단한 샘플을 보면서 진행해 보자
여러분이 스프링 트레이닝 주식회사라는 기술교육단체와 계약된 상태라고 가정하자 스프링 트레이닝사는 수강생이 온라인으로 교과 과정을 등록할 수 있도록 하는 애플리케이션을 만들어 달라고 요청했다.
먼저 애플리케이션의 서비스 계층부터 만들어 보자
아래의 그림은 스프링 트레이닝 애플리케이션에서 서비스 계층을 구성하는 계층을 보여준다.
서비스 계층에는 수강생 서비스(Student Service)와 교과과정 서비스 (Course Service) 라는 두 개의 서비스 컴포넌트가 있다.
-.수강생 서비스(Student Service) : 수강생과 관련된 모든 것을 처리
-.교과과정 서비스 (Course Service) : 교과과정과 관련된 모든 기능을 처리
지금은 어떻게 구현되어 있는지 코드를 구현 부분만 살펴보고 나중에
완전한 소스를 알아보자 궁금하면 www.acornpub.co.kr 에서 소스를 다운 받아 확인해 보세요
Student Service.java
CourseService.java
StudentServiceImpl
StudentServiceImpl은 학생을 찾고, 생성하고 수강하는 작업등을 StudentDao에 위임하여 StudentDao는 데이터베이스와 상호작용하여 처리한다. StudentDao 객체의 실제 구현내용은 나중에 알아보기로 한다.
그리고 StudentDao를 구현한 클래스는 StudentDaoImpl 클래스이다.
StudentDaoImpl 는 위의 소스에서 본 것과 같이 생성자와 setStudentDao() 메소드를 이용하여 StudentDao에 대한 참조를 얻을 수 있다.
CourseServiceImpl.java
CourseServiceImpl은 생성자를 통해 CourseDao의 참조를 할 수 있다. enrollStudentInCourse() 메소드는 수강생을 교과과정에 추가하기 전에 enforcePrerequisites()를 먼저 호출한다. 만약 수강생이 선수과목을 이수하지 않았다면 enforcePrerequisites()는 CourseException을 던질 것이며, 이를 다시 enrollStudentInCourse()가 던질 것이다.
enforcePrerequisites()는 StudentService의 참조를 사용해 수강생이 수료한 모든 과목을 얻어온다. 이는 선수과목이라는 비즈니스 요구사항을 충목시키기 위해 CourseDao 뿐만 아니라, CourseServiceImpl과도 참조한다는 의미다.
CourseServiceImpl은 CourseDao를 생성자를 통해 얻는 것과 달리, StudentService의 참조는 setStudentService() 메소드를 통해 얻는다. 이런 이유는 courseDao 를 이용하여 과목을 찾는데 사용되기 되고, 속성 값을 설정하지 않으면 인스턴스를 생성할수 없기때문에 private CourseDao courseDao 로 속성을 설정했다.
다음은 xml로 빈을 묶는 것에 대해 알아 보자