2020. 12. 11. 10:33ㆍ교육과정/KOSMO
키워드 : 스프링 프로젝트 만들기 / DI / 빈 생성 / 빈의 scope에 따른 객체 생성 / private 변수에 setter로 값 지정 / private 변수에 생성자로 값 지정 / p 네임스페이스 (pvalue)로 값 지정 /
****
0. 프레임워크란?
※ 애플리케이션들의 최소한의 공통점들을 찾아 하부 구조를 제공함으로써
개발자들로 하여금 시스템 하부 구조를 구현하는데 들어가는 노려을 절감하게 하는 것
(1) 프레임워크의 장점
- 비기능적인 요소들을 초기 개발 단계마다 구현해야 하는 불합리함을 극복해준다.
- 기능적인(Functional) 요구사항에 집중할 수 있도록 해준다.
- 디자인 패턴과 마찬가지로 반복적으로 발견되는 문제를 해결하기 위한 Solution을 제공한다.
디자인패턴 | 애플리케이션을 설계할 때 필요한 구조적인 가이드라인이 되어 줄 수는 있지만, 구체적으로 구현된 기반코드를 제공하지 않는다. |
클래스 라이브러리 | 개발자가 만든 클래스에서 직접 호출하여 사용하므로, 실행의 흐름에 대한 제어를 개발자의 코드가 관장하고 있다. |
프레임워크 | 디자인 패턴과 함께 패턴이 적용된 기반 클래스 라이브러리를 제공함으로써, 프레임워크를 사용하는 구조적인 틀과 구현코드를 함께 제공한다. 프레임워크에서 개발자가 만든 클래스를 호출하므로, 실행의 흐름에 대한 제어를 프레임워크가 담당한다. |
디자인패턴 + 클래스 라이브러리 → 프레임워크
(2) 스프링 프레임워크
: 자바 엔터프라이즈 개발을 편하게 도와주는 오픈소스 경량급 애플리케이션 프레임워크
- 애플리케이션 전 영역을 관통하는 일관된 프로그래밍 모델과 핵심 기술을 바탕으로 각 분야의 특정에 맞는 기능을 제공
- 스프링은 단순한 개발 툴과 기본적인 개발 환경으로, 필요하게 등장하던 프레임워크나 서버환경에 의존적인 부분을 제거
- 스프링의 기본설정과 적용기술만 잘 선택하고 준비해두면, 개발할 때 스프링과 관련된 코드나 API에 대해 거의 신경쓸 일이 없다.
(3) 스프링 프레임워크의 발전
1.X | - EJB의 대안으로 소개 - IoC (DI), AOP, XML 기반의 빈 정의 (IoC : Inversion of Control - 역행제어) |
2.X | - 스프링 시큐리티 - DI와 MVC를 Annotation 방식 설정 |
3.X | - RESTful 프레임워크 사용 |
4.X | - 웹 소켓 |
5.X | - 리액티브 프로그래밍 |
(4) 스프링 주요 프로젝트 및 라이브러리
모듈 설명
spring-beans 스프링 컨테이너를 이용해서 객체를 생성하는 기본 기능 제공
spring-context 객체 생성, 라이프 사이클 처리, 스키마 확장 등의 기능을 제공
spring-aop AOP 기능을 제공
spring-web REST Client, 데이터 변환 처리, 서블릿 필터, 파일 업로드 지원 등 웹 개발에 필요한 기반 기능 제공
spring-webmvc 스프링 기반의 MVC 프레임워크, 웹 애플리케이션을 개발하는데 필요한 Controller, View 구현을 제공
spring-websocket 스프링 MVC에서 웹 소켓 연동을 지원
spring-oxm XML과 자바 객체 간의 매핑을 처리하기 위한 API 제공
spring-tx 트랜잭션 처리를 위한 추상 레이어를 제공
spring-jdbc JDBC 프로그래밍을 보다 쉽게 할 수 있는 템플릿을 제공
spring-orm hibernater, JPA, MyBatis 등과의 연동을 지원
spring-jms JMS 서버와 메시지를 쉽게 주고 받을 수 있도록 하기 위한 템플릿, 애노테이션 등을 제공
spring-context-support 스케쥴링, 메일 발송, 캐시 연동, 벨로시티 등 부가 기능을 제공
(5) DI (Dependency Injection)
: xml 에서 객체 생성을 담당하여 메모리에 떠 있는 객체를 가져와서 사용하기 때문에 의존이라 함
컴포넌트 간의 연관이 적고, 코드가 단순하다.
객체 레퍼런스를 컨테이너로부터 주입 받아서 실행시에, 동적으로 의존 관계가 생성된다.
(참고)
DL (Dependency Lookup) 의존성 검색 | 저장소에 저장되어 있는 Bean에 접근하기 위해 컨테이너가 제공하는 API를 사용하여 Bean을 Lookup 하는 것 |
DI (Dependency Injection) 의존성 주입 | 각 클래스 간의 의존관계를 빈 설정(Bean Definition) 정보를 바탕으로 컨테이너가 자동으로 연결해주는 것 |
◆ IoC (Inversion of Control - 역행 제어)
: 객체의 생성, 생명주의 관리까지 모든 객체의 제어권이 바뀌었다는 의미의 디자인 패턴)
◆ IoC 컨테이너
: 스프링 프레임워크도 객체에 대한 생성 및 생명주기를 관리할 수 있는 IoC 컨테이너 기능을 제공한다.
: 객체의 생성을 책임지고, 의존성을 관리한다.
: POJO의 생성, 초기화, 서비스, 소멸에 대한 권한을 가진다.
: 개발자들이 직접 POJO를 생성할 수 있지만 컨테이너에게 맡긴다.
◆ IoC 분류
(6) 관련 용어
빈 (Bean) | - 스프링이 IoC 방식으로 관리하는 객체라는 뜻 - 스프링이 직접 생성과 제어를 담당하는 객체를 Bean이라고 부름 |
빈 팩토리 (Bean Factory) | - 스프링의 IoC를 담당하는 핵심 컨테이너를 가리킴 - Bean을 등록, 생성, 조회, 반환하는 기능을 담당함 - 이 BeanFactory를 바로 사용하지 않고, 이를 확장한 ApplicationContext를 주로 이용함 |
애플리케이션 컨텍스트 (ApplicationContext) |
- BeanFactory를 확장한 IoC 컨테이너 - Bean을 등록하고 관리하는 기능은 BeanFactory와 동일하지만, 스프링이 제공하는 각종 부가 서비스를 추가로 제공함 - 스프링에서는 ApplicationContext를 BeanFactory보다 더 많이 사용함 |
(7) 빈 설정 방법
XML 기반 설정 방식 | - 스프링 1.0 - xml 파일에 <bean> 요소로 빈을 정의한다. - <constructor-arg>나 <property> 요소로 의존성을 주입한다. |
Annotation 기반 설정 방식 | - 스프링 2.5 - @Component 같은 애노테이션이 부여된 클래스를 탐색하여 DI 컨테이너에 빈을 등록한다. |
Java 기반 설정 방식 | - 스프링 3.0 - 자바 클래스에 @Configuration을, 메소드에 @Bean 애노테이션을 사용해 빈을 정의한다. |
◆ 의존성 주입 애노테이션 - 스프링 설정 파일에 <context:component-scan> 필요함
@Autowired | - 스프링 제공 - 생성자, 메소드, 변수 위에 모두 사용 가능하지만, 주로 변수 위에 설정하여 해당 타입의 객체를 자동으로 할당 |
@Qualifier | - 스프링 제공 - 특정 객체의 이름으로 의존성을 주입할 때 사용 |
@Resource | - javax.annotation.Resource - @Autowired와 @Qualifier 기능을 결합한 역할 |
@Inject | - javax.inject.Inject - @Autowired와 동일한 기능 |
@Service | - XXXServiceImpl - 비니지스 로직을 처리하는 Service 클래스 |
@Repository | - XXXDAO - 데이터베이스 연동을 처리하는 DAO 클래스 |
@Controller | - XXXController - 사용자 요청을 제어하는 Controller 클래스 |
1. 스프링 프로젝트 시작하기 (DI 방식 사용)
(1) 프로젝트명 우클릭
- Configure
- Convert To Maven
- Finish
- xml 파일이 자동생성되면서 Java Project인 동시에 Maven Project가 됨
→ 라이브러리 import를 손쉽게 하기 위하여 Maven Project로 만드는 것 (자동으로 다운 받고 연결해줌)
※ Maven (goddaehee.tistory.com/199 참고)
→ 처음부터 Maven Project로 생성하면 구조가 다르기 떄문에 기존 Java Project에서 변경해준다.
(매번 수업마다 라이브러리 파일을 압축파일에서 함께 제공받았지만,
본래는 각 사이트마다 방문하여 라이브러리를 다운받았어야 함)
→ 자바용 프로젝트관리도구로 Apache Ant의 대안으로 만들어졌으며,
프로젝트의 전체적인 라이프 사이클을 관리하는 도구이다.
→ 필요한 라이브러리를 특정 문서 (pom.xml)에 정의해 놓으면 내가 사용할 라이브러리 뿐만 아니라,
해당 라이브러리가 작동하는데 필요한 다른 라이브러리들까지 관리하여 네트워크를 통해서
자동으로 다운받아 준다.
→ POM (Project Object Model) 프로젝트 객체 모델
: POM은 pom.xml 파일을 말하며, Maven을 이용하는 프로젝트의 root에 존재하는 xml 파일이다.
(하나의 자바 프로젝트에 빌드 툴을 maven으로 설정하면,
프로젝트 최상위 디렉토리에 "pom.xml"이라는 파일이 생성된다.
Maven의 기능을 이용하기 위해서 POM이 사용된다.
파일은 프로젝트마다 1개이며, pom.xml만 보면 프로젝트의 모든 설정, 의존성 등을 알 수 있다.
(2) 프로젝트명 우클릭
- Spring
- add spring nature
- J 표시가 S로 바뀜
(3) maven repository 검색 후 mvnrepository.com/ 접속
- spring-context 검색
(4) 첫번째로 나오는 spring-context 클릭
- 다운로드 수 많은 걸로 적당히 골라서 클릭 (5.2.11 RELEASE 선택함)
(5) MAVEN 탭의 내용 복사
: Maven이나 Gradle( name-value 형식) 방식을 제일 많이 사용한다.
(6) pom.xml 파일에서 </build> 태그 바로 아래에 <dependency>태그를 만들고
그 안에 복사해온 스크립트를 붙여넣는다.
</build>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.11.RELEASE</version>
</dependency>
</dependencies>
</project>
(7) 상단 메뉴
- Window
- Preferences
- enc 검색
- 체크 설정 및 UTP-8로 언어설정하기
(8) 맨 첫라인에 빨간줄 있을 경우에는 라이브러리 다운이 정상적으로 이루어지지 않았을 수 있다.
이 경우 repository 폴더 내의 파일들 삭제 후 라이브러리를 다시 다운받아야 한다.
※ 다운 받은 라이브러리의 경로
(9) src에 "ex1_xml1" 패키지를 만든다.
(10) "MessageBean" 이란 인터페이스를 만든다.
(11) 인터페이스에 인자 하나를 받는 sayHello( ) 메소드를 선언한다.
public interface MessageBean {
void sayHello(String name);
}
(12) MessageBean 인터페이스를 상속하는
클래스 MessageBeanEnImpl.java와 MessageBeanKoImpl.java 를 만들고 내용을 작성한다.
→ 각 클래스의 객체를 만들고 sayHello( ) 메소드 호출 시 해당 언어로 출력하게 된다.
public class MessageBeanEnImpl implements MessageBean {
public void sayHello(String name) {
System.out.println(name + ", Good morning");
}
}
public class MessageBeanKoImpl implements MessageBean {
public void sayHello(String name) {
System.out.println(", 안녕하세요, " + name);
}
}
(13) 메인함수를 포함하여 MainApp.java 파일 생성 후 DI 형식으로 객체 가져오기
(참고) 기존 자바 형식(POJO)
: MainApp.java 파일 내에서 new 키워드로 객체를 생성하여 사용하며
MainApp.java와 MessageBean.java 간 연관이 크다.
MessageBean bean = new MessageBeanEnImpl();
bean.sayHello("hong");
MessageBean bean1 = new MessageBeanKoImpl();
bean1.sayHello("홍");
ⓛ src 우클릭
- new
- other
- Spring
- Spring Bean Configuration File 선택
- Next
② applicationContext.xml 파일 생성
③ applicationContext.xml 에서 빈을 생성해준다.
<bean id='ko' class="ex1_xml1.MessageBeanKoImpl"></bean>
<bean id='en' class="ex1_xml1.MessageBeanEnImpl"></bean>
④ MainApp.java 에서 xml 파일 사용을 위한 ApplicationContext 객체 context를 생성한다.
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml1/applicationContext.xml");
⑤ context객체를 사용하여 2가지 방법으로 xml에 만든 빈(객체)을 가져올 수 있다.
◆ DI : xml 에서 객체 생성을 담당하여 메모리에 떠 있는 빈(객체)을 가져와서 사용하기 때문에 의존이라 하는 것
// (1) 객체 가져온 뒤 형 변환시키기
MessageBean bean = (MessageBean)context.getBean("ko");
bean.sayHello("홍길동");
// (2) 객체를 가져올 때 형 변환 함께 시키기
MessageBean bean2 = context.getBean("en", MessageBean.class);
bean2.sayHello("gilja");
⑥ en과 ko 파일에서 생성자 함수를 사용하여 객체가 언제 생성되어 메모리에 올라가는지 확인할 수 있다.
(생성자 함수에 sysout 작성 후 MainApp.java에서 실행결과 확인)
< MessageBeanEnImpl.java >
public MessageBeanEnImpl() {
super();
System.out.println("MessageBeanEnImpl 생성됨");
}
< MessageBeanKoImpl.java >
public MessageBeanKoImpl() {
super();
System.out.println("MessageBeanKoImple 생성됨");
}
< MainApp.java >
public static void main(String[] args) {
System.out.println("시작");
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml1/applicationContext.xml");
MessageBean bean = (MessageBean)context.getBean("ko");
bean.sayHello("홍길동");
MessageBean bean2 = context.getBean("en", MessageBean.class);
bean2.sayHello("gilja");
(실행 결과)
: 메인함수를 실행한 뒤 xml을 읽을 때 각각의 객체들을 모두 생성하고
그 후에 sayHello( ) 메소드들이 수행됨을 알 수 있다.
시작
MessageBeanEnImpl 생성됨
MessageBeanKoImple 생성됨
안녕하세요, 홍길동
gilja, Good morning
⑦ ko의 객체를 2번 가져올 때 객체 생성 내역 확인하기
MessageBean bean = (MessageBean)context.getBean("ko");
bean.sayHello("홍길동");
MessageBean bean1 = (MessageBean)context.getBean("ko");
bean1.sayHello("맹길동");
MessageBean bean2 = context.getBean("en", MessageBean.class);
bean2.sayHello("gilja");
(실행 결과)
: 메인함수를 실행한 뒤 xml을 읽을 때 각각의 객체들을 1번만 생성하고 함수 호출시 사용한다.
즉, ko 객체는 2번 가져왔지만 실제 객체의 생성은 1번만 되어 bean에서 쓰인 뒤 bean1에서 재사용되었다.
시작
MessageBeanKoImple 생성됨
MessageBeanEnImpl 생성됨
안녕하세요, 홍길동
안녕하세요, 맹길동
gilja, Good morning
⑧ scope를 지정하여 객체 생성을 조절할 수 있다.
: scope는 지정하지 않을 경우 기본이 singleton으로, xml을 읽는 순간에 빈을 생성한다.
: scope를 prototype으로 지정할 경우, xml을 읽는 순간에 빈을 생성하지 않고
getBean( ) 메소드가 호출될 때 객채를 생성하므로 메소드 호출 횟수만큼 객체가 여러개 만들어진다.
< applicationContext.xml >
<bean id='ko' class="ex1_xml1.MessageBeanKoImpl" scope='prototype'></bean>
<bean id='en' class="ex1_xml1.MessageBeanEnImpl" scope='singleton'></bean>
< MainApp.java >
public static void main(String[] args) {
System.out.println("시작");
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml1/applicationContext.xml");
System.out.println("시작2");
MessageBean bean = (MessageBean)context.getBean("ko");
bean.sayHello("홍길동");
MessageBean bean1 = (MessageBean)context.getBean("ko");
bean1.sayHello("맹길동");
MessageBean bean2 = context.getBean("en", MessageBean.class);
bean2.sayHello("gilja");
(실행 결과)
: 메인함수를 실행한 뒤 xml을 읽을 때 scope가 singleton인 en 객체만 생성한다.
scope가 prototype인 ko 객체는 getBean( ) 메소드가 호출될 때마다 객체를 생성됨을 확인할 수 있다.
시작
MessageBeanEnImpl 생성됨
시작2
MessageBeanKoImple 생성됨
안녕하세요, 홍길동
MessageBeanKoImple 생성됨
안녕하세요, 맹길동
gilja, Good morning
< MessageBean.java 전체 소스 코드 >
package ex1_xml1;
public interface MessageBean {
void sayHello(String name);
}
< MessageBeanEnImpl.java 전체 소스 코드 >
package ex1_xml1;
public class MessageBeanEnImpl implements MessageBean {
// 객체 생성 여부 확인을 위해 생성자 함수 사용
public MessageBeanEnImpl() {
super();
System.out.println("MessageBeanEnImpl 생성됨");
}
public void sayHello(String name) {
System.out.println(name + ", Good morning");
}
}
< MessageBeanKoImpl.java 전체 소스 코드 >
package ex1_xml1;
public class MessageBeanKoImpl implements MessageBean {
public MessageBeanKoImpl() {
super();
System.out.println("MessageBeanKoImple 생성됨");
}
public void sayHello(String name) {
System.out.println("안녕하세요, " + name);
}
}
< MainApp.java 전체 소스 코드 >
package ex1_xml1;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
// 0. POJO - 기존 자바 형식 : 매번 개발자가 객체 생성을 해줌
/* MessageBean bean = new MessageBeanEnImpl();
bean.sayHello("hong");
MessageBean bean1 = new MessageBeanKoImpl();
bean1.sayHello("홍"); */
// 1. DI : xml 에서 객체 생성을 담당하여 메모리에 떠 있는 객체를 가져와서 사용하기 때문에 의존이라 하는 것
System.out.println("시작");
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml1/applicationContext.xml");
// -> 이 때 xml 내에 작성된 빈 객체를 생성한다.
// (1) 객체 가져온 뒤 형 변환시키기
/* MessageBean bean = (MessageBean)context.getBean("ko");
bean.sayHello("홍길동");
// (2) 객체를 가져올 때 형 변환 함께 시키기
MessageBean bean2 = context.getBean("en", MessageBean.class);
bean2.sayHello("gilja"); */
// 객체가 언제 만들어지는지 확인하기
/* MessageBean bean = (MessageBean)context.getBean("ko");
bean.sayHello("홍길동");
MessageBean bean1 = (MessageBean)context.getBean("ko");
bean1.sayHello("맹길동");
MessageBean bean2 = context.getBean("en", MessageBean.class);
bean2.sayHello("gilja"); */
// -> ko 객체를 1번만 만들어서 bean과 bean1에서도 재사용한 것임
// scope 비교 (singleton과 prototype)
System.out.println("시작2");
MessageBean bean = (MessageBean)context.getBean("ko");
bean.sayHello("홍길동");
MessageBean bean1 = (MessageBean)context.getBean("ko");
bean1.sayHello("맹길동");
MessageBean bean2 = context.getBean("en", MessageBean.class);
bean2.sayHello("gilja");
// scope는 기본이 singleton, xml 읽는 순간에 빈 생성
// prototype은 xml을 읽는 순간에 빈을 생성하지 않고 getBean할때마다 생성하여 getBean 횟수만큼 객체가 만들어짐
}
}
< applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- DI(의존주입:dependency injection -->
<!-- 빈 생성 (scope는 기본이 singleton, xml 읽는 순간에 빈 생성)(prototype은 xml을 읽는 순간에 빈을 생성하지 않고 getBean할때마다 생성하여 getBean 횟수만큼 객체가 만들어짐 -->
<bean id='ko' class="ex1_xml1.MessageBeanKoImpl" scope='prototype'></bean>
<bean id='en' class="ex1_xml1.MessageBeanEnImpl" scope='singleton'></bean>
</beans>
2. DI방식에서 기본값 지정하기(value 지정) + 참조형 지정하기 (ref 지정)
(1) 기본값 지정하기 (value 지정) - setter 호출
① ex1_xml2_ref 패키지 생성
- MemberBean.java 클래스 생성
- 접근지정자를 private으로 하여 변수 선언
- output( ) 메소드와 기본생성자 만들기 (객체가 언제 생성되는지 확인하기 위함)
public class MemberBean {
private String name;
private int age;
private String message;
public void output() {
System.out.println(name + "[" + age + "]" + message);
}
public MemberBean() {
System.out.println("MemberBean 기본생성자");
}
② applicationContext.xml 파일 생성 후 빈 생성
<bean id='member' class="ex1_xml2_ref.MemberBean"></bean>
③ private인 변수를 사용하기 위하여 MemberBean.java 파일에서 setter 생성
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMessage(String message) {
this.message = message;
}
④ applicationContext.xml 의 <bean> 안에 <property> 태그를 사용하여
member라는 id를 부여받은 MemberBean 객체의 setter 함수를 호출한다.
<bean id='member' class="ex1_xml2_ref.MemberBean">
<property name="name" value='홍길동'></property> <!-- member.setName(value값); 이 호출됨 -->
<property name="age">
<value>33</value>
</property>
<property name="message" value='오늘도 화이팅!!'></property>
</bean>
⑤ 메인함수가 포함된 MainApp.java 파일을 만든 뒤 context 객체를 생성한다.
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml2_ref/applicationContext.xml");
⑥ context를 통해 getBean( ) 메소드를 호출하여
applicationContext.xml에서 member라는 id를 부여받은 클래스의 객체를
MemberBean 타입으로 형 변환하여 생성하도록 작성한다.
(기본적으로 getBean( ) 메소드의 결과로 Object 타입의 객체를 만들기 때문)
MemberBean bean = context.getBean("member", MemberBean.class);
⑦ MemberBean 타입의 객체 bean을 사용하여 MemberBean 클래스 내의 output( ) 메소드를 호출한다.
bean.output();
⑧ MainApp.java 실행결과
: 메인함수가 호출되면 xml을 읽어 경로에 해당하는 클래스의 객체를 member라는 id로 생성한다.
이 때 <property> 태그에서는 id가 member인 객체의 setter를 호출하여 각각의 값을 대입한다.
getBean( ) 메소드에서 id가 member인 클래스의 객체 bean을 MemberBean 타입으로 형 변환하여 생성한다.
객체 bean이 output( ) 메소드를 호출할 때는 각 변수에 값이 들어있어 다음과 같은 결과가 출력된다.
MemberBean 기본생성자
홍길동[33]오늘도 화이팅!!
(2) 기본값 지정하기 (value 지정) - 생성자 호출
ⓛ applicationContext.xml 에서 id가 member2인 빈 생성
<bean id='member2' class="ex1_xml2_ref.MemberBean"></bean>
② MemberBean.java 에서 모든 변수를 인자로 갖는 생성자 함수 만들기
public MemberBean(String name, int age, String message) {
super();
this.name = name;
this.age = age;
this.message = message;
System.out.println("MemberBean 인자있는 생성자 함수");
}
③ applicationContext.xml 에서 <bean> 안에 <constructor-arg> 태그를 사용하여
member2 라는 id를 부여받은 MemberBean 객체의 생성자함수에 값을 지정한다.
<bean id='member2' class="ex1_xml2_ref.MemberBean">
<constructor-arg value='홍굴자'></constructor-arg>
<constructor-arg value='23' type='int'></constructor-arg>
<constructor-arg><value>주말은 집에서</value></constructor-arg>
</bean>
④ MainApp.java 에서 id가 member2인 빈 가져와서 실행하기
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml2_ref/applicationContext.xml");
MemberBean bean2 = context.getBean("member2", MemberBean.class);
bean2.output();
⑤ 실행결과
: 메인함수에서 xml 파일을 읽어 id가 member2인 빈을 생성하고,
<constructor-arg> 태그를 통해 생성자 함수를 호출하여 값을 지정한다.
MainApp.java에서 getBean( ) 메소드를 통해 id가 member2인 빈을 가져와서
형 변환 후 bean2라는 변수명을 부여한다.
객체 bean2를 사용하여 output( ) 메소드를 호출하면 다음과 같은 결과가 출력된다.
MemberBean 인자있는 생성자 함수
홍굴자[23]주말은 집에서
(3) 참조형 값 지정하기 (ref 지정) - setter 호출
① MemberDao.java 파일을 만든 뒤, MemberBean 클래스를 데이터 타입으로 하는 변수 member를 선언하고
MemberDao 객체 생성시 호출 될 메소드 insert( )를 생성한다.
public class MemberDao {
private MemberBean member;
public void insert() {
member.output();
}
}
② setter를 생성한다.
public void setMember(MemberBean member) {
this.member = member;
}
③ Spring 환경설정 파일인 applicationcontext.xml 에서
<bean> 태그를 사용하여 MemberDao.java 클래스로부터 id가 dao인 빈을 생성하고,
<property> 태그를 사용하여 MemberBean 타입의 변수 member의 값에
id가 member2인 빈을 대입시키는 setMember( ) 메소드(setter)를 호출한다.
<bean id='dao' class="ex1_xml2_ref.MemberDao">
<property name='member' ref='member2'></property>
</bean>
④ MainApp.java 에서 id가 dao인 빈을 가져와서 MemberDao 타입으로 형 변환 후, insert( ) 메소드를 수행한다.
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml2_ref/applicationContext.xml");
MemberDao dao = context.getBean("dao", MemberDao.class);
dao.insert();
}
⑤ 실행결과
: 메인함수에서 xml을 읽어 id가 member2인 빈과 id가 dao인 빈을 각각의 경로로부터 생성한다.
이 때, member2 빈은 생성자 함수를 사용하여 값을 대입하고,
dao 빈은 setter를 사용하여 member2를 dao의 값으로 대입한다.
MainApp.java 에서 getBean( ) 메소드를 통해 id가 dao인 빈을 호출하면
값이 대입된 member2가 다시 대입되어 있는 빈 dao가 메인함수로 불려오고
MemberDao 타입으로 형변환하여 객체명 dao에 지정된다.
이렇게 불려온 객체 dao를 사용하여 insert( ) 메소드가 수행된다.
MemberBean 인자있는 생성자 함수
홍굴자[23]주말은 집에서
(4) 참조형 값 지정하기 (ref 지정) - 생성자 호출
① MemberDao.java 에서 인자 있는 생성자 함수를 만든다. (에러방지를 위해 인자 없는 생성자 함수도 만든다.)
public MemberDao(MemberBean member) {
super();
this.member = member;
}
public MemberDao() {
}
② Spring 환경설정 파일 applicationContext.xml 에서
<bean> 태그를 사용하여 id가 dao2인 빈을 해당 경로로부터 생성하고,
<constructor-arg> 태그를 통해 id가 member2인 빈을 값으로 지정한다.
<bean id='dao2' class="ex1_xml2_ref.MemberDao">
<constructor-arg ref='member2'></constructor-arg>
</bean>
③ MainApp.java 에서 id가 dao2인 빈을 가져와서 MemberDao 타입으로 형 변환 후, insert( ) 메소드를 수행한다.
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml2_ref/applicationContext.xml");
MemberDao dao2 = context.getBean("dao2", MemberDao.class);
dao2.insert();
}
④ 실행결과
: 메인함수에서 xml을 읽어 id가 member2인 빈과 id가 dao2인 빈을 각각의 경로로부터 생성한다.
이 때, member2 빈은 생성자 함수를 사용하여 값을 대입하고,
dao2 빈은 생성자 함수를 호출하여 member2를 dao2의 값으로 대입한다.
MainApp.java 에서 getBean( ) 메소드를 통해 id가 dao2인 빈을 호출하면
값이 대입된 member2가 다시 대입되어 있는 빈 dao2가 메인함수로 불려오고
MemberDao 타입으로 형변환하여 객체명 dao2에 지정된다.
이렇게 불려온 객체 dao2를 사용하여 insert( ) 메소드가 수행된다.
MemberBean 인자있는 생성자 함수
홍굴자[23]주말은 집에서
< MemberBean.java 전체 소스 코드 >
package ex1_xml2_ref;
public class MemberBean {
private String name;
private int age;
private String message;
public void output() {
System.out.println(name + "[" + age + "]" + message);
}
public MemberBean() {
System.out.println("MemberBean 기본생성자");
}
// private인 변수를 사용하는 방법
// 1. setter 호출
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMessage(String message) {
this.message = message;
}
// 2. 생성자 호출
public MemberBean(String name, int age, String message) {
super();
this.name = name;
this.age = age;
this.message = message;
System.out.println("MemberBean 인자있는 생성자 함수");
}
}
< applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 빈 생성 -->
<!-- 1. 기본값지정 (value 지정)
(1) setter 호출 --> <!--
<bean id='member' class="ex1_xml2_ref.MemberBean">
<property name="name" value='홍길동'></property> --><!-- member.setName(value값); 이 호출됨 --><!--
<property name="age">
<value>33</value>
</property>
<property name="message" value='오늘도 화이팅!!'></property>
</bean> -->
<!-- 1. 기본값 지정(value 지정)
(2) 생성자 이용
<value> 태그에서 자료형을 따지지 않기 때문에 숫자 입력시 ''을 사용하지 않아도 정상 출력됨, 자료형을 명확히 하고 싶을 경우에는
<constructor-arg value='23' type='int'></constructor-arg>
으로 기술하면 됨 -->
<bean id='member2' class="ex1_xml2_ref.MemberBean">
<constructor-arg value='홍굴자'></constructor-arg>
<constructor-arg value='23' type='int'></constructor-arg>
<constructor-arg><value>주말은 집에서</value></constructor-arg>
</bean>
<!-- 2. 참조형 지정 (ref 지정)
(1) setter 이용 --> <!--
<bean id='dao' class="ex1_xml2_ref.MemberDao"> -->
<!-- <property name='member' ref='member2'></property> setMember() 호출하는 태그 --><!--
</bean> -->
<!-- 2. 참조형 지정 (ref 지정)
(2) constructor 이용 -->
<bean id='dao2' class="ex1_xml2_ref.MemberDao">
<constructor-arg ref='member2'></constructor-arg>
</bean>
</beans>
< MainApp.java 전체 소스 코드 >
package ex1_xml2_ref;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml2_ref/applicationContext.xml");
/* MemberBean bean = context.getBean("member", MemberBean.class);
bean.output(); */
/*
* 출력결과
* MemberBean 기본생성자
홍길동[33]오늘도 화이팅!!
*/
/* MemberBean bean2 = context.getBean("member2", MemberBean.class);
bean2.output(); */
/*
* 출력결과
* MemberBean 기본생성자
MemberBean 인자있는 생성자 함수
홍길동[33]오늘도 화이팅!!
홍굴자[23]주말은 집에서
*/
/* MemberDao dao = context.getBean("dao", MemberDao.class);
dao.insert(); */
MemberDao dao2 = context.getBean("dao2", MemberDao.class);
dao2.insert();
}
}
< MemberDao.java 전체 소스 코드 >
package ex1_xml2_ref;
public class MemberDao {
private MemberBean member;
// 1. setter
public void setMember(MemberBean member) {
this.member = member;
}
public void insert() {
member.output();
}
// 2. constructor
public MemberDao(MemberBean member) {
super();
this.member = member;
}
public MemberDao() {
}
}
3. DI방식에서 값 지정하기 - p value 사용 (p 네임스페이스)
(1) 기본값 지정하기
① ex1_xml3_pvalue 패키지 생성 후 MemberBean.java와 MemberDao.java 복사해오기
② Spring 환경설정 파일인 applicationContext.xml 생성
③ Namespaces 에서 beans와 p 체크 후 저장
④ MemberBean.java 에서 변수 선언 및 setter를 호출하고 있다.
public class MemberBean {
private String name;
private int age;
private String message;
public void output() {
System.out.println(name + "[" + age + "]" + message);
}
public MemberBean() {
System.out.println("MemberBean 기본생성자");
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMessage(String message) {
this.message = message;
}
}
⑤ applicationContext.xml 에서 id가 bean이고 경로가 ex1_xml3_pvalue폴더의
MemberBean 클래스인 빈을 생성한다.
이 때 <bean> 태그의 속성으로 p:변수명="값" 을 사용하여
각 변수에 값을 지정함으로 코드를 획기적으로 단축할 수 있다.
<bean id='bean' class="ex1_xml3_pvalue.MemberBean" p:name='박길동' p:age='44' p:message='행복한 주말'>
</bean>
(기존)
<bean id='member' class="ex1_xml2_ref.MemberBean">
<property name="name" value='박길동'></property>
<property name="age" value='44'></property>
<property name="message" value='행복한 주말'></property>
</bean>
⑥ MainApp.java 파일 생성 후 Spring 컨테이너를 구동시키고,
id가 bean인 빈을 가져와 객체 생성 후 output( ) 메소드를 호출한다.
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml3_pvalue/applicationContext.xml");
MemberBean b = context.getBean("bean", MemberBean.class);
b.output();
}
}
( 실행결과 )
: 메인함수에서 Spring 컨테이너인 xml 파일을 읽어 id가 bean인 빈을 생성하면서
p : 네임스페이스에 의해 값을 지정한다. ( p : 네임스페이스는 setter를 이용함)
getBean( ) 메소드 수행의 결과로 객체 b를 생성하여 output( ) 메소드를 수행하면
"박길동[44]행복한 주말" 이라고 출력하게 된다.
MemberBean 기본생성자
박길동[44]행복한 주말
(2) 참조형 값 지정하기
① MainApp.java에서 id가 memberdao인 MemberDao 타입 객체 d를 생성하여 insert( ) 메소드를 호출하고자 한다.
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml3_pvalue/applicationContext.xml");
MemberDao d = context.getBean("memberdao", MemberDao.class);
d.insert();
}
}
② MemberDao.java 클래스는 데이터타입이 MemberBean인 참조형 member를 변수로 갖는다.
public class MemberDao {
private MemberBean member;
public void setMember(MemberBean member) {
this.member = member;
}
public void insert() {
member.output();
}
}
③ applicationContext.xml에 이미 <bean> 태그 안에서 p : value 를 사용하여 값을 지정하고 있다.
이 빈을 참조하여 id가 memberdao인 빈이 생성하는 <bean> 태그를 작성한다.
<bean id='bean' class="ex1_xml3_pvalue.MemberBean" p:name='박길동' p:age='44' p:message='행복한 주말'></bean>
<bean id='memberdao' class="ex1_xml3_pvalue.MemberDao" p:member-ref="bean"></bean>
( 실행결과 )
: 메인함수에서 Spring 컨테이너를 구동하여 xml을 읽을 때
bean이라는 빈이 생성되면서 p : 네임스페이스를 통해 값이 지정된다.
memberdao라는 빈은 생성될 때, 위에서 만들어진 빈을 가져다 참조하여 만들어지므로
다음과 같은 출력결과가 나온다.
MemberBean 기본생성자
박길동[44]행복한 주말
< MemberBean.java 전체 소스 코드 >
package ex1_xml3_pvalue;
public class MemberBean {
private String name;
private int age;
private String message;
public void output() {
System.out.println(name + "[" + age + "]" + message);
}
public MemberBean() {
System.out.println("MemberBean 기본생성자");
}
// private인 변수를 사용하는 방법
// 1. setter 호출
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMessage(String message) {
this.message = message;
}
}
< applicationContext.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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 1. 기본값 지정
(1) setter
(2) constructor
==============
(3) pvalue 지정 (*) -->
<bean id='bean' class="ex1_xml3_pvalue.MemberBean" p:name='박길동' p:age='44' p:message='행복한 주말'>
</bean>
<!-- 여기를 채우기 -->
<bean id='memberdao' class="ex1_xml3_pvalue.MemberDao" p:member-ref="bean"></bean>
</beans>
< MainApp.java 전체 소스 코드 >
package ex1_xml3_pvalue;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml3_pvalue/applicationContext.xml");
/* MemberBean b = context.getBean("bean", MemberBean.class);
b.output(); */
MemberDao d = context.getBean("memberdao", MemberDao.class);
d.insert();
}
}
< MemberDao.java 전체 소스 코드 >
package ex1_xml3_pvalue;
public class MemberDao {
private MemberBean member;
// 1. setter
public void setMember(MemberBean member) {
this.member = member;
}
public void insert() {
member.output();
}
}
4. List 에 값 지정하기
(1) ex1_xml4_list 패키지 생성 후 MemberBean.java 클래스를 복사해오고 새롭게 ListBean.java 클래스 생성
public class ListBean {
private List<Integer> intList;
// setter
public void setIntList(List<Integer> intList) {
this.intList = intList;
}
// constructor
public ListBean() {
super();
}
public ListBean(List<Integer> intList) {
super();
this.intList = intList;
}
}
(2) applicationContext.xml 를 만들고 <property> 태그를 통해 setter를 호출 및
<list> 태그 안의 <value> 태그를 사용하여 값을 지정할 수 있다.
<bean id='bean' class="ex1_xml4_list.ListBean"></bean>
<!-- setter 이용 -->
<property name="intList">
<list>
<value>20</value>
<value>30</value>
<value>56</value>
</list>
</property>
</beans>
(3) MainApp.java 생성 후 Spring 컨테이너를 구동하여 list에 담긴 값들을 하나씩 출력시키는 메소드를 작성한다.
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml4_list/applicationContext.xml");
ListBean list = context.getBean("bean", ListBean.class);
for (Integer i : list.getIntList()) {
System.out.println(i);
}
}
}
( 실행결과 )
: 메인함수에서 Spring 컨테이너를 구동하여 id가 bean인 ListBean 타입의 객체 list를 만든다.
이 때, <property> 태그에서 intList라는 이름의 List<Integer>에 20, 30, 56 이라는 값을 지정한다.
for 반복문에서는 객체 list에 들어있는 Integer 값을 하나씩 꺼내어 출력한다.
MemberBean 기본생성자
MemberBean 인자있는 생성자 함수
20
30
56
(4) 이전에 사용한 패키지로부터 MemberBean.java 를 복사해온다.
(5) ListBean.java 클래스에서 데이터타입이 MembreBean인 List 변수 memberList를 선언하고
setter와 getter를 생성한다.
public class ListBean {
private List<MemberBean> memberList;
public List<MemberBean> getMemberList() {
return memberList;
}
public void setMemberList(List<MemberBean> memberList) {
this.memberList = memberList;
}
}
(6) applicationContext.xml 에서 id가 m1, m2인 MemberBean의 빈을 생성하고
setter와 생성자를 이용하여 값을 지정한다.
id가 bean인 ListBean의 빈은 변수 memberList의 값으로 m1과 m2를 지정한다.
<bean id='bean' class="ex1_xml4_list.ListBean">
<!-- setter 이용 -->
<property name="intList"> <!-- setIntList() -->
<list>
<value>20</value>
<value>30</value>
<value>56</value>
</list>
</property>
<property name="memberList">
<list>
<ref bean='m1' />
<ref bean='m2' />
</list>
</property>
</bean>
<bean id='m1' class="ex1_xml4_list.MemberBean">
<!-- setter 이용하여 값 지정 -->
<property name='name'><value>홍길자</value></property>
<property name='age' value='27'></property>
<property name='message' value='낯설다'></property>
</bean>
<bean id='m2' class="ex1_xml4_list.MemberBean">
<!-- 생성자 이용하여 값 지정 -->
<constructor-arg ref='m2'></constructor-arg>
</bean>
</beans>
( 실행결과 )
: 메인함수에서 Spring 컨테이너를 구동하면서 id가 bean인 listBean 클래스의 빈을 생성하고,
MemberBean에서 2마리의 값을 지정하여 id가 m1, m2인 빈을 생성한다.
m1과 m2는 변수 memberList의 값으로 지정된다.
MemberBean 기본생성자
MemberBean 인자있는 생성자 함수
홍길자[27]낯설다
박길동[23]메롱
(8) applicationContext.xml 에서 id가 없는 무명빈을 추가하여, 곧바로 멤버변수의 값으로 지정할 수 있다.
<bean id='bean' class="ex1_xml4_list.ListBean">
<property name="memberList">
<list>
<ref bean='m1' />
<ref bean='m2' />
<!-- 무명빈 -->
<bean class="ex1_xml4_list.MemberBean">
<property name="name" value="홍길국"></property>
<property name="age" value="30"></property>
<property name="message" value="행복합시다2"></property>
</bean>
</list>
</property>
</bean>
(9) MainApp.java에서 id가 bean인 빈으로부터 객체 list를 생성하여 그 안에 들어있는 데이터를 하나씩 출력해본다.
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml4_list/applicationContext.xml");
ListBean list = context.getBean("bean", ListBean.class);
for(MemberBean m : list.getMemberList()) {
m.output();
}
}
}
( 실행결과 )
MemberBean 기본생성자
MemberBean 인자있는 생성자 함수
MemberBean 기본생성자
홍길자[27]낯설다
박길동[23]메롱
홍길국[30]행복합시다2
< ListBean.java 전체 소스 코드 >
package ex1_xml4_list;
import java.util.List;
public class ListBean {
private List<Integer> intList;
private List<MemberBean> memberList;
public List<MemberBean> getMemberList() {
return memberList;
}
public void setMemberList(List<MemberBean> memberList) {
this.memberList = memberList;
}
// setter
public void setIntList(List<Integer> intList) {
this.intList = intList;
}
// getter
public List<Integer> getIntList() {
return intList;
}
// constructor
public ListBean() {
super();
}
public ListBean(List<Integer> intList) {
super();
this.intList = intList;
}
}
< applicationContext.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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id='bean' class="ex1_xml4_list.ListBean">
<!-- setter 이용 -->
<property name="memberList">
<list>
<ref bean='m1' />
<ref bean='m2' />
<!-- 무명빈 -->
<bean class="ex1_xml4_list.MemberBean">
<property name="name" value="홍길국"></property>
<property name="age" value="30"></property>
<property name="message" value="행복합시다2"></property>
</bean>
</list>
</property>
</bean>
<bean id='m1' class="ex1_xml4_list.MemberBean">
<!-- setter 이용하여 값 지정 -->
<property name='name'><value>홍길자</value></property>
<property name='age' value='27'></property>
<property name='message' value='낯설다'></property>
</bean>
<bean id='m2' class="ex1_xml4_list.MemberBean">
<!-- 생성자 이용하여 값 지정 -->
<constructor-arg value='박길동'></constructor-arg>
<constructor-arg value='23'></constructor-arg>
<constructor-arg value='메롱'></constructor-arg>
</bean>
</beans>
< MainApp.java 전체 소스 코드 >
package ex1_xml4_list;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex1_xml4_list/applicationContext.xml");
ListBean list = context.getBean("bean", ListBean.class);
/* for (Integer i : list.getIntList()) {
System.out.println(i);
} */
for(MemberBean m : list.getMemberList()) {
m.output();
}
}
}
< MemberBean.java 전체 소스 코드 >
package ex1_xml4_list;
public class MemberBean {
private String name;
private int age;
private String message;
public void output() {
System.out.println(name + "[" + age + "]" + message);
}
public MemberBean() {
System.out.println("MemberBean 기본생성자");
}
// private인 변수를 사용하는 방법
// 1. setter 호출
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMessage(String message) {
this.message = message;
}
// 2. 생성자 호출
public MemberBean(String name, int age, String message) {
super();
this.name = name;
this.age = age;
this.message = message;
System.out.println("MemberBean 인자있는 생성자 함수");
}
}
5. 스프링에서 애노테이션을 사용하여 빈 생성하기
(1) ex2_annotation 패키지 생성
(2) ex1_xml2_ref 패키지로부터 MemberBean..java와 MemberDao.java 복사
(3) applicationContext.xml 생성 후 namespace 에서 context 체크, 저장
(4) applicationContext.xml 에서 <context> 태그 작성
: ex2_annotation 패키지를 쭉 스캔하겠다는 뜻
<context:component-scan base-package="ex2_annotation" />
(5) MemberBean.java와 MemberDao.java 에 @Component 어노테이션을 붙이고 해당 클래스를 import 한다.
→ @Component 어노테이션이 있는 곳을 스캔하기 위해 붙이는 것
@Component
public class MemberBean {
@Component
public class MemberDao {
(6) MemberDao.java 에서 필드 기반의 의존성 주입방식을 사용하여 입력값을 넣기 위해
기존에 작성된 setter와 생성자함수를 주석처리 한다.
(7) MemberBean 변수 선언 윗줄에 @Autowired 어노테이션을 붙이고 해당 클래스를 import 한다.
@Autowired
private MemberBean member;
(8) MainApp.java 파일을 만들고 스프링 컨테이너를 구동한다.
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex2_annotation/applicationContext.xml");
(9) MemberDao 클래스의 객체를 생성한 뒤 insert( ) 메소드를 수행하기 위한 스크립트를 작성한다.
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex2_annotation/applicationContext.xml");
MemberDao dao = context.getBean("", MemberDao.class);
dao.insert();
(10) 클래스 이름에서 첫글자만 소문자로 바꿔서 "" 안에 작성하면 객체 생성이 가능해진다.
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex2_annotation/applicationContext.xml");
MemberDao dao = context.getBean("memberDao", MemberDao.class);
dao.insert();
(11) 실행결과, 객체가 만들어진 뒤 기본 생성자에 들어있는 값이 대입되어 insert( ) 메소드가 수행됨을 알 수 있다.
MemberBean 기본생성자
X맨[20]마가 낀 6강
(12) 어노테이션에 별칭을 사용하여 객체 생성할 때 클래스명 대신 사용할 수 있다.
@Component
→ @Component(dao)
위와 같이 ( ) 에서 생성될 빈의 별칭을 지정해주면, MainApp 에서 별칭으로 빈을 얻어올 수 있다.
MemberDao dao = context.getBean("memberDao", MemberDao.class);
→ MemberDao dao = context.getBean("dao", MemberDao.class);
( 실행결과 )
: 메인함수에서 스프링 컨테이너를 구동하여
applicationContext.xml 의 <context> 태그에서 지정한 폴더를 스캔한다.
@Component 애노테이션을 찾이 빈을 생성하고 @Autowired 애노테이션을 이용하여 필요한 객체와 연결시킨다.
결과적으로 MemberBean.java의 기본생성자 함수에서 각 변수의 값이 지정되고,
값을 가진 MemberBean 객체가 @Autowired 애노테이션을 통해 MemberDao 객체의 멤버변수 값으로 지정된다.
insert( ) 메소드를 수행하면 멤버변수 member에 지정된 값을 사용하여 화면에 출력하게 된다.
MemberBean 기본생성자
X맨[20]마가 낀 6강
※ 참고
((xml 방법은 만들기는 어렵지만 유지보수가 쉽다))
((annotation 방법은 만들기는 쉽지만 유지보수가 어렵다)) - 어노테이션의 위치를 찾기 어려워서임
< MemberBean.java 전체 소스 코드 >
package ex2_annotation;
import org.springframework.stereotype.Component;
@Component
public class MemberBean {
private String name;
private int age;
private String message;
public void output() {
System.out.println(name + "[" + age + "]" + message);
}
public MemberBean() {
name = "X맨";
age = 20;
message = "마가 낀 6강";
System.out.println("MemberBean 기본생성자");
}
// private인 변수를 사용하는 방법
// 1. setter 호출
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setMessage(String message) {
this.message = message;
}
// 2. 생성자 호출
public MemberBean(String name, int age, String message) {
super();
this.name = name;
this.age = age;
this.message = message;
System.out.println("MemberBean 인자있는 생성자 함수");
}
}
< applicationContext.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">
<!-- ex2_annotation 패키지를 쭉 스캔하겠다는 뜻 -->
<context:component-scan base-package="ex2_annotation" />
</beans>
< MainApp.java 전체 소스 코드 >
package ex2_annotation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex2_annotation/applicationContext.xml");
// 빈 이름(객체명)은 자동으로 동일한 이름으로 하되 첫 글자가 소문자
// 그래서 그동안 클래스명을 첫글자 대문자로 하도록 권장했던 것
MemberDao dao = context.getBean("memberDao", MemberDao.class);
dao.insert();
}
}
< MemㅠerDao.java 전체 소스 코드 >
package ex2_annotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
@Component
public class MemberDao {
// 3. 필드 기반의 의존성 주입방식
@Autowired
private MemberBean member;
// 1. setter
/* public void setMember(MemberBean member) {
this.member = member;
} */
public void insert() {
member.output();
}
// 2. constructor
/* public MemberDao(MemberBean member) {
super();
this.member = member;
}
public MemberDao() {
} */
}
6. Autowiring
(1) ex3_autowiring 패키지 생성한다.
(2) MessageBean.java 라는 인터페이스 생성하고 sayHello( ) 메소드를 선언한다.
public interface MessageBean {
void sayHello();
}
(3) MessageBeanImpl.java 라는 클래스 생성 후 MessageBean 상속, 추상메소드 완성한다.
public class MessageBeanImpl implements MessageBean {
public void sayHello() {
}
}
(4) MemberBeanImpl.java 클래스에서 변수를 선언한다.
private String name;
private String message;
(5) setter 또는 생성자로 값을 지정한다. (setter 선택함)
public void setName(String name) {
this.name = name;
}
public void setMessage(String message) {
this.message = message;
}
(6) 상속한 sayHello( ) 메소드 작성한다.
public void sayHello() {
System.out.println(name + "님께" + message);
}
(7) applicationContext.xml 파일 생성 후 <bean> 태그 작성한다.
<bean id='message' class="ex3_autowiring.MessageBeanImpl"></bean>
(8) 메인함수가 포함된 MainApp.java 파일 생성 후 context 객체 생성한다. (스프링 컨테이너 구동)
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex2_annotation/applicationContext.xml");
(9) MessageBean 객체 생성 후 sayHello( ) 메소드 호출한다. (컨테이너로부터 빈 가져오기)
public class MainApp {
public static void main(String[] args) {
ApplicationContext context
= new ClassPathXmlApplicationContext("ex2_annotation/applicationContext.xml");
MessageBean bean = context.getBean("message", MessageBean.class);
bean.sayHello();
(10) applicationContext.xml 에서 <property> 태그를 사용하여 값을 입력한다.
<bean id='message' class="ex3_autowiring.MessageBeanImpl">
<property name="name" value="짝꿍" />
<property name="message" value="돌아오세요" />
</bean>
( 실행결과 )
: 메인함수에서 스프링 컨테이너를 구동하여 applicationContext.xml에 작성된
id가 message이고 경로가 ex_autowiring.MessageBeanImpl인 빈을 생성한다.
빈이 생성될 때 <property>태그에서 setter를 호출하여 각 변수에 값을 지정한다.
메인함수에서 id가 message인 빈을 가져와서 객체 bean을 생성하고 sayHello( ) 메소드를 호출한다.
sayHello( ) 메소드에서는 값이 지정된 빈을 사용하여 다음과 같은 결과를 화면에 출력한다.
짝꿍님께돌아오세요
(11) applicationContext.xml 에서 <property name="name" value="짝꿍님" /> 가 없을 경우,
name에 해당하는 setter를 호출하지 않아 name의 출력값이 null이 되지만 에러는 발생하지 않는다.
<bean id='message' class="ex3_autowiring.MessageBeanImpl">
<!-- <property name="name" value="짝꿍" /> -->
<property name="message" value="돌아오세요" />
</bean>
null님께돌아오세요
(12) MessageBeanImpl.java 에서 setName( ) 윗 줄에 @Required 어노테이션을 붙이면
필수입력사항으로 지정해줄 수 있다.
※ namespace 에서 context 체크 후 <context> 태그 작성한다.
@Required
public void setName(String name) {
this.name = name;
}
→ (Context 버전이 높아서 @Required 어노테이션 적용 안 됨)
@Required 어노테이션은 스프링 프레임워크 5.1 부터 공식적으로 deprecated 되었다. 필수값 세팅을 위하여 생성자 주입을 사용할것을 권장한다. (bean property 세터 메소드와 함께 InitializingBean.afterPropertiesSet() 을 구현하는것도 또하나의 방법이다.(