오늘부터는 스프링 수업을 한다.
STS 다운받기
수업에 필요한 버전으로 다운 받기
3.9.12 버전의 맨 위에 있는 zip 파일을 받는다.
위 버전의 스프링은 자바 11버전을 써야 버전 충돌을 방지할 수 있어 현재 설치된 자바 17버전을 지우고 자바 11을 다운 받는다.
STS를 실행하기 전 springworkspace를 만들어준다.
이제 C:\work\utils\sts-bundle\sts-3.9.12.RELEASE 경로로 STS가 설치된 것을 확인한 후 springworkspace 로 경로설정을 하고 들어가면 이런 창이 뜬다. 새로운 파일을 만들기 위해 보면 spring legacy project가 보인다.
위 파일을 springworkspace의 메타데이터, 위 경로에 넣고 다시 STS를 열어 spring legacy project 로 새로운 파일을 만들 때 보면
전엔 보이지 않았던 simple spring utility project, spring MVC project 가 생겼다.
그런데 spring legacy project가 뭘까?
Spring Legacy Project는 스프링 프레임워크의 초기 버전에서 제공하던 다양한 기능을 포함한 프로젝트 유형이다.
주로 기존의 Spring MVC, Spring Web Flow, 그리고 여러 레거시 기술들을 활용하여 개발된 애플리케이션을 지원한다. 이를 통해 개발자는 레거시 시스템과의 호환성을 유지하면서도 스프링의 장점을 활용할 수 있다.
더 이해하기 쉽게 참고하기 → https://cuna.tistory.com/133
스프링을 쓰기 위해 톰캣 서버를 연결한다.
스프링
: 구조되어진 틀 안에 우리가 내용만 넣어 처리하는 방식이다.
spring MVC project → maven 과 여러 라이브러리가 세팅되어 생성되는 어플리케이션이다.
스프링은 POJO방식을 기반으로 한 웹 프레임워크이고,
IoC/ DI, AOP, PSA spring의 주요 기술을 활용해 POJO 기반의 구성을 이루게 되었다.
스프링은 객체 생성에서 소멸까지 컨테이너에서 관리해준다.
POJO 방식을 좀 더 효율적으로 사용할 수 있다.
ex) ‘물감, 붓 등 다 세팅해둘테니 개발자 너가 그리고 싶은 것을 그려라’ 하는 것이 스프링
▼ Plain Old Java Object (POJO)
Plain Old Java Object (POJO)는 특정한 규약이나 프레임워크에 종속되지 않은 간단한 자바 객체입니다. POJO는 다음 특징을 가집니다:
- 특정한 인터페이스나 클래스를 구현할 필요 없음: POJO는 특정한 인터페이스나 클래스를 구현할 필요 없이 자유롭게 정의할 수 있습니다.
- 캡슐화: POJO는 필드와 메서드를 통해 데이터를 캡슐화합니다.
- 기본적인 자바 클래스: POJO는 자바의 기본적인 클래스로, 특별한 애노테이션이나 설정이 필요 없습니다.
이러한 특성 덕분에 POJO는 쉽게 작성, 유지보수, 테스트가 가능하며, 다양한 자바 프레임워크와 호환됩니다.
스프링에서 프로젝트 만들기
프로젝트 세팅은 매번 해야한다.
Spring Legacy Project → spring MVC project →
패키지 설정에 ex) com.springbook.biz 이런 식으로 . . 구성으로 만들어서 설정해주기
프로젝트가 만들어지는데 시간이 걸리니 기다려야 한다. 그 시간 동안 이것저것 누르면 오류의 원인이 된다.
자바의 버전을 바꿔준다.
workspace와 html, css, jsp를 UTF-8 로 맞춰준다.
홈컨트롤러 파일로 들어가 실행 후 위와 같은 주소로 들어가면 Hello world! 화면을 볼 수 있다.
pom.xml 에서는 내가 설치한 버전에 맞게 버전 수정을 해주고 톰캣을 다시 시작해 문제 없이 돌아가는지 확인해주면 프로젝트 세팅은 끝난다.
파일을 만들고 작업할 위치
- src/main/java → java 파일
- src/main/resources → xml 파일
- WEB-INF → jsp 파일
스프링에서는 WEF-INF 아래 jsp를 넣어서 사용한다. → jsp는 그렇게 사용할 수 없어서 둘의 이런 차이가 보안을 강화해준다.
스프링의 3대 요소
IOC (Inversion of Controller) : 제어의 역전
객체의 생성부터 생명주기 관리까지 모든 객체에 대한 제어권을 스프링이 가져간다.
만드는 것은 개발자가, 관리는 스프링 컨테이너가
개발자의 간섭은 최소화한다.
구조가 비슷하면 인터페이스를 통해 표준화 시킨다.
객체 지향적 프로그램의 기본 구성 :
사용하려는 클래스가 어떤 클래스를 직접 사용하는게 아니라 중개되는 역할의 클래스(인터페이스)를 통해 접근하는 것이 결합도가 낮은 프로그램이다. → 다형성을 구현할 수 있는 형태
결합도가 낮은 프로그램은 표준화를 사용할 수 있다.
스프링워크는 패턴의 집합체라고 할 수 있다.
스프링 워크의 디자인 패턴 )
- 팩토리 패턴
생성을 위한 클래스를 만들어 다른 클래스에 접근한다.
스프링에서
bean = 객체
BeanFactory.java
package polymorphism;
public class BeanFactory {
// bean == 객체
// getBean 이라는 매개변수를 받아서 객체를 생성하겠다
// 모든 타입에 사용할 수 있는 Object
public Object getBean(String beanName) {
if (beanName.equals("samsung")) {
return new SamsungTV();
}else {
return new LgTV();
}
}
}
위와 같이 factory 파일이 만들어져야 한다.
- 싱글톤 패턴
동일타입으로 객체를 한번 이상 생성이 불가
// new GenericXmlApplicationContext("applicationContext.xml");
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
TV tv = (TV)factory.getBean("tv"); // 싱글톤 패턴
TV tv2 = (TV)factory.getBean("tv");
System.out.println(tv); // 싱글톤 주소값 : polymorphism.SamsungTV@25084a1e
System.out.println(tv2); // 싱글톤 주소값 : polymorphism.SamsungTV@25084a1e
// 싱글톤 패턴을 사용하지 않으면 주소가 달라진다, 동일타입으로 객체생성 가능
tv.powerOn();
tv.powerOff();
tv.volumeUp();
tv.volumeDown();
XML파일에 빈 정보 등록
= SamsungTV tv = new SamsungTV();
<bean id="" class=""></bean>
ex)
<bean id="tv" class="polymorphism.SamsungTV"></bean>
= SamsungTV tv = new SamsungTV();
위와 아래가 같은 의미다!
id 에는 생성할 객체, class에는 패키지 경로
인터페이스를 표준화 시킬 수 있는 경우)
SamsungTV.java
package polymorphism;
public class SamsungTV implements TV{
public void powerOn() {
System.out.println("SamsungTV -- 전원 켠다");
}
public void powerOff() {
System.out.println("SamsungTV -- 전원 끈다");
}
public void volumeUp() {
System.out.println("SamsungTV -- 소리 올리다");
}
public void volumeDown() {
System.out.println("SamsungTV -- 소리 내리다");
}
}
Lg.java
package polymorphism;
public class LgTV implements TV{
@Override
public void powerOn() {
System.out.println("LgTV -- 전원 켠다");
}
@Override
public void powerOff() {
System.out.println("LgTV -- 전원 끈다");
}
@Override
public void volumeUp() {
System.out.println("LgTV -- 소리 올리다");
}
@Override
public void volumeDown() {
System.out.println("LgTV -- 소리 내리다");
}
}
위 두 파일의 코드는 구조가 비슷하기 때문에 인터페이스를 통해 표준화 시킬 수 있다.
DI (Dependency Injection) : 의존성 주입
- 생성자 의존 주입
- Setter 메소드 의존 주입
- 멤버변수 의존 주입
- 어노테이션 방식의 bean 등록
- 자동 의존 주입 방식
기존 코드
A a = new A();
B b = new B(a);
스프링에서는 둘의 관계만 표시해두면 된다.
생성자 의존 주입
TVUser.java
package polymorphism;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class TVUser {
public static void main(String[] args) {
// new 라는 키워드를 사용하지 않는다
// org.springframework 아래 있는 패키지 사용을 사용하는 경우가 대부분이다
// 잘 모르겠으면 org.springframework 로 임포트
// 아래는 BeanFactory factory = new BeanFactory(); 와 같은 의미의 코드이다.
new GenericXmlApplicationContext("applicationContext.xml");
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
TV tv = (TV)factory.getBean("tv"); // 싱글톤 패턴
TV tv2 = (TV)factory.getBean("tv");
System.out.println(tv); // 싱글톤 주소값 : polymorphism.SamsungTV@25084a1e
System.out.println(tv2); // 싱글톤 주소값 : polymorphism.SamsungTV@25084a1e
// 싱글톤 패턴을 사용하지 않으면 주소가 달라진다.
tv.powerOn();
tv.powerOff();
tv.volumeUp();
tv.volumeDown();
}
}
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">
<!-- = SamsungTV tv = new SamsungTV(); -->
<!-- <bean id="" class=""></bean> -->
<!-- <bean id="tv" class="polymorphism.SamsungTV"></bean> 싱글톤 패턴 사용 -->
<!-- scope="prototype"을 추가하면 싱글톤 패턴 사용을 하지 않을 수 있다. -->
<!-- 생성자 의존 주입 -->
<bean id="tv" class="polymorphism.SamsungTV" scope="prototype">
<!-- 괸계설정 -->
<constructor-arg ref="apple"></constructor-arg>
<!-- 기본형 관계설정 시 value를 쓴다 -->
<constructor-arg value="10000"></constructor-arg>
</bean>
</beans>
SamsungTV.java
package polymorphism;
public class SamsungTV implements TV{
// 소니스피커를 사용해야 한다
private SonySpeaker speaker;
private int price;
public SamsungTV() {
System.out.println("===> SamsungTV 객체생성");
}
// 생성자 의존주입
public SamsungTV(SonySpeaker speaker) {
System.out.println("===> SamsungTV(2) 객체생성");
this.speaker = speaker;
}
public SamsungTV(SonySpeaker speaker, int price) {
System.out.println("===> SamsungTV(3) 객체생성");
this.speaker = speaker;
this.price = price;
}
public void powerOn() {
System.out.println("SamsungTV -- 전원 켠다. (가격: " + price + ")");
}
public void powerOff() {
System.out.println("SamsungTV -- 전원 끈다.");
}
public void volumeUp() {
speaker.volumeUp();
// speaker = new SonySpeaker();
// speaker.volumeUp();
// System.out.println("SamsungTV -- 소리 올리다");
}
public void volumeDown() {
speaker.volumeDown();
// speaker = new SonySpeaker();
// speaker.volumeDown();
// System.out.println("SamsungTV -- 소리 내리다");
}
}
Setter 메소드 의존 주입
TVUser.java
package polymorphism;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class TVUser {
public static void main(String[] args)
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
TV tv = (TV)factory.getBean("tv"); // 싱글톤 패턴
tv.powerOn();
tv.powerOff();
tv.volumeUp();
tv.volumeDown();
}
}
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">
<!-- Setter 메소드 의존 주입 -->
<bean id="tv" class="polymorphism.SamsungTV" scope="prototype">
<property name="speaker" ref="sony"></property>
<property name="price" value="10000"></property>
</bean>
<bean id="sony" class="polymorphism.SonySpeaker"></bean>
<bean id="apple" class="polymorphism.AppleSpeaker"></bean>
</beans>
어노테이션 방식의 bean 등록
@Component
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">
<!-- 패키지를 스캔해준다. 다 해주는 것은 아니고 표시되어진 클래스만 스캔해준다 -> 이것이 어노테이션 -->
<context:component-scan base-package="polymorphism"></context:component-scan>
LgTV.java
package polymorphism;
import org.springframework.stereotype.Component;
// id="tv" 쓴 것과 같은 의미
@Component("tv")
public class LgTV implements TV{
@Override
public void powerOn() {
System.out.println("LgTV -- 전원 켠다");
}
@Override
public void powerOff() {
System.out.println("LgTV -- 전원 끈다");
}
@Override
public void volumeUp() {
System.out.println("LgTV -- 소리 올리다");
}
@Override
public void volumeDown() {
System.out.println("LgTV -- 소리 내리다");
}
}
TVUser.java
package polymorphism;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class TVUser {
public static void main(String[] args) {
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
TV tv = (TV)factory.getBean("tv");
tv.powerOn();
tv.powerOff();
tv.volumeUp();
tv.volumeDown();
}
}
여기서 호출하는 tv는 LgTV 이다.
LgTV 에 어노테이션을 붙여줬기 때문.
자동 의존 주입
@Autowired
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">
<!-- 패키지를 스캔해준다. 다 해주는 것은 아니고 표시되어진 클래스만 스캔해준다 -> 이것이 어노테이션 -->
<context:component-scan base-package="polymorphism"></context:component-scan>
</beans>
LgTV.java
package polymorphism;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;
// id="tv" 쓴 것과 같은 의미
@Component("tv")
public class LgTV implements TV{
// 자동 의존주입 방식 : 선언된 변수의 타입으로 의존 주입한다.
// 어노테이션 @Autowired
// @Qualifier 아이디 값으로 구분
@Autowired
@Qualifier("apple")
private Speaker speaker;
public LgTV() {
System.out.println("===> LgTV 객체생성");
}
@Override
public void powerOn() {
System.out.println("LgTV -- 전원 켠다");
}
@Override
public void powerOff() {
System.out.println("LgTV -- 전원 끈다");
}
@Override
public void volumeUp() {
speaker.volumeUp();
// System.out.println("LgTV -- 소리 올리다");
}
@Override
public void volumeDown() {
speaker.volumeDown();
// System.out.println("LgTV -- 소리 내리다");
}
}
AppleSpeaker.java
package polymorphism;
import org.springframework.stereotype.Component;
@Component("apple")
public class AppleSpeaker implements Speaker {
public AppleSpeaker() {
System.out.println("===> AppleSpeaker 객체생성");
}
public void volumeUp() {
System.out.println("AppleSpeaker 소리 울린다");
}
public void volumeDown() {
System.out.println("AppleSpeaker 소리 내린다");
}
}
SonySpeaker.java
package polymorphism;
import org.springframework.stereotype.Component;
@Component("sony")
public class SonySpeaker implements Speaker{
public SonySpeaker() {
System.out.println("===> SonySpeaker 객체생성");
}
public void volumeUp() {
System.out.println("SonySpeaker 소리 울린다");
}
public void volumeDown() {
System.out.println("SonySpeaker 소리 내린다");
}
}
TVUser.java
package polymorphism;
import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.GenericXmlApplicationContext;
public class TVUser {
public static void main(String[] args) {
AbstractApplicationContext factory = new GenericXmlApplicationContext("applicationContext.xml");
TV tv = (TV)factory.getBean("tv");
tv.powerOn();
tv.powerOff();
tv.volumeUp();
tv.volumeDown();
}
}
'2024_UIUX 국비 TIL' 카테고리의 다른 글
UIUX _국비과정 0716 [스프링 게시판, 사용자 로그인 여부 알리기] (0) | 2024.07.29 |
---|---|
UIUX _국비과정 0716 [스프링 3대 요소, 게시판 기본 구조 만들기] (0) | 2024.07.29 |
UIUX _국비과정 0712 [모델2방식으로 페이스북 로그인 프로세스 구현] (0) | 2024.07.29 |
UIUX _국비과정 0711 [페이스북 로그인] (0) | 2024.07.29 |
UIUX _국비과정 0710 [오픈 API활용-카카오맵] (0) | 2024.07.25 |