본문 바로가기

수업 정리

59일차 수업 정리(Spring)

**Spring

    => Java Framework

    => 대규모 애플리케이션 개발에서  개발자들의 역량을 획일화 하여 빠르게 구현할 수 있도록 하는 것이 목적

    => 이러한 Java Framework로 이전에는 struts를 많이 사용

        - 일본의 경우 struts로 구현된 애플리케이션을 유지보수하면서 사용

1. Spring Project 작업 도구

    => Eclipse(Plug in, Spring Tool Suite, 기업에서 제작한 별도 프레임워크 - 전자정부 프레임워크, Any Framework)

    => Intelli J - 개인 개발자나 중소기업 등에서 이용

 

2. Spring Project 종류

    => Legacy Project(Spring MVC Project) : 이전에 사용하던 Spring Web Project, STS 4버전 이후로는 제공되지 않음

        - 기존의 대기업, 금융, 공공기관 프로젝트가 이 방식으로 만들어져 있음

    => Spring Boot Project(Starter Project) : 애플리케이션을 빠르게하기 위해서 제공되는 템플릿

        - JSP가 아니라 다른 방식으로 출력, 자체 WAS를 제공

 

3. Spring Legacy Project

    => Maven 기반

    => Maven : Build Tool 

        - Source -> Compile(Source를 운영체제나 Virtual Machine이 이해가능 코드로 변환 - 문법오류시 컴파일 실패)

-> build(실행가능하도록 start up 코드나  컴파일된 파일들 사이의 관계를 설정) -> load(메모리에 적재) -> run(실행)

 

4. pom.xml

    => repository : 중앙 저장소 이외의 곳에서 다운로드 받고자 할 때 설정

        - 수업시간에는 Oracle 사용을 할 때 설정

        - 기업에서는 함부로 설정하면 안됨

    => dependencies : 외부 라이브러리 사용을 설정

        - 사용자 계정의 .m2라는 디렉토릴를 이용

        - 외부 라이브러리 설정시, m2 디렉토리에 가서 라이브러리가 있는지 확인후, 있으면 그 라이브러리를 사용하고

         없으면 repositories에 설정된 곳으로 가보고 그 다음중앙 저장소에서 가서 다운로드를 받아서 사용

       - 다운로드가 잘 되지 않거나, 일부분만 다운로드 되는 경우, m2 디렉토리를 삭제, 재 build시 다운로드가 다시 됨

       - 다른 컴퓨터의 m2 디렉토리를 복사해서 사용해도 됨

 

**Spring Project의 pom.xml

    => 프로젝트를 생성하면 Maven 설정파일인 pom.xml이 자동으로 생성

1. Properties

<properties>
     <java-version>1.6</java-version>
     <org.springframework-version>3.1.1.RELEASE</org.springframework-version>
     <org.aspectj-version>1.6.10</org.aspectj-version>
     <org.slf4j-version>1.6.6</org.slf4j-version>
</properties>

    => java version은 1.8로 변경

    => Spring version은 5.0.7로 변경

    => properties는 자주 사용할 문자열을 하나의 태그로 만들어 둔것

        - class안의 static final상수와 같은 역할

 

2. Dependencies

    => 외부 라이브러리를 설정하는 태그

    => scope가 생략되어 있으면 배포시 라이브러리도 함께 배포

        - scope에 provided가 있으면 배포시 이 라이브러리는 운영환경에 있는 것을 사용한다는 의미

        - scope에 test가 있으면 이 라이브러리는 배포시 삭제됨

 

3. Spring MVC Project

    => Spring Web Project로 HomeController라고 하는 Controller와 메인화면에 해당하는 JSP 파일도 제공

 

