1. 첫 번째 사례
클래스 내부에 메서드 생성
간단한 인삿말을 출력하는 프로그램 작성
메시지를 출력하는 sayHello메서드를 만들어 호출
단, sayHello메서드를 호출하려면
먼저 HelloSpring4App01에 대한 객체를 생성해야 함
인사말을 출력하는 메서드가 현재 클래스에 있기 때문에
프로그램 확장성 측면에서 봤을 때 제약이 존재
ex) 참조하는 메서드의 인자가 1개에서 2개가 된다면?
즉, 유지보수/업무분담의 어려움이 발생
해결책 : 인사말 출력하는 기능을 담당하는 별도의 클래스 생성
public class HelloSpring4App01 {
public static void main(String[] args) {
//System.out.println("Hello, World!!");
HelloSpring4App01 app = new HelloSpring4App01(); //2b
app.sayHello("sunwoo!");
}
private void sayHello(String msg) { //2a
System.out.println("Hello," + msg);
}
}
2. 두 번째 사례
외부 클래스를 통해 인사말을 구현하는 기능 구현
인삿말을 출력하려면 외부 클래스를 객체화한 뒤
sayHello 메서드 호출
한편 HelloSpring4 App02을 실행하려면
HelloSpring4 Bean02라는 클래스가 있어야 함
즉, 클래스 간의 의존성이 생긴다
의존성이 커짐으로 발생하는 부수적인 단점은
코드 변경 시 그것과 연관되는 다른 클래스에도 영향을 미침
유지보수의 범위가 넓어짐
해결책 : 인터페이스를 도입해서 객체 간 의존성을 낮춤
// HelloSpring4 App02
public class HelloSpring4App02 {
public static void main(String[] args) {
HelloSpring4Bean02 bean = new HelloSpring4Bean02();
bean.sayHello("Sunwoo!!!");
}
}
// HelloSpring4 Bean02
package imlsw96.bean;
public class HelloSpring4Bean02 {
public void sayHello(String world) {
System.out.println("Hello," + world);
}
}
03. 세 번째 사례
인사말을 한국어, 영어, 일본어로 출력하도록 기능을 개선.
해당 기능을 제각각의 이름으로 호출하는 경우
지나치게 복잡해지고 기능에 따라 이름을
일일이 외워야 하는 불편함이 존재함
해결 : 인터페이스를 도입해서 객체 간 의존성을 낮춤
public class HelloSpring4App03 {
public static void main(String[] args) {
HelloSpring4Bean03 bean = new HelloSpring4Bean03();
bean.sayHelloKor("스프링4 !!!");
bean.sayHelloEng("spring4 !!!");
bean.sayHelloJpn("일본어 !!!");
}
}
package imlsw96.bean;
public class HelloSpring4Bean03 {
// 다양한 언어로 인삿말을 출력하는 메서드
public void sayHelloKor(String world) {
System.out.println("안녕하세요," + world);
}
public void sayHelloEng(String world) {
System.out.println("Hello," + world);
}
public void sayHelloJpn(String world) {
System.out.println("おはようございます," + world);
}
}
4. 네 번째 사례
인터페이스를 도입
확장성이 높고 유연한 코드를 작성할 수 있음
또한, 객체 간의 tightly coupled도 피할 수 있음
03번의 예로 객체 생성할 때 그에 맞는 클래스명, 다른 변수명으로 객체를 생성해서 사용해야 하지만
객체 간의 의존성도 낮출 수 있음
하지만, new 연산자로 객체를 생성하는 코드가 노출
다시 말해, HelloSpring4 Bean04는
HelloSpirng4 Bean04 Kor.HelloSpirng4 Bean04 Eng, HelloSpirng4 Bean04 Jpn에 의존적이라는 의미
해결 : factory 패턴을 이용해서
객체 생성을 전담하는 클래스를 만들어
객체 생성과정을 캡슐화함
package imlsw96.basic;
import imlsw96.bean.*;
public class HelloSpring4App04 {
public static void main(String[] args) {
HelloSpring4Bean04 bean = new HelloSpring4Bean04Kor();
bean.sayHello("스프링4");
bean = new HelloSpring4Bean04Eng();
bean.sayHello("Spring4");
bean = new HelloSpring4Bean04Jpn();
bean.sayHello("Spring4");
}
}
package imlsw96.bean;
public interface HelloSpring4Bean04 {
// 다국어 인삿말을 위해 동일한 인터페이스를 정의
void sayHello( String msg );
}
package imlsw96.bean;
public class HelloSpring4Bean04Eng implements HelloSpring4Bean04 {
// 영어로 인삿말을 출력하는 메서드
@Override
public void sayHello(String world) {
System.out.println("Hello," + world);
}
}
package imlsw96.bean;
public class HelloSpring4Bean04Jpn implements HelloSpring4Bean04 {
// 일본어로 인삿말을 출력하는 메서드
@Override
public void sayHello(String world) {
System.out.println("こんにちは," + world);
}
}
package imlsw96.bean;
public class HelloSpring4Bean04Kor implements HelloSpring4Bean04 {
// 한국어HelloSpring4Bean03로 인삿말을 출력하는 메서드
@Override
public void sayHello(String world) {
System.out.println("안녕하세요," + world);
}
}
5. 다섯 번째 사례
factory 패턴을 이용해서 객체 생성을 캡슐화함
한편, 매개변수를 이용해서 생성할 객체를 취사선택함
객체생성을 팩토리 패턴으로 구현해야 함
따라서, 개발자가 신경 써야 할 부분이 은연중에 추가됨
즉, 비즈니스 로직 코드 작성하는 것도 버거운데
객체 생성 관련 클래스로 따로 작성하는 것은 더욱 힒듬
해결 : 객체 생성 부분은 외부의 힘을 빌림
IoC 컨테이너가 객체를 생성하고 그것을 주입 (inject) 받음
import imlsw96.bean.*;
public class HelloSpring4App05 {
public static void main(String[] args) {
HelloSpring4Bean05Factory.create("kor").sayHello("스프링4");
HelloSpring4Bean05Factory.create("eng").sayHello("스프링4");
HelloSpring4Bean05Factory.create("jpn").sayHello("스프링4");
}
}
package imlsw96.bean;
public class HelloSpring4Bean05Factory {
// 인삿말을 출력하는 객체를 생성하는 create 메서드 정의
// type이라는 매개변수를 통해 출력할 인삿말의 유형을 선택함
public static HelloSpring4Bean04 create(String type){
HelloSpring4Bean04 bean = null;
if (type.equalsIgnoreCase("kor"))
bean = new HelloSpring4Bean04Kor();
else if (type.equalsIgnoreCase("eng"))
bean = new HelloSpring4Bean04Eng();
else if (type.equalsIgnoreCase("jpn"))
bean = new HelloSpring4Bean04Jpn();
return bean;
}
}
이 부분은 보면서 헷갈릴 수도 있어서 그냥 필자의 뇌피셜을 싸질러보면
위의 4번째 사례에서 만들어놓은 interface타입을 return 하는 05 Factory 클래스에 create라는 이름의 메서드를 생성해서
인자 값 검사를 해줘서 인터페이스를 상속받아 kor , eng, jpn클래스를 인스턴스화를 시켜주고 그 값을 넘겨준다.
그러고 메인 메서드가 있는 App05번에 보면 Factory클래스에 생성해놓은 메서드를 이용하여 객체 생성 부분을 캡슐화해서 나라별로 언어를 실행하는 걸 확인할 수 있다.
6. 스프링 프레임워크를 사용하는 첫번째 사례
05번의 에제를 보면 factory 패턴을 이용해서 객체를 생성하는 코드를 작성했었다.
하지만 스프링프레임워크를 사용하면 이러한 과정은 필요 없다.
스프링 프레임워크를 이용한 개발의 필수요건은
인터페이스 기반 설계!
실행 원리
예제를 보면 알 수 있듯 객체 생성 시 NEW연산자를 사용하지 않고
스프링이 대신 객체를 생성하고 프로그램에서는 DI를 통해 사용함
- bean.xml에 스프링 컨테이너가 미리 생성해둬야 할 객체와 이름을 정의해 둠
- 프로그램이 시작되면 bean06.xml에 작성한 객체 정보를 스프링 컨테이너가 읽어서 객체를 만들어 둠
- BeanFactory에서 getBean 메서드로 해당 객체를 가져와서 HelloSpring4 Bean04 타입의 변수에 주입
- 주입된 변수를 통해 sayHello메서드를 호출하면 인사말이 출력됨
/bean06.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="kor" class="imlsw96.bean.HelloSpring4Bean04Kor"/>
<bean id="eng" class="imlsw96.bean.HelloSpring4Bean04Eng"/>
<bean id="jpn" class="imlsw96.bean.HelloSpring4Bean04Jpn"/>
</beans>
<bean>을 해서 클래스를 설정해주고 참조할 id 값을 설정해준 후 메인클래스로 돌아와서 확인해보자
/HelloSpring4 App06
package imlsw96.basic;
import imlsw96.bean.HelloSpring4Bean04;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.FileSystemResource;
public class HelloSpring4App06 {
public static void main(String[] args) {
// 스프링 컨테이너의 관리를 받는 객체들이 정의된 설정파일 읽기
BeanFactory bf = new XmlBeanFactory(
new FileSystemResource("src/main/java/bean06.xml"));
// 스프링 컨테이너를 통해 지정한 객체를 주입받음
HelloSpring4Bean04 bean= (HelloSpring4Bean04) bf.getBean("kor");
bean.sayHello("스프링4");
bean=(HelloSpring4Bean04) bf.getBean("eng");
bean.sayHello("스프링4");
bean=(HelloSpring4Bean04) bf.getBean("jpn");
bean.sayHello("스프링4");
}
}
스프링 프레임워크에서 제공하는 컨테이너는 2가지
BeanFactory / ApplicationContext
이둘중 BeanFactory를 이용해서 bean06.xml 파일을 읽어왔는데
BeanFactory 방식은 스프링에서 구식 방법이라 고함
다음 사례에서는 ApplicationContext를 이용한 방법
7. 스프링 프레임워크를 사용하는 두 번째 사례
package imlsw96.basic;
import imlsw96.bean.HelloSpring4Bean04;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class HelloSpring4App07 {
public static void main(String[] args) {
// 스프링 컨테이너의 관리를 받는 객체들이 정의된 설정파일 읽기
ApplicationContext ctx = new
FileSystemXmlApplicationContext("/src/main/java/bean06.xml");
// 스프링 컨테이너를 통해 지정한 객체를 주입받음
HelloSpring4Bean04 bean= (HelloSpring4Bean04) ctx.getBean("kor");
bean.sayHello("스프링4");
bean=(HelloSpring4Bean04) ctx.getBean("eng");
bean.sayHello("스프링4");
bean=(HelloSpring4Bean04) ctx.getBean("jpn");
bean.sayHello("스프링4");
}
}
/bean06.xml 동일
[Spring] 스프링 XML 설정 파일 작성 방법 정리
[Spring] 스프링 XML 설정 파일 작성 방법 정리 📄 목차 1. 스프링 XML 설정 파일 포맷 - 기본 포맷 - 애노테이션 설정을 사용하기 위한 포맷 2. 빈(Bean) 설정 예시 - 자동 주입 설정 - autowire 속성 3.
atoz-develop.tistory.com
'JAVA & APP :국비지원 학원 복습 > Spring' 카테고리의 다른 글
스프링프레임워크로 JDBC와 mybatis (0) | 2021.01.25 |
---|---|
스프링프레임워크 사용전후 비교 간단 프로그램..? (0) | 2021.01.25 |
Maven을 이용해 Spring 시작하기 (0) | 2021.01.21 |
웹 애플리케이션(Web application) (0) | 2021.01.21 |
SpringFramework ? (0) | 2021.01.15 |