**IoC(Inversion Of Control - 제어의 역전)
=>객체지향 프로그래밍의 기본적인 원리는 클래스를 만들고 이 클래스로부터 객체를 생성해서 사용하는 것입니다.
=>사용하려는 객체의 용도 또는 방법에 따라서 클래스를 디자인 해야 합니다.
=>이렇게 클래스를 사용하려는 용도나 방법에 따라 디자인 하는 것을 디자인 패턴이라고 합니다.
=>클래스는 일반적인 형태로 비지니스 로직만 구현하도록 개발자가 만들고 디자인 패턴의 적용은 컨테이너나 프레임워크가 해서 객체를 만들어주는 방식
=>Spring에선느 IoC의 구현을 어노테이션(@ - 결국은 자바코드로 변환)을 이용하는 방법과 xml 파일을 이용하는 방법(자바 코드로 변환) 2가지를 제공합니다.
1.xml 파일에 객체를 생성하는 코드
<bean class="객체를 생성하고자 하는 클래스의 전체 경로" id="구분하는 이름"></bean>
2.application project 일 때는 xml 파일을 직접 읽지만 web project일 때는 web.xml 파일에 xml 파일을 읽도록 설정을 합니다.
=>직접 읽어서 객체를 생성하기
| GenericXmlApplicationContext 변수 = new GenericXmlApplicationContext("xml 파일 경로"); | cs |
=>파일 경로는 classpath:파일경로를 적는데 classpath는 src/main/resources 또는 src/main/java 인데 나중에 두 개의 디렉토리는 하나로 합쳐지기 때문에 위치는 관계없습니다.
=>파일을 읽으면 bean 태그로 만들어진 객체들은 전부 싱글톤 패턴으로 생성됩니다.
3.bean으로 만들어진 객체 사용
| 자료형 객체이름 = 변수.getBean("bean의 아이디", 클래스이름.class); | cs |
=>getBean을 호출할 때 아이디를 생략하면 클래스이름으로 만들어진 bean을 찾아서 대입
=>bean의 아이디만 입력하고 클래스이름을 생략하면 이 때는 Object 타입으로 리턴되기 때문에 강제 형 변환을 해서 사용해야 합니다.
**IoC 실습
1.Simple Spring Maven Project 를 생성
2.pom.xml 파일에서 Spring Version 변경 - 4.2.4, 4.1.0, 4.0.4, 4.0.1
<!-- Spring -->
| <spring-framework.version>4.2.4.RELEASE</spring-framework.version> | cs |
3.Java Version 변경
=>프로젝트를 선택하고 마우스 오른쪽을 클릭해서 [Properties]
=>[Project Facets]에서 Java Version 변경
1.1 -> 1.2 -> 1.5(Generic, Annotation) -> 1.8(Lambda, stream API)
-> 1.6(현재 전자정부 프레임워크 표준) -> 1.8
4.IoC 와 DI에 이용할 VO 클래스 생성 - domain.MemberVO
| package domain; public class MemberVO { private String email; | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | private String name; //email 과 name 프로퍼티 생성 public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } //디버깅을 위한 메소드 @Override public String toString() { return "MemberVO [email=" + email + ", name=" + name + "]"; } } | cs |
5.bean을 만들어주는 Spring Bean Configuration 파일을 생성하고 MemberVO 클래스의 bean 생성코드를 작성
=>src/main/resources 디렉토리에 applicationContext.xml
=>bean을 만들 때 id 설정은 대부분 클래스이름을 그대로 적고 첫 글자만 소문자로 변경하는 것이 관례입니다.
| <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | cs |
| xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> | cs |
| <bean id="memberVO" class="domain.MemberVO"></bean> </beans> | cs |
6.application을 실행할 수 있도록 하기 위해서 main 메소드를 소유한 클래스를 만들고 main 메소드에 5번에서 만든 applicationContext.xml 파일을 읽는 코드를 작성
| import org.springframework.context.support.GenericXmlApplicationContext; | cs |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import domain.MemberVO; public class Main { public static void main(String[] args) { //스프링 빈 설정 파일을 읽어서 실행 GenericXmlApplicationContext context = new GenericXmlApplicationContext( "classpath:applicationContext.xml"); //설정 파일에 만든 memberVO라는 id를 가진 bean을 //MemberVO 타입으로 변환해서 가져오기 MemberVO memberVO = context.getBean("memberVO", MemberVO.class); memberVO.setEmail("ggangpae1@gmail.com"); memberVO.setName("박문석"); System.out.println(memberVO); //스프링 빈 설정 파일이 생성한 모든 객체 삭제하기 context.close(); } } | cs |
DI(Dependency Injection = 의존성 주입 )
=>의존성 주입(Dependency Injection, DI)은 프로그래밍에서 구성요소간의 의존 관계가 소스코드 내부가 아닌 외부의 설정파일 등을 통해 정의되게 하는 디자인 패턴 중의 하나이다. -위키피디아
=> 인스턴스 변수에 외부에서 생성한 데이터를 대입
=> Contructor (생성자)를 이용하는 방법과 Property(setter)를 이용하는 방법 2가지가 있습니다.
=> Constructor를 이용하는 방법은 객체를 생성할 때 외부에서 대입받는 것이고 Property를 이용하는 방법은 필요할 때 대입받는 방법입니다.
=> Constructor를 이용하는 방법은 처음부터 만들어서 소유하고 있기 떄문에 호출 속도가 빠르다는 장점은 있지만무거워질 가능이 있습니다.
Property를 이용하는 방법은 필요할 때 만들기 때문에 호출 속도가 느리다는 단점이 있지만 프로그램이 가벼워진다는 장점이 있습니다 .
1. 생성자를 이용하는 DI
| <bean id = "빈의 아이디" class="클래스 경로"> <constructor-arg value="값"> </constructor-arg> 또는 <constructor-arg ref="다른 bean의 아이디"> </constructor-arg> </bean> | cs |
=> 생성자를 이용하는 방법을 사용할 때는 클래스에 매개변수
2. 생성자 만들기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* Object super; */ // Default Contructor 매개변수가 없는 생성자 public MemberVo() { super(); // super =new Obejct(); this=new Member(); } // 그렇기에 그만 큼 속도에서 이득 볼수 있는게 생성자이다 public MemberVo(String email) { super(); this.email = email; } // 메서드 원형을 얘기할 때는 변수명은 안들어간다 public MemberVo(String email, String name) { super(); this.email = email; this.name = name; } public MemberVo(String email, String name, String addr) { super(); this.email = email; this.name = name; this.addr = addr; } | cs |
3. applicationContext.xml 파일에 매개변수가 있는 생성자를 이용해서 bean을 만드는 코드를 추가
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <bean id="memberVo" class="domain.MemberVo"></bean> <!-- new MemberVo(String email)로 생성 --> <bean id="memberVo1" class="domain.MemberVo"> <constructor-arg value="jessica72@naver.com"></constructor-arg> </bean> <!-- new MemberVo(String email String name)로 생성 --> <bean id="memberVo2" class="domain.MemberVo"> <constructor-arg value="hunt72@naver.com"></constructor-arg> <constructor-arg value="헌트"></constructor-arg> </bean> <!-- new MemberVo(String email, String name, String addr)로 생성 --> <bean id="memberVo3" class="domain.MemberVo"> <constructor-arg value="tae72@naver.com"></constructor-arg> <constructor-arg value="태연"></constructor-arg> <constructor-arg value="한국"></constructor-arg> </bean> </beans> | cs |
4. applicationContext.xml 파일에서 생성자의 매개변수에 값을 직접 대입하지 않고 다른 bean의 id를 대입해서 의존성 주입
| // ref와 value의 사용 때는 재사용을 해야할 것같을 때 ref, <bean id="memberVo3" class="domain.MemberVo"> <constructor-arg value="tae72@naver.com"></constructor-arg> <!-- <constructor-arg value="태연"></constructor-arg> --> <constructor-arg ref= "name"></constructor-arg> <constructor-arg value="한국"></constructor-arg> </bean> <!-- String name = new String("헌트") 까지 한 것 --> <bean id="name" class="java.lang.String"> <constructor-arg value="태연"></constructor-arg> </bean> | cs |
6.main을 실행
====================================
****IoC 실습
1.Simple Spring Maven Project 를 생성
2.pom.xml 파일에서 Spring Version 변경 - 4.2.4, 4.1.0, 4.0.4, 4.0.1
<!-- Spring -->
<spring-framework.version>4.2.4.RELEASE</spring-framework.version>
3.Java Version 변경
=>프로젝트를 선택하고 마우스 오른쪽을 클릭해서 [Properties]
=>[Project Facets]에서 Java Version 변경
1.1 -> 1.2 -> 1.5(Generic, Annotation) -> 1.8(Lambda, stream API)
-> 1.6(현재 전자정부 프레임워크 표준) -> 1.8
4.IoC 와 DI에 이용할 VO 클래스 생성 - domain.MemberVO
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | package domain; public class MemberVO { private String email; private String name; //email 과 name 프로퍼티 생성 public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } public String getName() { return name; } public void setName(String name) { this.name = name; } //디버깅을 위한 메소드 @Override public String toString() { return "MemberVO [email=" + email + ", name=" + name + "]"; } } | cs |
5.bean을 만들어주는 Spring Bean Configuration 파일을 생성하고 MemberVO 클래스의 bean 생성코드를 작성
=>src/main/resources 디렉토리에 applicationContext.xml
=>bean을 만들 때 id 설정은 대부분 클래스이름을 그대로 적고 첫 글자만 소문자로 변경하는 것이 관례입니다.
| <?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="memberVO" class="domain.MemberVO"></bean> </beans> | cs |
6.application을 실행할 수 있도록 하기 위해서 main 메소드를 소유한 클래스를 만들고 main 메소드에 5번에서 만든 applicationContext.xml 파일을 읽는 코드를 작성
import org.springframework.context.support.GenericXmlApplicationContext;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import domain.MemberVO; public class Main { public static void main(String[] args) { //스프링 빈 설정 파일을 읽어서 실행 GenericXmlApplicationContext context = new GenericXmlApplicationContext( "classpath:applicationContext.xml"); //설정 파일에 만든 memberVO라는 id를 가진 bean을 //MemberVO 타입으로 변환해서 가져오기 MemberVO memberVO = context.getBean("memberVO", MemberVO.class); memberVO.setEmail("ggangpae1@gmail.com"); memberVO.setName("박문석"); System.out.println(memberVO); //스프링 빈 설정 파일이 생성한 모든 객체 삭제하기 context.close(); } } | cs |
**DI(Dependency Injection = 의존성 주입 )
=> 인스턴스 변수에 외부에서 생성한 데이터를 대입
=> Contructor (생성자)를 이용하는 방법과 Property(setter)를 이용하는 방법 2가지가 있습니다.
=> Constructor를 이용하는 방법은 객체를 생성할 때 외부에서 대입받는 것이고 Property를 이용하는 방법은 필요할 때 대입받는 방법입니다.
=> Constructor를 이용하는 방법은 처음부터 만들어서 소유하고 있기 떄문에 호출 속도가 빠르다는 장점은 있지만무거워질 가능이 있습니다.
Property를 이용하는 방법은 필요할 때 만들기 때문에 호출 속도가 느리다는 단점이 있지만 프로그램이 가벼워진다는 장점이 있습니다 .
1. 생성자를 이용하는 DI
| <bean id = "빈의 아이디" class="클래스 경로"> <constructor-arg value="값"> </constructor-arg> 또는 <constructor-arg ref="다른 bean의 아이디"> </constructor-arg> </bean> | cs |
=> 생성자를 이용하는 방법을 사용할 때는 클래스에 매개변수
2. 생성자 만들기
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | /* Object super; */ // Default Contructor 매개변수가 없는 생성자 public MemberVo() { super(); // super =new Obejct(); this=new Member(); } // 그렇기에 그만 큼 속도에서 이득 볼수 있는게 생성자이다 public MemberVo(String email) { super(); this.email = email; } // 메서드 원형을 얘기할 때는 변수명은 안들어간다 public MemberVo(String email, String name) { super(); this.email = email; this.name = name; } public MemberVo(String email, String name, String addr) { super(); this.email = email; this.name = name; this.addr = addr; } | cs |
3. applicationContext.xml 파일에 매개변수가 있는 생성자를 이용해서 bean을 만드는 코드를 추가
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <bean id="memberVo" class="domain.MemberVo"></bean> <!-- new MemberVo(String email)로 생성 --> <bean id="memberVo1" class="domain.MemberVo"> <constructor-arg value="jessica72@naver.com"></constructor-arg> </bean> <!-- new MemberVo(String email String name)로 생성 --> <bean id="memberVo2" class="domain.MemberVo"> <constructor-arg value="hunt72@naver.com"></constructor-arg> <constructor-arg value="헌트"></constructor-arg> </bean> <!-- new MemberVo(String email, String name, String addr)로 생성 --> <bean id="memberVo3" class="domain.MemberVo"> <constructor-arg value="tae72@naver.com"></constructor-arg> <constructor-arg value="태연"></constructor-arg> <constructor-arg value="한국"></constructor-arg> </bean> </beans> | cs |
4. applicationContext.xml 파일에서 생성자의 매개변수에 값을 직접 대입하지 않고 다른 bean의 id를 대입해서 의존성 주입
| // ref와 value의 사용 때는 재사용을 해야할 것같을 때 ref, <bean id="memberVo3" class="domain.MemberVo"> <constructor-arg value="tae72@naver.com"></constructor-arg> <!-- <constructor-arg value="태연"></constructor-arg> --> <constructor-arg ref= "name"></constructor-arg> <constructor-arg value="한국"></constructor-arg> </bean> <!-- String name = new String("헌트") 까지 한 것 --> <bean id="name" class="java.lang.String"> <constructor-arg value="태연"></constructor-arg> </bean> | cs |
6.main을 실행
====================================
**Property(변수 + getter 와 setter : 속성 ) 를 이요한 DI
====================================
=> set 메소드를 이용해서 인스턴스 변수에 데이터를 대입
=> 생성자를 이용하는 것보다 느리게 만들어지지만 메모리 부담은 줄어듭니다.
python과 C#에서는 변수.변수명 으로 불러서 프로퍼리를 할수 있게 해줍니다.
| <bean id="빈의 아이디" class="클래스의 경로"> <property name="프로퍼리이름" value="값"> </property> <property name="프로퍼티이름" ref="다른 bean의 아이디"></property> </bean> | cs |
=>프로퍼티이름은 변수명이 아니며, setter 메소드에서 set을 제외하고 나머지 문자열의
첫글자만 소문자로 변경합니다.
=>MemberVo 는 2개의 프로퍼티가 존재합니다.
1. applicationContext.xml 파일에 property에 의존성 주입하는 bean을 생성하는 코드를 작성
| <bean id = "memberVo4" class="domain.MemberVo"> <property name="email" value="tstigma@naver.com"></property> <property name="name" ref="second"></property> </bean> <bean id = "second" class="java.lang.String"> <constructor-arg value="armor"></constructor-arg> </bean> | cs |
2.main 메소드에서 bean을 가져오는 코드를 작성하고 실행
| MemberVo memberVo4 = context.getBean("memberVo4",MemberVo.class); System.out.println(memberVo4); | cs |
======================================================
namespace
======================================================
**namespace(이름공간)를 이용하면 constructor-arg 나 property태그 대신에 bean을 생성하는 코드 내부에 속성으로 값을 대입할 수 있습니다.
c와 p네임스페이스를 추가하면 됩니다.
코드를 간결하게 만들기 위해 사용합니다.
1.applicationContext.xml 파일에 c와 p 네임스페이스 추가
2.applicationContext.xml 파일에 c와 p 네임스페이스를 이용한 bean 생성 코드 추가
| <!-- MemberVO memberVO4 = new MemberVO("abc@gmail.com", "조헌"); --> <bean id="memberVO4" class="domain.MemberVO" c:email="abc@gmail.com" c:name="조헌"/> <!-- MemberVO memberVO5 = new MemberVO(); memberVO5.setEmail("efg@gmail.com"); memberVO5.setName("강감찬")--> <bean id="memberVO5" class="domain.MemberVO" p:email="efg@gmail.com" p:name="강감찬" /> | cs |
=======================================================
Collection을 주입받기 위한 예제
1. 4개의 Collection을 인스턴스 변수로 갖는 클래스 생성
domain.CollectionDI
2.SpringBeanConfiguration 파일을 생성하고 CollectionDI 객체를 생성해주는 bean 코드를 추가
=>src/main/resources 디렉토리의 collection.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <?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="collectionDI" class="domain.CollectionDI"> <property name="list"> <list> <value>배열</value> <value>ArrayList</value> <value>LinkedList</value> <value>Stack</value> <value>Queue</value> <value>Deque</value> </list> </property> <property name="set"> <set> <value>HashSet</value> <value>LinkedHashSet</value> <value>TreeSet</value> </set> </property> <property name="properties"> <props> <prop key="Encapsulation">캡슐화</prop> <prop key="Inheritance">상속성</prop> <prop key="Polymorphism">다형성</prop> </props> </property> <property name="map"> <map> <entry> <key><value>Encapsulation</value></key> <value>클래스를 만드는 것</value> </entry> <entry> <key><value>Inheritance</value></key> <value>하위 클래스가 상위 클래스의 모든 것을 물려받는 것</value> </entry> <entry> <key><value>Polymorphism</value></key> <value>동일한 메시지에 대하여 다르게 반응하는 성질</value> </entry> </map> </property> </bean> </beans> | cs |
**일반적인 프로그램 구조
domain class, DAO---> Service ----> Controller --- > View
=>ApplicationProgramming 에서는 Controller의 역할을 Main이 합니다.
1. spring과 java version 바꿉니다.
2. Spring과 Java 버전 설정
3. VO로 사용할 클래스 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 | package domain; public class Board { private int num ; private String id; private String name; private String subject; private String content; private int readcount; private String writedate ; //작성일 ㅁ public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public int getReadcount() { return readcount; } public void setReadcount(int readcount) { this.readcount = readcount; } public String getWritedate() { return writedate; } public void setWritedate(String writedate) { this.writedate = writedate; } @Override public String toString() { return "Board [num=" + num + ", id=" + id + ", name=" + name + ", subject=" + subject + ", content=" + content + ", readcount=" + readcount + ", writedate=" + writedate + "]"; } } | cs |
4. Board 테이블과 연동하는 메소드를 소유한 BoardDao 클래스를 생성하고 메소드 작성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package dao; import domain.Board; public class BoardDao { public Board get(int num) { Board board = new Board(); board.setNum(num); board.setId("dispo0"); board.setName("관리자"); board.setSubject("공지사항"); board.setContent("미세먼지 조심하세요 "); board.setReadcount(1); board.setWritedate("2018-04-07"); return board; } } | cs |
5.실제 비지니스 로직의 메소드 원형을 소유한 Service 인터페이스 생성
=>service.BoardService
| package service; import domain.Board; public interface BoardService { public Board get(int num); } | cs |
6.비지니스 로직을 구현할 ServiceImpl 클래스를 생성하고 메소드 구현
=>service.BoardServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package service; import dao.BoardDao; import domain.Board; public class BoardServiceImpl implements BoardService { //BoardDao 참조형 변수 private BoardDao boardDao; //접근자 메소드 public BoardDao getBoardDao() { return boardDao; } public void setBoardDao(BoardDao boardDao) { this.boardDao = boardDao; } //비지니스 로직을 수행하는 메소드 @Override public Board get(int num) { return boardDao.get(num); } } | cs |
7.클라이언트의 요청을 받아서 적절한 비지니스 로직 처리 메소드를 호출하는 Controller를 생성하고 메소드 작성
=>controller.BoardController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package controller; import domain.Board; import service.BoardService; public class Controller { private BoardService boardService; public BoardService getBoardService() { return boardService; } public void setBoardService(BoardService boardService) { this.boardService = boardService; } public Board doGet(int num) { return boardService.get(num); } } | cs |
8.main 메소드를 소유한 Main 클래스를 만들어서 실행 코드를 작성하고 실
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import controller.BoardController; import dao.BoardDao; import domain.Board; import service.BoardServiceImpl; public class Main { public static void main(String[] args) { //BoardDao 객체 생성 BoardDao boardDao = new BoardDao(); //BoardService 객체 생성 BoardServiceImpl boardService = new BoardServiceImpl(); //BoardDao 객체 주입 boardService.setBoardDao(boardDao); //BoardController 객체 생성 BoardController boardController = new BoardController(); //BoardService 객체 주입 boardController.setBoardService(boardService); Board board = boardController.doGet(101); System.out.println(board); } } | cs |
9.객체를 singleton으로 생성할 수 있도록 해주는 설정 파일을 추가
src/main/resources 디렉토리에 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="boardDao" class="dao.BoardDao"></bean> <bean id="boardService" class="service.BoardServiceImpl"></bean> <bean id="boardController" class="controller.BoardController"></bean> </beans> | cs |
10.main 메소드를 수정하고 실행
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package main; import org.springframework.context.support.GenericXmlApplicationContext; import controller.Controller; import dao.BoardDao; import domain.Board; import service.BoardServiceImpl; public class Main { public static void main(String[] args) { GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:applicationContext.xml"); // BoardDao 객체 생성 BoardDao boardDao = context.getBean(BoardDao.class); // BoardSerivce 객체 생성 BoardServiceImpl boardservice = context.getBean(BoardServiceImpl.class); // BoardDao 객체 주입 boardservice.setBoardDao(boardDao); // 컨트롤 객체 생성 Controller boardController = context.getBean(Controller.class); // boardService 객체 주입 boardController.setBoardService(boardservice); Board board = boardController.doGet(101); System.out.println(board); } } | cs |
11. IOC만 적용한 경우
=>Spring의 Ioc를 적용하면 Spring이 생성하는 객체는 전부 Singleton 패턴으로 만들어지고 실행할 때 객체를 모두 생성해서 사용가능하도록 해줍니다.
context.close하면 메모지 정리를 전부다 해줍니다.
12.applicationContext.xml 파일에 property를 이용해서 BoardService 객체에는 Boardao 객체를 BoardContoller 객체에는 BoardService 객체를
주입하는 코드를 작성 -DI 적용
| <bean id="boardDao" class="dao.BoardDao"> </bean> <bean id="boardService" class="service.BoardServiceImpl"> <property name="boardDao" ref="boardDao"></property> </bean> <bean id="boardContoller" class="controller.Controller"> <property name="boardService" ref="boardService"></property> </bean> | cs |
13.main 메소드를 수정하고 실행
| public static void main(String[] args) { GenericXmlApplicationContext context = new GenericXmlApplicationContext( "classpath:applicationContext.xml"); // 컨트롤 객체 생성 Controller boardController = context.getBean(Controller.class); Board board = boardController.doGet(101); System.out.println(board); context.close(); } | cs |
14.Spring DI를 이용하면 실해앟고자 하는 크랠스의 객체만 만들어서 필요한 메소드를 호출하기만 하면됩니ㅏㄷ.
중간에 대입하고 하는 과정응ㄴ 새략해도 됩니다.
**annotation과 xml 의 혼용
=>spring bean configuration 파일에 context 네임스페이스를 추가하고
<context:annotation-config>태그를 추가해야 합니다.
@Autowired
=>인스턴스 변수 위에 어노테이션을 추가하면 setter를 자동생성해주고 동일한 자료형의 bean이 있으면 자동으로 대입해줍니다.
=> 동일한 자료형이 없으면 , 동일한 자료형이 두개 있으면 어떻게 되느냐 ?
자료형이 없으면, 주입할 수 없다
동일한 자료형이 두개 있으면 연결불가능 qualifying bean of type
2.BoardServiceImpl 클래스에 있는 BoardDao 참조형 변수 위에 @Autowired를 추가하고 접근자 메소드를 제거
3.BoardController 클래스에 있는 BoardService 참조형 변수 위에 @Autowired를 추가하고 접근자 메소드를 제거
4.applicationContext.xml 파일에 context 네임스페이스 추가
5.applicationContext.xml 파일에 <context:annotation-config/> 추가
6.property를 이용한 di 코드를 제거
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?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.2.xsd"> <!-- annotation을 적용하기 위한 태그 --> <context:annotation-config /> <bean id="boardDao" class="dao.BoardDao"></bean> <bean id="boardService" class="service.BoardServiceImpl"> </bean> <bean id="boardController" class="controller.BoardController"> </bean> </beans> | cs |
7. @Autowired 사용시 주의 할점
1) AutoWired가 설정된 참조형 변수의 bean이 없는 경우
NoSuch로 시작하는 예외가 발생
2) 동일한 자료형으로 2개 이상 만들어진 경우 : NoUnique로 시작하는 예외가 발생하는데
이 문제를 해결하는 방법으로는 @Autowired 아래에 @Qualifier ("빈의 아이디")를 추가 하면됩니다.
8. Autowired 대신에 Resource(name="빈의 아이디")를 사용할 수 있고 inject 라이브러리를 추가하면
@inject를 사용할 수 있습니다.
bean 자동 생성
=>spring bean configuration 파일에 <context:component-scan base-package="패키지이름"/> 태그가 존재하면 패키지이름 하위에 존재하는 클래스 들 중에서 @Component, @Controller, @Service, @Repository 어노테이션이 있는 클래스들의 bean을 자동 생성해 줍니다.
=>@Component는 모든 클래스에 추가가 가능한데 Controller, Service, Repository는 역할에 맞게 추가해야 합니다.
=>id는 클래스이름의 첫글자만 소문자로 변경한 것으로 자동 설정됩니다.
1.controller, service, dao 패키지 안에 있는 클래스들을 board 패키지를 생성해서 안으로 전부 이동
2.BoardDao, BoardServiceImpl, BoardController 클래스 위에 @Component 어노테이션을 추가
3.applicationContext.xml 파일에 3개의 클래스 bean 태그를 제거
4.applicationContext.xml 파일에 @Component가 붙은 클래스들의 bean을 자동생성해주는 태그를 추가
<!-- board 패키지에 있는 클래스들 중에서
@Component(Controller, Service, Repository)가 붙은
클래스들의 bean을 자동 생성 -->
<context:component-scan base-package="board" />
====================================
=> set 메소드를 이용해서 인스턴스 변수에 데이터를 대입
=> 생성자를 이용하는 것보다 느리게 만들어지지만 메모리 부담은 줄어듭니다.
python과 C#에서는 변수.변수명 으로 불러서 프로퍼리를 할수 있게 해줍니다.
<bean id="빈의 아이디" class="클래스의 경로">
<property name="프로퍼리이름" value="값"> </property>
<property name="프로퍼티이름" ref="다른 bean의 아이디"></property>
</bean>
=>프로퍼티이름은 변수명이 아니며, setter 메소드에서 set을 제외하고 나머지 문자열의
첫글자만 소문자로 변경합니다.
=>MemberVo 는 2개의 프로퍼티가 존재합니다.
1. applicationContext.xml 파일에 property에 의존성 주입하는 bean을 생성하는 코드를 작성
| <bean id = "memberVo4" class="domain.MemberVo"> <property name="email" value="tstigma@naver.com"></property> <property name="name" ref="second"></property> </bean> <bean id = "second" class="java.lang.String"> <constructor-arg value="armor"></constructor-arg> </bean> | cs |
2.main 메소드에서 bean을 가져오는 코드를 작성하고 실행
| MemberVo memberVo4 = context.getBean("memberVo4",MemberVo.class); System.out.println(memberVo4); | cs |
======================================================
namespace
======================================================
**namespace(이름공간)를 이용하면 constructor-arg 나 property태그 대신에 bean을 생성하는 코드 내부에 속성으로 값을 대입할 수 있습니다.
c와 p네임스페이스를 추가하면 됩니다.
코드를 간결하게 만들기 위해 사용합니다.
1.applicationContext.xml 파일에 c와 p 네임스페이스 추가
2.applicationContext.xml 파일에 c와 p 네임스페이스를 이용한 bean 생성 코드 추가
| <!-- MemberVO memberVO4 = new MemberVO("abc@gmail.com", "조헌"); --> <bean id="memberVO4" class="domain.MemberVO" c:email="abc@gmail.com" c:name="조헌"/> <!-- MemberVO memberVO5 = new MemberVO(); memberVO5.setEmail("efg@gmail.com"); memberVO5.setName("강감찬")--> <bean id="memberVO5" class="domain.MemberVO" p:email="efg@gmail.com" p:name="강감찬" /> | cs |
=======================================================
Collection을 주입받기 위한 예제
1. 4개의 Collection을 인스턴스 변수로 갖는 클래스 생성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | domain.CollectionDI package domain; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; public class CollectionDI { // 4개의 Collection인스턴스 변수 private List<String> list; private Set<String> set; private Properties properties; private Map<String, Object> map; public List<String> getList() { return list; } public void setList(List<String> list) { this.list = list; } public Set<String> getSet() { return set; } public void setSet(Set<String> set) { this.set = set; } public Properties getProperties() { return properties; } public void setProperties(Properties properties) { this.properties = properties; } public Map<String, Object> getMap() { return map; } public void setMap(Map<String, Object> map) { this.map = map; } @Override public String toString() { return "CollectionDI [list=" + list + ", set=" + set + ", properties=" + properties + ", map=" + map + "]"; } } | cs |
2.SpringBeanConfiguration 파일을 생성하고 CollectionDI 객체를 생성해주는 bean 코드를 추가
=>src/main/resources 디렉토리의 collection.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | <?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="collectionDI" class="domain.CollectionDI"> <property name="list"> <list> <value>배열</value> <value>ArrayList</value> <value>LinkedList</value> <value>Stack</value> <value>Queue</value> <value>Deque</value> </list> </property> <property name="set"> <set> <value>HashSet</value> <value>LinkedHashSet</value> <value>TreeSet</value> </set> </property> <property name="properties"> <props> <prop key="Encapsulation">캡슐화</prop> <prop key="Inheritance">상속성</prop> <prop key="Polymorphism">다형성</prop> </props> </property> <property name="map"> <map> <entry> <key><value>Encapsulation</value></key> <value>클래스를 만드는 것</value> </entry> <entry> <key><value>Inheritance</value></key> <value>하위 클래스가 상위 클래스의 모든 것을 물려받는 것</value> </entry> <entry> <key><value>Polymorphism</value></key> <value>동일한 메시지에 대하여 다르게 반응하는 성질</value> </entry> </map> </property> </bean> </beans> | cs |
**일반적인 프로그램 구조
domain class, DAO---> Service ----> Controller --- > View
=>ApplicationProgramming 에서는 Controller의 역할을 Main이 합니다.
1. spring과 java version 바꿉니다.
2. Spring과 Java 버전 설정
3. VO로 사용할 클래스 생성
package domain;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 | public class Board { private int num ; private String id; private String name; private String subject; private String content; private int readcount; private String writedate ; //작성일 ㅁ public int getNum() { return num; } public void setNum(int num) { this.num = num; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public int getReadcount() { return readcount; } public void setReadcount(int readcount) { this.readcount = readcount; } public String getWritedate() { return writedate; } public void setWritedate(String writedate) { this.writedate = writedate; } @Override public String toString() { return "Board [num=" + num + ", id=" + id + ", name=" + name + ", subject=" + subject + ", content=" + content + ", readcount=" + readcount + ", writedate=" + writedate + "]"; } } | cs |
4. Board 테이블과 연동하는 메소드를 소유한 BoardDao 클래스를 생성하고 메소드 작성
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | package dao; import domain.Board; public class BoardDao { public Board get(int num) { Board board = new Board(); board.setNum(num); board.setId("dispo0"); board.setName("관리자"); board.setSubject("공지사항"); board.setContent("미세먼지 조심하세요 "); board.setReadcount(1); board.setWritedate("2018-04-07"); return board; } } | cs |
5.실제 비지니스 로직의 메소드 원형을 소유한 Service 인터페이스 생성
=>service.BoardService
| package service; import domain.Board; public interface BoardService { public Board get(int num); } | cs |
6.비지니스 로직을 구현할 ServiceImpl 클래스를 생성하고 메소드 구현
=>service.BoardServiceImpl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | package service; import dao.BoardDao; import domain.Board; public class BoardServiceImpl implements BoardService { //BoardDao 참조형 변수 private BoardDao boardDao; //접근자 메소드 public BoardDao getBoardDao() { return boardDao; } public void setBoardDao(BoardDao boardDao) { this.boardDao = boardDao; } //비지니스 로직을 수행하는 메소드 @Override public Board get(int num) { return boardDao.get(num); } } | cs |
7.클라이언트의 요청을 받아서 적절한 비지니스 로직 처리 메소드를 호출하는 Controller를 생성하고 메소드 작성
=>controller.BoardController
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package controller; import domain.Board; import service.BoardService; public class Controller { private BoardService boardService; public BoardService getBoardService() { return boardService; } public void setBoardService(BoardService boardService) { this.boardService = boardService; } public Board doGet(int num) { return boardService.get(num); } } | cs |
8.main 메소드를 소유한 Main 클래스를 만들어서 실행 코드를 작성하고 실
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import controller.BoardController; import dao.BoardDao; import domain.Board; import service.BoardServiceImpl; public class Main { public static void main(String[] args) { //BoardDao 객체 생성 BoardDao boardDao = new BoardDao(); //BoardService 객체 생성 BoardServiceImpl boardService = new BoardServiceImpl(); //BoardDao 객체 주입 boardService.setBoardDao(boardDao); //BoardController 객체 생성 BoardController boardController = new BoardController(); //BoardService 객체 주입 boardController.setBoardService(boardService); Board board = boardController.doGet(101); System.out.println(board); } } | cs |
9.객체를 singleton으로 생성할 수 있도록 해주는 설정 파일을 추가
src/main/resources 디렉토리에 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="boardDao" class="dao.BoardDao"></bean> <bean id="boardService" class="service.BoardServiceImpl"></bean> <bean id="boardController" class="controller.BoardController"></bean> </beans> | cs |
10.main 메소드를 수정하고 실행
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package main; import org.springframework.context.support.GenericXmlApplicationContext; import controller.Controller; import dao.BoardDao; import domain.Board; import service.BoardServiceImpl; public class Main { public static void main(String[] args) { GenericXmlApplicationContext context = new GenericXmlApplicationContext("classpath:applicationContext.xml"); // BoardDao 객체 생성 BoardDao boardDao = context.getBean(BoardDao.class); // BoardSerivce 객체 생성 BoardServiceImpl boardservice = context.getBean(BoardServiceImpl.class); // BoardDao 객체 주입 boardservice.setBoardDao(boardDao); // 컨트롤 객체 생성 Controller boardController = context.getBean(Controller.class); // boardService 객체 주입 boardController.setBoardService(boardservice); Board board = boardController.doGet(101); System.out.println(board); } } | cs |
11. IOC만 적용한 경우
=>Spring의 Ioc를 적용하면 Spring이 생성하는 객체는 전부 Singleton 패턴으로 만들어지고 실행할 때 객체를 모두 생성해서 사용가능하도록 해줍니다.
context.close하면 메모지 정리를 전부다 해줍니다.
12.applicationContext.xml 파일에 property를 이용해서 BoardService 객체에는 Boardao 객체를 BoardContoller 객체에는 BoardService 객체를 주입하는 코드를 작성 -DI 적용
| <bean id="boardDao" class="dao.BoardDao"> </bean> <bean id="boardService" class="service.BoardServiceImpl"> <property name="boardDao" ref="boardDao"></property> </bean> <bean id="boardContoller" class="controller.Controller"> <property name="boardService" ref="boardService"></property> </bean> | cs |
13.main 메소드를 수정하고 실행
| public static void main(String[] args) { GenericXmlApplicationContext context = new GenericXmlApplicationContext( "classpath:applicationContext.xml"); // 컨트롤 객체 생성 Controller boardController = context.getBean(Controller.class); Board board = boardController.doGet(101); System.out.println(board); context.close(); } | cs |
14.Spring DI를 이용하면 실해앟고자 하는 크랠스의 객체만 만들어서 필요한 메소드를 호출하기만 하면됩니ㅏㄷ.
중간에 대입하고 하는 과정응ㄴ 새략해도 됩니다.
**annotation과 xml 의 혼용
=>spring bean configuration 파일에 context 네임스페이스를 추가하고
<context:annotation-config>태그를 추가해야 합니다.
1. @Autowired
=>인스턴스 변수 위에 어노테이션을 추가하면 setter를 자동생성해주고 동일한 자료형의 bean이 있으면 자동으로 대입해줍니다.
=> 동일한 자료형이 없으면 , 동일한 자료형이 두개 있으면 어떻게 되느냐 ?
자료형이 없으면, 주입할 수 없다
동일한 자료형이 두개 있으면 연결불가능 qualifying bean of type
2.BoardServiceImpl 클래스에 있는 BoardDao 참조형 변수 위에 @Autowired를 추가하고 접근자 메소드를 제거
3.BoardController 클래스에 있는 BoardService 참조형 변수 위에 @Autowired를 추가하고 접근자 메소드를 제거
4.applicationContext.xml 파일에 context 네임스페이스 추가
5.applicationContext.xml 파일에 <context:annotation-config/> 추가
6.property를 이용한 di 코드를 제거
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | <?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.2.xsd"> <!-- annotation을 적용하기 위한 태그 --> <context:annotation-config /> <bean id="boardDao" class="dao.BoardDao"></bean> <bean id="boardService" class="service.BoardServiceImpl"> </bean> <bean id="boardController" class="controller.BoardController"> </bean> </beans> | cs |
7. @Autowired 사용시 주의 할점
1) AutoWired가 설정된 참조형 변수의 bean이 없는 경우
NoSuch로 시작하는 예외가 발생
2) 동일한 자료형으로 2개 이상 만들어진 경우 : NoUnique로 시작하는 예외가 발생하는데
이 문제를 해결하는 방법으로는 @Autowired 아래에 @Qualifier ("빈의 아이디")를 추가 하면됩니다.
8. Autowired 대신에 Resource(name="빈의 아이디")를 사용할 수 있고 inject 라이브러리를 추가하면
@inject를 사용할 수 있습니다.
**bean 자동 생성
=>spring bean configuration 파일에 <context:component-scan base-package="패키지이름"/> 태그가 존재하면 패키지이름 하위에 존재하는 클래스 들 중에서 @Component, @Controller, @Service, @Repository 어노테이션이 있는 클래스들의 bean을 자동 생성해 줍니다.
=>@Component는 모든 클래스에 추가가 가능한데 Controller, Service, Repository는 역할에 맞게 추가해야 합니다.
=>id는 클래스이름의 첫글자만 소문자로 변경한 것으로 자동 설정됩니다.
1.controller, service, dao 패키지 안에 있는 클래스들을 board 패키지를 생성해서 안으로 전부 이동
2.BoardDao, BoardServiceImpl, BoardController 클래스 위에 @Component 어노테이션을 추가
3.applicationContext.xml 파일에 3개의 클래스 bean 태그를 제거
4.applicationContext.xml 파일에 @Component가 붙은 클래스들의 bean을 자동생성해주는 태그를 추가
<!-- board 패키지에 있는 클래스들 중에서
@Component(Controller, Service, Repository)가 붙은
클래스들의 bean을 자동 생성 -->
<context:component-scan base-package="board" />