**IoC(제어의 역전)

    => 일반적인 프로그래밍에서는 클래스를 개발자가 만들고 이 클래스의 인스턴스를 생성하여 사용

    => 클래스 제작은 개발자가 하지만 인스턴스 생성이나 관리는 프레임워크가 하게되는데 이것을 제어의 역전이라 함

    => 대표적인 경우가 Web Programming에서 HttpServlet으로부터 상속받는 클래스를 디자인 하지만 실제 인스턴스

        제작 및 사용은 WAS(Web Application, Server - Web Container : tomcat9.0)가 함

    => 이유 : 개발자는 비지니스 로직 작성에만 집중하도록 하기 위해

1. Factory Method Pattern

    => 생성자를 호출하여 객체를 생성하지 않고 다른 클래스의 메소드를 이용해서 객체를 생성하는 방식

    => DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();

        - 여기서 인스턴스는 DocumentBuilder 클래스의 메소드를 호출하지 않고 Factory의 메소드를 호출하여 생성

    => 이유 : 제작 과정이 복잡한 경우 만드는 메소드를 직접 호출하는 것 보다 다른 클래스의 메소드를 간단하게 호출

        하여 생성하는 것이 가독성을 높일수 있기 때문 

 

2. Proxy Pattern

    => 클래스 제작시 Framework가 다른코드를 삽입하여 새로운 클래스를 디자인, 우리가 사용하게 만들어주는 패턴

        - 개발자는 자신이 만든 클래스를 사용하는 것 처럼 사용하면 됨

    => 이러한 이유로 프레임워크 이용하여 작업시 final class는 조심해서 생성해야 함

 

3. 인스턴스 생성은 xml 파일이나 어노테이션을 이용하여 생성

 

4. class는 java 디렉토리에 생성

    => 애플리케이션이 실행될 때 java 디렉토리에 있는 것만 컴파일

    => 클래스가 아닌 것은 아무 디렉토리에나 만들어도 됨

 

**IoC 실습

1. domain 패키지에 DTO 클래스를 생성

package com.pk.IoC.domain;

public class Item {
	private String code;
	private String name;
	private String price;
	
	public Item() {
		super();
		// TODO Auto-generated constructor stub
	}
	public Item(String code, String name, String price) {
		super();
		this.code = code;
		this.name = name;
		this.price = price;
	}
	
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getPrice() {
		return price;
	}
	public void setPrice(String price) {
		this.price = price;
	}
	
	@Override
	public String toString() {
		return "Item [code=" + code + ", name=" + name + ", price=" + price + "]";
	}
}

 

2. HomeController의 메소드에서 인스턴스를 생성하여 출력

    => 일반적인 클래스 사용 방법

public String home(Locale locale, Model model) {
	//Item 클래스 사용(사용자 정의 자료형)
	//static 변수나 메소드를 사용하는 경우를 제외하고
	//class는 instance를 만들어서 사용
	Item item = new Item();
	
	item.setCode("001");
	item.setName("단감");
	item.setPrice("1000");
    
	System.out.println(item);
	
	return "home";
}

 

**Factory Method Pattern 적용

1. ItemFactory 클래스를 만들고 Itme 인스턴스를 만들어서 리턴하는 메소드를 생성

public class ItemFactory {
	//Item 클래스의 인스턴스를 만들어서 리턴하는 메소드
	public static Item create() {
		Item item = new Item();
		return item;
	}
}

 

2. HomeController의 메소드 수정

    => 생성자를 이용하지 않고 팩토리 클래스의 메소드를 이용하여 생성

public String home(Locale locale, Model model) {
	//Item 클래스 사용(사용자 정의 자료형)
	//static 변수나 메소드를 사용하는 경우를 제외하고
	//class는 instance를 만들어서 사용
	Item item = ItemFactory.create();
	
	item.setCode("001");
	item.setName("단감");
	item.setPrice("1000");
    
	System.out.println(item);
	
	return "home";
}

 

**Springdml IoC 사용

1. appServlet.xml 파일에 작성

<beans:bean class="com.pk.IoC.domain.Item"/>

 

2. HomeController 클래스의 코드를 수정

    => 상단에 작성

