『 목차 』
- Spring이란?
- 스프링 프로젝트 기본 폴더 구조
- IoC컨테이너와 DI
- 프레임워크
■ Spring
스프링은 그 자체가 구조를 설계할 수 있도록 만들어 졌다는 뜻으로, 개발자가 부품을 만들어 조립하는 형태의 개발이 가능하다는 것을 의미한다.
- 제어의 역행 (IoC / Inversion of Control)
: 메소드나 객체의 호출작업을 개발자가 결정하는 것이 아니라 외부에서 결정되는 것을 의미한다. 프레임워크에서 사용하는 방법으로, 개발자는 필요한 부분을 개발해서 끼워넣는 형태로 개발하고 실행.
- 의존성 주입 (DI / Dependency Injection)
: 제어의 역행이 일어날 때 스프링이 내부에 있는 객체(Bean)들 간에 관계를 관리할 때 사용하는 기법
스프링은 의존성 주입을 프레임워크에서 처리하기 때문에 개발자는 자신이 만드는 객체나 클래스 외에는 신경쓰지 않고 코드를 만들고, 자신의 코드에 필요한 객체는 스프링을 통해 주입받는 구조로 작성된다. 의존성 주입의 종류는 생성자를 통한 주입과 set메소드를 이용한 주입으로 구분된다.
이전까지는 클래스에서 직접 객체를 생성(new)해서 사용하는 방식을 사용했지만, setter를 이용해서 필드 값을 받아오는 방식과 똑같이 setter를 이용해서 객체를 받아오는 방식을 이용한다.
기존에 존재했던 Calculator라는 클래스가 존재했다면, 사용자는 이를 이용하여 MyCalculator 클래스를 만드는데 이때 Calculator객체를 사용하기위해 직접 new를 이용하여 객체를 생성하지 않고 setter를 이용하여 받도록 구현한다 -> 개발의 편의(?)
출처 http://a07274.tistory.com/200
■ 스프링 프로젝트 기본 폴더 구조
src/main/java 자바 소스파일을 두는 폴더
src/main/resources 프로그램 실행 중에 참조하는 기타 파일을 두는 폴더
src/test/java 단위 테스트를 위한 테스트 자바 소스 파일을 두는 폴더
src/test/resource 단위 테스트를 위한 테스트 관련 기타 파일을 두는 폴더
우선 감이 안잡히더라도 스프링 예제를 하나 보고 시작하도록 하자 :-)
△ 예제) 프로젝트 패키지 구조
src/main/java
- com/javalec/ex
- Calculator
- MyCalculator
- MainClass
src/main/resources
- applicationCTX.xml
[ Calculator ]
계산할 숫자 필드와 실제 계산 메소드 구현 -> 기존에 존재하는 소스
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 |
package com.javalec.ex;
public class Calculator {
public void addtion(int firstNum,int secondNum){
System.out.println("addition");
int result = firstNum+secondNum;
System.out.println(firstNum+"+"+secondNum+"="+result);
}
public void subtraction(int firstNum,int secondNum){
System.out.println("subtraction");
int result = firstNum-secondNum;
System.out.println(firstNum+"-"+secondNum+"="+result);
}
public void multiplication(int firstNum,int secondNum){
System.out.println("multiplication");
int result = firstNum*secondNum;
System.out.println(firstNum+"*"+secondNum+"="+result);
}
public void division(int firstNum,int secondNum){
System.out.println("division");
int result = firstNum/secondNum;
System.out.println(firstNum+"/"+secondNum+"="+result);
}
} |
cs |
[ MyCalculator ]
Calculator 객체를 setter로 받아서 이 객체를 이용해서 계산을 수행 -> 개발자
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 |
package com.javalec.ex;
public class MyCalculator {
Calculator calculator;
private int firstNum;
private int secondNum;
public MyCalculator(){ }
public void add(){
calculator.addtion(firstNum, secondNum);
}
public void sub(){
calculator.subtraction(firstNum, secondNum);
}
public void mul(){
calculator.multiplication(firstNum, secondNum);
}
public void div(){
calculator.division(firstNum, secondNum);
}
//객체를 직접 생성하지 않고 밖에서 생성한 객체를 여기서 받음
public void setCalculator(Calculator calculator){
this.calculator = calculator;
}
public void setFirstNum(int firstNum){
this.firstNum = firstNum;
}
public void setSecondNum(int secondNum){
this.secondNum = secondNum;
}
} |
cs |
[ MainClass ]
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 |
package com.javalec.ex;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class MainClass {
public static void main(String[] args) {
/*
MyCalculator mycalculator = new MyCalculator();
mycalculator.setCalculator(new Calculator());
mycalculator.setFirstNum(10);
mycalculator.setSecondNum(2);
mycalculator.add();
mycalculator.sub();
mycalculator.mul();
mycalculator.div();
위와같은 구조를 똑같이 구현한 것이 밑에 코드. 훨씬 짧고 간결하지 않은가?
*/
String configLocation = "classpath:applicationCTX.xml";
AbstractApplicationContext ctx = new GenericXmlApplicationContext(configLocation);
MyCalculator myCalculator = ctx.getBean("myCalculator",MyCalculator.class);
myCalculator.add();
myCalculator.sub();
myCalculator.mul();
myCalculator.div();
}
}
|
cs |
[ applicationCTX.xml ]
각 클래스를 bean 태그를 이용하여 선언 및 필드 값 지정하여 MyCalculator에서 Calculator 객체를 setter로 값 지정
■ IoC컨테이너와 DI
Jsp & Servlet에서 MVC2패턴으로 게시판을 만들때를 생각해보자. Controller에서 작업을 수행하기 위해서 DAO가 필요로했다. 예를 들어 회원목록을 가지고 온다고 하면, MemberFrontController에서 해당하는 MemberListAction을 호출 (Action은 원래 Controller에 다 있어야 하는 기능들이지만 FrontController안에 모든 기능을 넣지 않기위해 Controller를 분리한거라고 생각하면 됨) 한다. MemberListAction에서 회원정보를 가지고 오기위해서는 MemberDAO를 생성하여 이 MemberDAO안에서 DB와 연동시켜서 정보를 가지고오는 작업을 수행해준다. 이렇게 특정 작업을 수행할 때 사용하는 객체를 '의존 객체'라고 하고, 이런 관계를 '의존 관계'라고 한다.
의존객체를 관리에는 필요할 때마다 의존 객체를 직접 생성하는 고전적인 방법에서부터 외부에서 의존 객체를 주입해 주는 최근의 다양한 방법까지 다양한 방식이 존재한다.
이렇게 의존관계를 사용하면서 의존객체와의 결합도가 증가하면 발생하는 문제가 무엇일까?
1. 코드의 잦은 변경
: 의존 객체를 사용하는 쪽과 의존 객체 사이의 결합도가 높아져서 의존 객체나 보관소에 변경이 발생하면 바로 영향을 받는다.
예를들어 의존 객체의 기본 생성자가 public에서 private로 바뀌면 의존 객체를 생성하는 모든 코드를 찾아서 변경해 주어야 한다.
2. 대체가 어렵다
: 의존 객체를 다른 객체로 대체하기가 어렵다. MemberDAO가 오라클 데이터베이스를 사용하도록 작성되어 있는데, 만약 MySQL 데이터베이스를 사용하도록 바꿔야 한다면, 일부 SQL문을 수정해야한다. 다른 방법으로는 각 데이터베이스 별로 MemberDAO를 준비하는 것인데, 그래도 여전히 문제는 남아있다. DB가 바뀔 때마다 DAO를 사용하는 코드도 변경해야하기 때문이다.
위에서 언급한 문제를 해결하기 위해 의존 객체를 외부에서 주입받는 방식으로 바뀌게 된다. 의존 객체를 전문으로 관리하는 '빈 컨테이너'가 등장하게 되었다. 빈 컨테이너는 객체가 실행되기 전에 그 객체가 필요로 하는 의존 객체를 주입해주는 역할을 수행한다. 이런 방식으로 의존 객체를 관리하는 것을 '의존성 주입(DI)'이라고 하고, 좀 더 일반적인 말로 '역제어(IoC)'라고 부른다. 즉 역제어 방식의 한 예가 의존성 주입(DI)이다.
스프링 외에도 다양한 종류의 IoC/DI 프레임워크가 등장해서 널리 사용되고 있다. 하지만 스프링만큼 유연하고 강력한 기능을 가진 IoC컨테이너와 DI 기술을 제공하는 것은 없다.
스프링 애플리케이션에서는 오브젝트의 생성과 관계설정, 사용, 제거등의 작업을 애플리케이션 코드 대신 독립된 컨테이너가 담당한다. 이를 컨테이너가 코드 대신 오브젝트에 대한 제어권을 갖고 있다고 해서 IoC라고 부른다. 그래서 스프링 컨테이너를 IoC 컨테이너라고도 한다. 스프링에선 IoC를 담당하는 컨테이너를 빈 팩토리 또는 애플리케이션 컨텍스트라고 부르기도 한다. 오브젝트의 생성과 오브젝트 사이의 런타임 관계를 설정하는 DI 관점으로 볼 때는 컨테이너를 빈 팩토리라고 한다. 그런데 스프링 컨테이너는 단순한 DI 작업보다 더 많은 일을 한다. DI를 위한 빈 팩토리에 엔터프라이즈 애플리케이션을 개발하는데 필요한 여러가지 컨테이너 기능을 추가한 것을 애플리케이션 컨텍스트라고 부른다. 즉, 애플리케이션 컨텍스트는 그 자체로 IoC와 DI를 위한 빈 팩토리면서 그 이상의 기능을 가졌다고 보면 된다.
스프링의 IoC컨테이너는 일반적으로 애플리케이션 컨텍스트라고 보면 된다.
스프링의 빈 팩토리와 애플리케이션 컨텍스트는 각각 기능을 대표하는 BeanFactory와 ApplicationContext라는 두 개의 인터페이스로 정의되어 있다. ApplicationContext 인터페이스는 BeanFactory 인터페이스를 상속한 서브 인터페이스이다.
실제로 스프링 컨테이너 또는 IoC 컨테이너라고 말하는 것은 바로 이 ApplicationContext 인터페이스를 구현한 클래스의 오브젝트다.
스프링에서 다음과 같은 코드는 스프링 컨테이너를 생성하는 부분이다.
AbstractApplicationContext ctx = new GenericXmlApplicationContext();
아직 컨테이너는 생성되었지만 아무 역할도 하지 않는 빈컨테이너일 뿐이다. 이렇게 만들어진 컨테이너가 본격적인 IoC 컨테이너로서 동작하려면 두가지가 필요하다. 바로 POJO 클래스와 설정 메타정보 이다.
POJO 클래스
POJO( Plain Old Java Object ) 클래스는 애플리케이션의 핵심 코드를 담고 있는 클래스이다. 이 POJO 클래스는 원칙을 따라 애플리케이션 코드를 작성한다. 각각의 POJO는 특정 기술과 스펙에서 독립적일뿐더러 의존관계에 있는 다른 POJO와 느슨한 결합을 갖도록 만들어야한다.
- 정리하자면, POJO는 평범한 자바빈즈 객체를 의미한다!!
- 참고하시길. https://ko.wikipedia.org/wiki/Plain_Old_Java_Object
다음 예제는 앞으로 나올 예제지만 미리 구조만 보자. Pencil이라는 interface가 있고 이 interface를 implements한 객체 Pencil4B, Pencil6B, Pencil6BEraser가 있다. MainClass에서는 Pencil을 통해 설정된 Bean이 4B인지 6B인지 6BEraser인지 출력해준다.
△ 예제)
src/main/java
- com/Pencil/ex
-MainClass.java
-Pencil.java
-Pencil4B.java
-Pencil6B.java
-Pencil6BEraser.java
- com/main/resources
-applicationCTX.xml
총 4개의 POJO클래스인 MainClass 클래스와 Pencil4B, Pencil6B, Pencil6BEraser 클래스는 Pencil 인터페이스를 사이에두고 느슨하게 연결되어 있다. 구체적으로 서로의 이름과 존재를 알 필요도 없으며 단지 서로 관계를 맺고 사용될 때 필요한 최소한의 인터페이스 정보만 공유하면 된다. 그 역할을 Pencil 인터페이스가 담당한다.MainClass는 Pencil이라는 인터페이스를 구현한 클래스의 오브젝트라면 어떤 것이든 사용 가능하다. Pencil 구현 클래스를 변경하더라도 MainClass 코드의 수정이 필요 없다.단지 런타임 시에 오브젝트를 연결해주는 IoC 컨테이너의 도움만 있으면 된다.
POJO 코드를 설계할 때는 일단 유연한 변경 가능성을 고려해서 만든다. 위의 예제는 MainClass와 Pencil4B를 사용하기로 작정하고 만들기 때문에 와닿지 않을 수 있다. 하지만 클래스 모델링 때나 클래스 코드를 작성할 때는 이런 의도는 아직 드러나는 단계가 아니기 때문에 단지 유연한 확장성을 고려하고 자신의 기능에 충실한 POJO를 만들고, 결합도가 낮은 유연한 관계를 가질 수 있도록 인터페이스를 이용해 연결해주는 것까지가 IoC 컨테이너가 사용할 POJO를 준비하는 첫 단계이다.
설정 메타정보
두 번째로 필요한 것은 앞에서 만든 POJO 클래스들 중에 애플리케이션에서 사용할 것을 선정하고 이를 IoC 컨테이너가 제어할 수 있도록 적절한 메타정보를 만들어 제공하는 작업이다.
IoC 컨테이너의 가장 기초적인 역할은 오브젝트를 생성하고 이를 관리하는 것이다. 스프링 컨테이너가 관리하는 이런 오브젝트는 빈이라고 부른다. IoC 컨테이너가 필요로 하는 설정 메타정보는 바로 이 빈을 어떻게 만들고 어떻게 동작하게 할 것인가에 관한 정보다. 스프링의 설정 메타정보는 XML 파일이 아니다. 스프링에 대한 대표적인 오해 중의 하나는 스프링의 설정정보는 XML로 되어 있다는 것이다. 스프링이 XML에 담긴 내용을 읽어서 설정 메타정보로 활용하는 건 사실이지만 그렇다고 해서 스프링이 XML로 된 설정 메타정보를 가졌다는 말은 틀렸다.
스프링의 설정 메타정보는 BeanDefinition 인터페이스로 표현되는 순수한 추상 정보다. 스프링 IoC 컨테이너, 즉 애플리케이션 컨텍스트는 바로 이 BeanDefinition으로 만들어진 메타정보를 담은 오브젝트를 사용해 IoC와 DI 작업을 수행한다. 따라서 스프링의 메타정보는 특정한 파일 포맷이나 형식에 제한되거나 종속되지 않는다. 대신 XML이든 소스코드 어노테이션이든 자바 코드이든 프로퍼티 파일이든 상관없이 BeanDefinition으로 정의되는 스프링의 설정 메타정보의 내용을 표현한 것이 있다면 무엇이든 사용 가능하다. 원본의 포맷 구조, 자료의 특성에 맞게 읽어와 BeanDefinition오브젝트로 변환해주는 BeanDefinitionReade가 있으면 된다. (당연히 BeanDefinitionReader도 인터페이스이다.) 따라서 이를 구현한 리더를 만들기만 하면 스프링의 설정 메타정보는 어떤 형식으로든 작성할 수 있다.
BeanDefinition 인터페이스로 정의되는, IoC 컨테이너가 사용하는 빈 메타정보는 대략 다음과 같다.
- 빈 아이디, 이름, 별칭 : 빈 오브젝트를 구분할 수 있는 식별자
- 클래스 또는 클래스 이름 : 빈으로 만들 POJO 클래스 또는 서비스 클래스 정보
- 스코프 : 싱글톤, 프로토타입과 같은 빈의 생성 방식과 존재 범위
- 프로퍼티 값 또는 참조 : DI 에 사용할 프로퍼티 이름과 값 또는 참조하는 빈의 이름
- 생성자 파라미터 값 또는 참조 : DI에 사용할 생성자 파라미터 이름과 값 또는 참조할 빈의 이름
- 지연된 로딩 여부, 우선 빈 여부, 자동와이어링 여부, 부모 빈 정보, 빈팩토리 이름 등
스프링 IoC 컨테이너는 각 빈에 대한 정보를 담은 설정 메타정보를 읽어들인 뒤에, 이를 참고해서 빈 오브젝트를 생성하고 프로퍼티나 생성자를 통해 의존 오브젝트를 주입해주는 DI 작업을 수행한다.
■ 프레임워크란?
내가 정리한 프레임워크란 정해진 틀이라고 생각한다. 예를들어 이전까지 자바에서 프로그램을 작성했던 환경을 생각해보자.
계산기 클래스 Calculator가 있고 이 계산기 클래스를 쓰려고 한다면 내가 만든 MyCalculator클래스의 main에서 Calculator cal = new Calculator();를 해서 cal.setNum1(10)으로 숫자를 입력해넣고 cal.add() 메소드를 이용해서 계산을 수행한다.
하지만 프레임워크는 정해진 틀이라고 했다. Spring 환경에서 이러한 동작을 수행하려면 Spring(1)에서 제일 처음 보여줬던 예시를 참고하자.
계산기능이 잘 만들어져있는 Calculator 클래스가 있고, MyCalculator 클래스는 Calculator를 setter로 객체를 받아서 (DI란 이런것이지) 똑.같.은 기능을 구현해놓고 단지 Calculator에 없는 계산할 숫자를 입력받는 기능을 추가해넣었다. 그리고나서 MyCalculator에서 계산을 하는것도 아니고 또 MainClass가 따로 있다. (말이 MainClass지 main메소드와 같다고 생각하면 안될것같다 나중에 웹으로 쓸때는 main이 없으니까?)
이 MainClass에서 applicationCTX.xml 경로를 지정해주고 이 applicationCTX.xml에서 만들어졌을거라고 가정하고 Bean을 받아와서 MyCalculator에 주입한다.
이렇게 수행하면 xml에서 Bean(MyCalculator 객체 )을 생성해서 값을 지정하고 MyCalculator객체에서 계산기능을 Calculator를 받아와서 계산하니까 이부분까지도 ref를 이용해서 다 수행했다. MainClass에서는 그냥 받아오기만 하면 된다.
지금은 복잡하고 왜이렇게 써야할지 모르겠다는 생각이 들지만 다시한번 말하자면 프레임워크는 약속이니까!
그냥 '이렇게 써야되는 툴'이라고 생각해야한다...
jsp를 이용해서 웹사이트를 만들 수 있다. MVC2패턴으로 웹사이트를 만들었다면, 스프링을 이용해서도 똑같이 만들 수 있어. 그럼 왜 스프링을 (훨씬 더 많이) 쓰는가?
- 스프링은 약속이야. 프레임워크니까. 왜 이렇게 써야할까가 아니라 이렇게 써야된다라고 정해놓은거니까. 나중에 프로젝트 규모가 커지면 스프링이 훨씬 더 편하니까.
- jsp 기반으로 mvc2패턴으로 게시판을 짤 수 있지만 프로젝트 규모가 커지고 유지보수, 재사용성을 고려한다면 스프링이 훨씬 좋기때문! (유지보수할때 xml 추가해서 짜면 되니깐)
뜬금없지만 프레임워크가 아니라 그냥 이런 소스를 직접 라이브러리를 불러와서 짜면되지 않겠냐는 생각이 들었다면 다음 글을 보자 :)
라이브러리와 프레임워크의 차이
일단 모든 소스코드든 라이브러리든 메모리에 들어가는 정보는, 컴파일러나 인터프리터에게는 호출가능한 모듈일 뿐입니다.
이런 물리적인 계층을 보지말고, 그 위의 논리적인 계층을 봐야합니다.
라이브러리는 톱, 망치, 삽같은 연장입니다.
사람이 들고 썰고, 바꿔들고 내려치고, 다시 바꿔들고 땅을 파는 겁니다.
프레임워크는 차, 비행기, 배같은 탈것입니다.
사람이 타서 엔진 켜고, 기어 넣고, 핸들 돌리고, 운전하거나, 조종하거나 해야합니다.
도구를 쓸 때, 급하면 썰어야 할 곳에 망치를 쳐도 됩니다. 땅 파야할 때 톱으로 땅을 긁어내도 됩니다.
사람은 도구를 선택하는 입장이기 때문에, 어떤 도구를 사용하든 원하는 것을 만들어낼 수 만 있으면 됩니다.
반면에, 탈것은 정해진 곳으로만 다녀야 합니다. 차를 타고 하늘을 날거나, 배를 타고 땅으로 갈 수는 없습니다.
하지만, 그 목적에 맞게 만들어져 있기 때문에, 톱이나 망치를 들고 먼저 탈것을 만들어야할 필요가 없습니다.
그저 정해진 규칙에 맞춰서 엔진, 기어, 핸들만 잘 돌리면 됩니다.
라이브러리와는 달리 프레임워크는 이미 프로그래밍할 규칙이 정해져 있습니다.
예를 들어, 설정파일로 사용되는 XML에 어떤 태그를 써야하며, 어떤 함수를 추가적으로 작성해야하고,
소스 파일을 어느 위치에 넣어야하며, DB와 연동하기 위해 무엇을 써넣어야 하는지 정해져 있습니다.
보통 이런 대부분의 작업은 프레임워크가 하고자 하는 일에 비하면 아주 작은 일이며, 사람은 극히 일부분만 조정함으로써 목적을 달성할 수 있습니다.
만약 프레임워크가 담당하는 부분이 내가 하고자 하는 목적과 다를 경우에는 어떻게 할까요?
그럼 그냥 프레임워크를 잘못쓴겁니다.
더 목적에 가까운 프레임워크를 찾아보면 대부분 있을겁니다.
없거나 구하기 힘들다면, 비슷한 프레임워크를 라이브러리 단계에서 변경해서 다른 프레임워크로 만들면 됩니다.
차를 튜닝한다음, 차를 다시 운전하면 된다는 말이지요.
혹시 프레임워크 없이 그냥 라이브러리로만 만들면 안될까요?
안될 이유가 어딨겠습니까?
그냥 다 다시 만들 능력과 시간과 여유만 있다면 그렇게 해도 되지요.
스스로 만든 프레임워크는 버그도 스스로 잡아야하지만, 남들이 만들어놓은 프레임워크는 쓰는 사람이 많은 만큼 그만큼 수정이나 업데이트도 빠릅니다.
기능이 마음에 안드는 부분이 있다면, 프레임워크를 고치면 됩니다. 처음부터 다 만드는 것보다는 싸게 먹히지요.
내일 당장 지방에서 서울로 출근해야하는데, 혼자서 차를 만들어서 타고 가야한다는 생각을 해보세요.
출처 https://kldp.org/node/124237 (프레임워크와 라이브러리의 차이)
아무리 자바 가상 머신이 가비지를 찾아서 자동으로 없애 준다고 해도, 이 작업 또한 CPU를 사용하는 일이기에 시스템 성능에 영향을 끼친다. 따라서 개발자는 늘 인스턴스의 생성과 소멸에 대해 관심을 가지고 시스템 성능을 높일 수 있는 방향으로 구현해야한다. 또한 중복 작업을 최소화하여 유지보수를 좋게 만드는 방법을 찾아야 한다. 이것이 개발자의 의무이다.
이런 개발자들의 노력은 시스템에 적용되어 많은 시간동안 시스템이 운영되면서 검증된다. 디자인 패턴은 이렇게 검증된 방법들을 체계적으로 분류하여 정의한 것으로, 디자인 패턴은 이미 실무에서 사용되고 검증된 방법이기 때문에 시스템 개발에 디자인 패턴을 사용하면 시행착오를 최소화 할 수 있다.
이러한 디자인 패턴이 특정 문제를 해결하기 위한 검증된 방법이라면, 프레임워크(Framework)는 이런 디자인 패턴을 적용해 만든 시스템 중에서 우수 사례(Best Practice)를 모아 하나의 개발 틀로 표준화 시킨 것을 말한다.
프레임워크의 대표적인 예로 국내외적으로 많이 사용하고 있으며 범용 시스템 개발에 사용할 수 있는 스프링 프레임워크가 있으며 스프링 프레임워크보다 기능은 작지만, 웹 MVC 프레임워크로 특화된 스트럿츠도 있다. 국내에서는 스트럿츠보다는 스프링 MVC 프레임워크를 더 많이 사용한다고 한다.
앞으로 배울 내용이지만 스프링과 MyBatis는 항상 같이쓰이는 개념이기때문에 미리 간략하게 MyBatis를 언급하자면, MyBatis(이전 iBatis)는 데이터베이스 연동을 쉽게 해주는 프레임워크이다. MyBatis를 사용하면 개발자는 더 이상 JDBC프로그래밍을 할 필요가 없다.
'Web > Spring' 카테고리의 다른 글
Spring MVC(1) (0) | 2016.05.16 |
---|---|
Spring 한글처리 (0) | 2016.05.16 |
Spring(4)_Environment,Properties (0) | 2016.05.13 |
Spring(3) (1) | 2016.05.12 |
Spring(2) (0) | 2016.05.11 |