@Autowired
private Item item;

    => 메소드에서 Item 생성하는 부분을 삭제

//Item item = ItemFactory.create();

 

**Simple Spring Maven Project 만들기

    - 모레까지 이 방법을 사용(중요하지 않음 : IoC, DI, MyBatis, Hibernate연동을 웹이 아닌 환경에서 하기 위해 생성)

    => STS에서 위의 프로젝트가 만들어지지 않는 경우

1. Java Project 생성

 

2. Maven Project 로 변환 : pom.xml 생성

    => 프로젝트를 생성하고 마우스 오른쪽 클릭하고 [Configure] - [Convert to Maven Project]를 선택

 

3. pom.xml에 코드 추가

    => https://ggangpae1.tistory.com/304?category=840479 에서 복사 

 

simple spring maven 프로젝트가 안만들어지는 경우

1.8 UTF-8 UTF-8 5.0.7.RELEASE 4.2.1.Final 1.0.13 1.7.5 4.11 org.springframework spring-context ${spring-framework.version} org.springframework spring-tx ${spring-framework.version} org.slf4j slf4j-a..

ggangpae1.tistory.com

        - 하단의 </build>아래에 붙여 넣기

 

**Spring의 IoC(Inversion Of Control)

    => 제어의 역전

    => 개발자가 만든 클래스의 제어권을 프레임워크가 가지는 것

    => 인스턴스 생성 및 관리를 개발자가 아닌 프레임워크가 하는 것

    => 목적은 개발자는 비지니스 로직 구현에만 집중하도록 하기 위한 것

1. Spring Bean

    => Spring이 만들어주는 인스턴스

 

2. Bean Factory

    => 스프림에서 빈을 생성하고 관리하는 인스턴스

    => 생성 방법 : xml 파일을 이용해서 생성, 환경 설정 클래스를 만들어서 annotation을 이용하여 생성할수도 있음

    => xml 파일도 실제 실행시 Spring 클래스로 변환, 이 때 많이 사용되는 클래스는 GenericXmlApplicationContext와

        WebApplicationContext 클래스

 

**Configuration을 이용해서 bean 생성

1. domain.Good 클래스를 생성

package domain;

public class Good {
	private int num;
	private String name;
	
	public Good() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public Good(int num, String name) {
		super();
		this.num = num;
		this.name = name;
	}
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "Good [num=" + num + ", name=" + name + "]";
	}
	
}

 

2. Spring Factory 클래스 생성

    => 클래스 위에 @Configuration을 추가

    => 인스턴스를 생성해서 리턴하는 메소드위에는 @Bean을 추가

    => 전자정부 프레임워크나 기업의 프레임워크는 기본적 작업이 수행되도록 프로젝트를 생성해줌

        - 설정내용을 읽지 못하면 수정할수 없음

package domain;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

//Spring Bean Factory 클래스를 만들어주는 어노테이션
//annotation : 자주 사용되는 복잡한 코드를 하나의 단어로 만들어 놓은 것
//자바에서는 하나의 클래스
//build 시는 자바코드로 변경됨
@Configuration
public class GoodFactory {
	//Spring에서 Bean을 생성해주는 메소드를 만들기 위한 어노테이션
	//클래스 내부에 만들어지는 메소드가 인스턴스 변수(프로퍼티)를 사용하지 않으면
	//static 메소드로 만들어서 클래스를 가지고 바로 호출하게 만드는 것이 효율적
	@Bean
	public static Good build() {
		Good good = new Good();
		return good;
	}
}

 

3. main 메소드를 소유한 클래스를 만드록 main 메소드를 작성

    => BeanFactory 클래스를 사용하기 위한 생성 방법

        - AnnotationConfigApplicationContext 변수 = new AnnotationConfigApplicationContext(클래스명.class)

    => BeanFactory 클래스의 메소드를 호출하는 방법

        - 변수.getBean(String 메소드명, 실제 생성될 클래스명.class);

        - 메소드 이름 생략시 클래스명과 일치하는 bean을 생성해주는 메소드를 호출

        - 클래스명 생략시 Object 타입으로 만들어서 리턴하기 때문에 강제 형 변환하여 사용

 

4. Spring이 만들어주는 Bean은 기본적으로 Singleton Pattern이 적용

    => SingletonPattern : 인스턴스를 1개만 생성할 수 있는 디자인 패턴

    => Spring으로 만든 Application이 실행되는 환경은 Server일 가능성이 높기 때문

    => Server는 특별한 경우가 아니면 인스턴스를 1개만 생성하여 사용자의 요청을 스레드로 처리

 

5. 2개의 객체가 동일한 객체인지 확인 - 해시코드 확인

    => 인스턴스의 hashCode() 메소드를 호출하면 안됨

        - hashCode() 메소드는 재정의하여 사용하라고 제공되는 메소드

    => 해시코드는 System 클래스의 메소드를 이용하여 출력

AnnotationConfigApplicationContext context = 
		new AnnotationConfigApplicationContext(GoodFactory.class);

Good good = context.getBean("build", Good.class);
good.setNum(1);
good.setName("사과");
System.out.println(good);
		
Good good1 = context.getBean("build", Good.class);
good1.setNum(2);
good1.setName("수박");
System.out.println(good1);
		
//해시코드 출력
//해시코드가 동일하면 동일한 메모리 영역을 사용하고 있는 것
System.out.println(System.identityHashCode(good));
System.out.println(System.identityHashCode(good1));

 

**XML을 이용한 Bean 생성으로 변경

    => XML을 이용하여 Bean을 생성하고자 할 때는 SpringBeanConfiguration 파일을 추가

    => Bean 생성

        - <bean class="bean을 생성할 클래스 경로" id="아이디" />

    => 설정파일 불러오기

        - GenericXmlApplicationContext 변수 = new GenericXmlApplicationContext("설정파일경로");

    => Bean을 가져오는 자바코드는 이전과 동일

 

1. src 디렉토리에 SpringBeanConfiguration 파일을 추가

    => applicationContext.xml

 

2. Good 클래스의 Bean 을 생성하는 코드를 추가

<!-- domain.Good 클래스의 bean을 생성하는 코드 -->
<bean class="domain.Good" id="good"></bean>
//XML을 이용하여 Bean을 생성
GenericXmlApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
Good good = context.getBean("good", Good.class);
good.setNum(1);
good.setName("사과");
System.out.println(good);
		
Good good1 = context.getBean("build", Good.class);
good1.setNum(2);
good1.setName("수박");
System.out.println(good1);
		
//해시코드 출력
System.out.println(System.identityHashCode(good));
System.out.println(System.identityHashCode(good1));
		
//상수는 상수 풀에 저장하고 풀에 저장한 상수의 참조를 변수에 저장
int a = 10;
int b =10;
System.out.println(System.identityHashCode(a));
System.out.println(System.identityHashCode(b));
		
context.close();

 

**Bean 태그

    => 클래스를 등록해서 인스턴스를 생성하기 위한 태그

1. id 속성 : 구분하기 위한 식별자로 설정하지 않으면 클래스명#0으로 설정

2. class 속성 : 생성할 인스턴스의 클래스 경로(필수)

3. name 속성 : id에 대한 별명인데 특수문자가 가능

4. init-method : 초기화 메소드 이름을 설정

    => 초기화 내용을 생성자에 작성, 직접 인스턴스 생성없이 컨테이너나 프레임워크가 생성하는 경우, 별도 제공되는 초기화 메소드를 이용

5. destroy-method : 소멸될때 호출되는 메소드

6. lazy-init : 지연생성 여부로 true or false로 설정(default -> false)

    => 지연생성은 처음부터 만들어두는 것이 아니고 처음 사용할 때 만드는 것

    => Server Application은 일반적으로 lazy-init을 하지않고, Client Application을 만들때 lazy-init을 사용

    => SPA(Single Page Application)를 만들 때도, lazy-loading을 고려해야 함

7. scope : 기본값은 singleton인데, request, session등을 설정할 수 있음

8. abstract : 추상클래스 여부를 설정하는 것인데 기본값은 false

9. factory-method : 생성자가 아닌 메소드를 이용하여 인스턴스를 생성할 때 메소드명을 설정하는 것

 

**Spring DI

1. DI(Dependency Injection) : 의존성 주입

    =>클래스 내에서 사용하는 타클래스의 인스턴스를 클래스 외부(프레임워크, 컨테이너)에서 대입받아 사용

 

2. 의존성 주입의 구현방법

  1) 생성자를 이용하는 방법

  2) setter(property)를 이용하는 방법

    => 사용은 변수를 하는 것처럼 보이지만 실제로는 getter와 setter 매소드를 이용하는 것을 property라고 함

 

3. Bean에서의 의존성 설정

  1) 생성자를 이용하는 방법

    - <bean id="" class="">

            <constructor-arg value="값"/>

      </bean>

    => 값이 생성자에 대입됨

    => constructor-arg는 여러개 사용 가능

    => indec라는 속성을 이용해서 순서를 정하여 대입하는 것도 가능

    => Type이라는 속성을 이용해서 값의 자료형도 설정가능

        - 미설정시 기본적으로 String이지만 적당하게 형 변환하여 대입

    => class 에 매개변수를 대입받는 생성자가 존재해야 함

 

**DI 실습

    => DTO, DAO, service, Controller 클래스를 만들어서 작업 수행

    => DTO는 DAO나 Service에서 사용

    => DAO는 Service가 사용

    => service는 Controller가 사용

1. DTO 클래스로 사용할 domain.Good 클래스 생성

package domain;

public class Good {
	private int num;
	private String name;
	
	public Good() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public Good(int num, String name) {
		super();
		this.num = num;
		this.name = name;
	}
	
	public int getNum() {
		return num;
	}
	public void setNum(int num) {
		this.num = num;
	}
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@Override
	public String toString() {
		return "Good [num=" + num + ", name=" + name + "]";
	}
	
}

 

2. DAO 클래스를 생성 - DAO에도 템플릿 메소드 패턴을 적용하기도 함

public class GoodDao {
	//메소드
	//상세보기를 위한 메소드
	//기본키를 매개변수로 받아서 하나의 DTO를 생성하여 리턴
	public Good detail(int num) {
		Good good = new Good();
		good.setNum(1);
		good.setName("망고");
		
		return good;
	}
}

 

3. Service 인터페이스를 생성하고 메소드를 선언

    => service.Good.Service

package service;

public interface GoodService {
	//상세보기를 처리할 메소드
	public void detail();
}

 

4. Setrvice 인페이스를 implement한 ServiceImpl 클래스를 생성 

    => service.GoodServiceImpl

package service;

import dao.GoodDao;

public class GoodServiceImpl implements GoodService {
	//DAO 변수를 선언
	private GoodDao goodDao;
	
	public GoodServiceImpl() {
		super();
		//사용할 인스턴스를 직접 생성하면 의존성 주입이 아님
		goodDao = new GoodDao();
	}

	public GoodServiceImpl(GoodDao goodDao) {
		super();
		//직접 생성하지 않고 매개변수로 받은 것을 대입
		//이렇게 외부로부터 받은 것을 대입하는 것을 의존성 주입이라고 함
		this.goodDao = goodDao;
	}

	public GoodDao getGoodDao() {
		return goodDao;
	}

	//외부로부터 매개변수로 받아서 인스턴스 변수에 대입하면 의존성 주입
	public void setGoodDao(GoodDao goodDao) {
		this.goodDao = goodDao;
	}

	@Override
	public void detail() {
		System.out.println(goodDao.detail(1));
	}

}

 

5. Controller로 사용할 클래스를 생성

    => Controller.GoodController : 하나의 Controller : 하나의 Controller로 전부 처리시 이름을 Front Controller라고 함

        - 여러개의 Controller로 나눌때는 서비스이름Controller라고 함

package controller;

import service.GoodService;
import service.GoodServiceImpl;

public class GoodController {
	//Service 인스턴스를 저장할 변수 생성
	private GoodService goodService;

	public GoodController() {
		super();
		goodService = new GoodServiceImpl();
	}

	public GoodController(GoodService goodService) {
		super();
		this.goodService = goodService;
	}

	public GoodService getGoodService() {
		return goodService;
	}

	public void setGoodService(GoodService goodService) {
		this.goodService = goodService;
	}
	
	//상세보기를 위한 메소드
	public void detail() {
		goodService.detail();
	}
}

 

6. main 메소드를 소유한 클래스를 생성해서 실행코드를 작성하고 이용

public class main {

	public static void main(String[] args) {
		//Dao 인스턴스를 생성
		GoodDao goodDao = new GoodDao();
		
		//Service 인스턴스를 생성
		//이렇게 하면 생성자를 이용한 주입이라고 함
		//GoodService goodService = new GoodServiceImpl(goodDao);
		
		//프로퍼티를 이용한 주입 - setter 메소드 이용
		GoodServiceImpl goodService = new GoodServiceImpl();
		goodService.setGoodDao(goodDao);
		
		//Controller를 인스턴스를 생성
		GoodController goodController = new GoodController(goodService);
		goodController.detail();
	}

}

 

7. 일반적인 응용프로그램은 위처럼 인스턴스를 직접 생성해서 생성자나 setter를 이용해서 주입하고 사용

 

 

**Spring에서의 의존성 주입

1. 생성자를 이용한 주입

<bean class="클래스 경로" id="구별하기 위한 식별자">
	<constructor-arg value="값"/>
</bean>

    => constructor-arg는 여러개 설정 가능

 

2. SpringBeanConfiguration 파일을 추가하고 Good 클래스의 bean을 생성하는 코드 작성

<!-- 매개변수가 없는 생성자(Default Constructor)를 이용해서 bean 생성 -->
<bean class="domain.Good" id="good"></bean>

 

3. main메소드에서 위의 bean을 가져와서 사용하는 코드를 작성

GenericXmlApplicationContext context = new GenericXmlApplicationContext("applicationContext.xml");
Good good = context.getBean("good", Good.class);
System.out.println(good);
context.close();

 

4. 실행결과

    => 매개변수가 없는 생성자를 만들었기 때문에 기본값으로 출력

 

5. bean 생성 코드 변경

<!-- 매개변수가 있는 생성자를 이용 -->
<bean class="domain.Good" id="good">
	<constructor-arg value="1" />
	<constructor-arg value="수박" />
</bean>

 

6. 실행 후 결과

    => 생성자를 이용해서 값을 대입했기 때문에 대입한 값이 출력

 

7. value 대신에 다른 bean의 아이디를 설정하는 것도 가능

<constructor-arg>
	<ref bean="다른 bean의 id" />
</constructor-arg>

 

8. Good 클래스의 bean을 만드는 코드 수정

 <!-- 다른 bean의 id 설정 -->
 <bean class="java.lang.String" id="name">
 	<constructor-arg value="무화과" />
 </bean>
 <bean class="domain.Good" id="good">
	<constructor-arg value="1" />
	<constructor-arg>
		<ref bean = "name"/>
	</constructor-arg>
</bean>

 

9. Property를 이용한 주입

<bean class="" id="">
	<property name="프로퍼티명" value="값" />
</bean>

    => 프로퍼티명은 변수명이 아니고 setter 메소드에서 set을 제거하고 첫글자를 소문자로 변경한 것

    => value 대신에 ref bean을 사용하는 것이 가능

 

10. Good 클래스의 bean 생성 코드 변경

<!-- 프로퍼티를 이용한 의존성 주입 -->
<bean class="java.lang.String" id="name">
	<constructor-arg value="오렌지" />
</bean>
<bean class="domain.Good" id="good">
	<property name="num" value="3"/>
	<property name="name" >
		<ref bean="name"/>
	</property>
</bean>

 

11. c와 p NameSpace 이용

    => c와 p NameSpace를 추가하면 별도의 태그가 아니라 속성으로 생성자와 프로퍼티를 이용한 주입이 가능

    => bean 태그 안에 p:프로퍼티명 = "값" 또는 p:프로퍼티명-ref="다른 bean의 ID"로 설정

        - 생성자를 이용하는 경우면 p 대신에 c를 사용

 

12. 네임스페이스 이용

  1) c와 p 네임스페이스 추가

 

  2) bean 생성 코드를 수정

<!-- p Namespace 이용 -->
<bean class="domain.Good" id="good"  p:num="5" p:name-ref="name"/>

 

**Collection Type 설정(List, Set, Map, Properties)

1. List(데이터를 순서대로)

<list value-type="요소의 자료형">
	<value>값</value>
    <value>값</value> 
    ...
</list>    

 

2. Set(데이터를 빠르게 조회하기 위해 인덱스를 생성하여 저장)

<set value-type="요소의 자료형">
	<value>값</value>
    <value>값</value> 
    ...
</set>    

 

3. Map(Dictionary라고도 하는데 Key와 Value쌍으로 데이터를 저장)

<map>
	<entry>
    	<key>키</key>
        <value>값</value>
    </entry>
    <entry key="키" value="값" />
</map>

 

4. Properties(Map처럼 Key 와 Value를 쌍으로 저장하는데, Key 와 Value 모두 String 만 가능)

<props>
	<prop key="키">값</prop>
    <prop key="키">값</prop>
</props>

 

**annotation을 이용한 IoC와 DI 설정

1. XML 설정파일과 Annotation을 혼합해서 사용하고자 하는 경우

    => spring bean configuration 파일에 context 네임스페이스를 추가하고, <context:annotation-config/>를 추가

 

2.  @Autowired

    => 변수위에 사용, 어노테이션이 추가되면 자동으로 setter를 생성하고 동일한 자료형의 bean이 있으면 자동 주입

    => 이 어노테이션이 설정되어 있는데 동일한 자료형의 bean이 없으면 예외가 발생(주입하는데 실패(메시지))

        - @Autowired(required=false)로 설정히 없어도 예외가 발생하지 않음

    => 동일한 자료형의 bean이 2개 이상 존재한다면 이 경우도 애매모호하다고 예외를 발생시킴

        - @Autowired(name="bean의 id")로 설정시 id가 일치하는 bean을 주입받음

    => 동일한 역할을 수행하는 어노테이션으로 @Inject, @Resource(name="bean의 id")-java1.8부터 지원

 

3. bean을 자동생성해주는 어노테이션

    => spring bean configuration에 <context:component-scan="패키지명"/> 설정시, 패키지명에 해당하는 모든 하위

        패키지에서 @Component, @Repository, @Service, @Controller 어노테이션이 붙은 클래스의 bean을 자동 생성

        - 패키지 명은 여러개 사용 가능

 

4. Spring Project를 만들어서 작업을 할 때는 하나의 루트 패키지를 만들고 그 안에 세부 패키지들을 만들어 작업 수행

 

5. 가장 중요한 것

    - bean을 생성하는 기본적인 방법

    - Controller, Service, Repository, Component를 이용한 Bean생성

    - Autowired 설정

 

 

 

Tip!

1. 프로젝트 할 때 Junit Test 꼭 사용하기

    => 단위테스트시 가장 많이 사용됨