

- 어려워도 하던 것 처럼 다른 예시로 이해하든 구글링해서 이해하든 어떻게든 일단 이해부터 하자.
Oracle,MyBatis는 잘 쓰지 않는다.DataBase와 연관 없이 애초에 프레임워크라서 설정에SQL을 넣고 시작한다(Java에서 설정). 일반Spring에서MyBatis을 사용 하긴 한다.
- 웹이 어떤 식으로 동작하는지 구조 파악 👉 숲을 보자
- 세부적으로 어떤게 동작하는지 알기 👉 나무를 보자

Spring 은 2가지 종류가 있다
Spring(일반): 스프링 프레임워크(Spring Framework)는 자바 플랫폼을 위한 오픈 소스 애플리케이션 프레임워크로서 간단히 스프링(Spring)이라고도 한다. 동적인 웹 사이트를 개발하기 위한 여러 가지 서비스를 제공하고 있다. 대한민국 공공기관의 웹 서비스 개발 시 사용을 권장하고 있는전자정부 표준프레임워크의 기반 기술로서 쓰이고 있다. 사용되는 기본 개념 링크❓
프레임 워크사전적 의미로는 "소프트웨어 어플리케이션이나 솔루션의 개발을 수월하게 하기 위해 소프트웨어의 구체적 기능들에 해당하는 부분의 설계와 구현을 재사용 가능하도록 협업화된 형태로 제공하는 소프트웨어 환경" 이라고 정의가 되어있다.
간단하게 생각해서 어플리케이션(=소프트웨어)을 편리하고 효율적으로 제작하기 위해, 뼈대가 되는 클래스들과 인터페이스로 구성된 일종의 기본 설계 틀이라고 생각하면 된다
Spring Boot(일반): 빠른Spring, 우리는 이걸로 배운다.
- 웹 서버 내장,
Tomcat필요 없다.- 라이브러리 관리를 위한 스프링 부트
스타터제공Xml설정을 사용하지 않는다- 제어 역전
IOC- 의존성 주입
DI- 관점 지향 프로그래밍
AOP❗ 초반이라 정확 하지 않을 수 있다. 나중에 따로 공부하며 수정해 나가자.

❓ Kotlin
이전까지Android개발 언어는JAVA로 많이 사용됐지만,
2017년 5월Google I/O에서Kotlin을 공식 언어로 채택한 후,
Kotlin으로 앱을 개발하는 기업들이 많아졌다.
실제Kotlin은 2011년에 출시되었고, 2012년에 오픈소스 프로젝트로 공개되었다. 공식 언어는 2017년에 채택되었지만 출시는 2011년도. 위 사진 처럼Spring에서도 쓰인다는 것

👉 안전하게 17버전으로
❓ Gradle
Groovy 기반으로 한 BUILD TOOL

👉 웹 개발은 의존성이 필요

👉 Spring 웹 개발의 제일 기본의 의존성




👉 HelloWorld 하나로 합치자


plugins {
id 'java' // 자바 연결
id 'org.springframework.boot' version '3.2.0' // 스프링 부트 버전 3.2.0
id 'io.spring.dependency-management' version '1.1.4' // 스프링 의존 관리 버전 1.1.4
}
group = 'com.study' // 회사명
version = '0.0.1-SNAPSHOT' // 건들지 말자
java {
sourceCompatibility = '17' // 자바 17버전
}
repositories {
mavenCentral() // Maven repository 사용
}
dependencies { // 의존성
implementation 'org.springframework.boot:spring-boot-starter-web' // 실제 의존성
testImplementation 'org.springframework.boot:spring-boot-starter-test' // 테스트 용 의존성
}
tasks.named('test') { // 클라우드 환경에서 테스트 중요하다..
useJUnitPlatform() // 테스트에서 OK면 바로 올라간다. 테스트 설정 JUnit
}
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip 👉 버전 정보, 변경 가능하다
src:main(소스)-test(테스트 소스).gitignore:git사용 제거 항목 설정gradlew,gradlew.bat: 리눅스web빌더를 사용하기 위한jar생성시 사용Help.md: 도움말settings.gradle:gradle설정

❗ 절대 틀리면 안된다


👉 빌드, Springboot는 일반 Spring과 다르게 Main문이 있다.

👉 서버 실행이 잘 됐다
package com.study.HelloWorld;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication //어노테이션, 애너테이션 SpringBootApplication : 스프링 부트 어플리케이션 사용
public class HelloWorldApplication {
// 메인문
public static void main(String[] args) { // args는 옵션을 주는 것, 따로 공부하자
// 스프링 어플리케이션 실행 메소드
// 매개변수 : HelloWorldApplication.class
SpringApplication.run(HelloWorldApplication.class, args);
}
}
DI(Dependenct Injection):Has관계
부모 관계는 아니지만 없으면 사용이 안된다. 예) 자동차의 엔진은 부모 자식 관계는 아니지만 엔진이 없으면 자동차가 굴러가지 않는다.
👉Java에서의 의존 주입,Spring에선 이렇게 안한다.
👉Spring에서의 의존 주입, 제어의 역전(싱글톤), 스프링 컨테이너@로 사용. 객체 개념을 잘 알고 있어야 에러 등 쉽게 잡을 수 있다. 여러 가지로 참고할 자료들이 많다. 공부 필요
강한 결합: 객체 간의 의존 관계에서 직접 객체를 생성하면 생성부터 메모리 관리를 위한 소멸까지 해당 객체의 라이프사이클을 개발자가 다 관리약한 결합: 누군가가 생성한 객체를 주입받을 경우, 사용하기만 하면 된다.
package DITest;
class Member{
String name;
String nickname;
public Member(){
}
}
public class UnderstandDI {
public static void main(String[] args) {
}
public static void memberUser1(){
// 강한 결합 : 직접 생성
Member m1 = new Member();
}
// 약한 결합 : 생성된 것을 주입 받음 - 의존 주입(DI)
public static void memberUser2(Member m){
Member m2 = m;
}
}

package com.study.springboot.bean;
public interface Printer {
public void print(String message);
}
package com.study.springboot.bean;
public class PrinterA implements Printer {
@Override
public void print(String message){
System.out.println("Printer A : " + message);
}
}
package com.study.springboot.bean;
public class PrinterB implements Printer {
@Override
public void print(String message){
System.out.println("Printer B : " + message);
}
}
package com.study.springboot.bean;
public class Member {
private String name;
private String nickname;
private Printer printer;
public Member(){}
public Member(String name, String nickname, Printer printer) {
this.name = name;
this.nickname = nickname;
this.printer = printer;
}
public void setName(String name) {
this.name = name;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void setPrinter(Printer printer) {
this.printer = printer;
}
public void print(){
printer.print("Hello " + name + " : " + nickname);
}
}
package com.study.springboot.bean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration // Spring에서 관리하는 어노테이션, 객체가 필요 없다
public class Config {
// 빈(bean) : 스프링이 IoC 방식으로 관리하는 객체
// 빈 팩토리(BeanFactory) : 스프링의 IoC를 담당하는 핵심 컨테이너
// 어플리케이션 컨텍스트(ApplicationContext) : 빈 팩토리를 확장한 IoC 컨테이너
@Bean
public Member member1(){ // 싱글톤으로 제공
// Setter Injection (Setter 메소드를 이용한 의존성 주입)
Member member1 = new Member();
member1.setName("강동원");
member1.setNickname("도사");
member1.setPrinter(new PrinterA());
return member1;
}
@Bean(name = "hello") // member1 이 있기 때문에 이름을 준 것
public Member member2(){
// COnstructor Injection (생성자를 이용한 의존성 주입)
return new Member("전우치", "도사", new PrinterA());
}
@Bean
public PrinterA printerA(){
return new PrinterA();
}
@Bean
public PrinterB printerB(){
return new PrinterB();
}
}
package com.study.springboot.bean;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
// @SpringBootApplication
public class DI {
public static void main(String[] args) {
//SpringApplication.run(DI.class, args);
// 1. IoC 컨테이너 생성
ApplicationContext context =
new AnnotationConfigApplicationContext(Config.class);
// 2. Member Bean 가져오기
Member member1 = (Member) context.getBean("member1");
member1.print();
// 3. Member Bean 가져오기
Member member2 = context.getBean("hello", Member.class);
member2.print();
// 4. PrinterB Bean 가져오기
Printer printer = context.getBean("printerB", Printer.class);
member1.setPrinter(printer);
member1.print();
}
}

❗ 한글 깨지면

-Xmx2048m
-Dfile.encoding=UTF-8
-Dconsole.encoding=UTF-8
👉 추가


👉 변경
package com.study.springboot.bean;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
// @SpringBootApplication
public class DI {
public static void main(String[] args) {
//SpringApplication.run(DI.class, args);
// 1. IoC 컨테이너 생성
ApplicationContext context =
new AnnotationConfigApplicationContext(Config.class);
// 2. Member Bean 가져오기
Member member1 = (Member) context.getBean("member1");
Member member3 = (Member) context.getBean("member1");
member1.print();
// 3. Member Bean 가져오기
Member member2 = context.getBean("hello", Member.class);
member2.print();
// 4. PrinterB Bean 가져오기
Printer printer = context.getBean("printerB", Printer.class);
member1.setPrinter(printer);
member1.print();
// 5. 싱글톤인지 확인
if(member1 == member2){
System.out.println("1. 동일한 객체입니다.");
}
else {
System.out.println("1. 서로 다른 객체입니다.");
}
if(member1 == member3){
System.out.println("2. 동일한 객체입니다.");
}
else {
System.out.println("2. 서로 다른 객체입니다.");
}
}
}

👉 1. member1 = member2 서로 다른 객체
2. member1 = member3 동일한 객체
싱글톤(Bean)이다. 하나의 객체를 돌려 쓰는 것(공중목욕탕)
package com.study.springboot.annotation;
import com.study.springboot.annotation.Printer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
@Component // 👉 @ComponentScan을 사용하여 @Bean을 사용하지 않아도 된다.
public class Member {
@Value("강동원")
private String name;
@Value("도사")
private String nickname;
@Autowired // ⭐자동 연결, 엄청 많이 쓴다.⭐
// 자동으로 연결 할 건데 컨테이너에 객체가 여러 개이면 이름(printerA)보고 찾는 것
@Qualifier("printerA")
private Printer printer;
public Member(){}
public Member(String name, String nickname, Printer printer) {
this.name = name;
this.nickname = nickname;
this.printer = printer;
}
public void setName(String name) {
this.name = name;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public void setPrinter(Printer printer) {
this.printer = printer;
}
public void print(){
printer.print("Hello " + name + " : " + nickname);
}
}
package com.study.springboot.annotation;
import com.study.springboot.annotation.Printer;
import org.springframework.stereotype.Component;
@Component("printerA")
public class PrinterA implements Printer {
@Override
public void print(String message){
System.out.println("Printer A : " + message);
}
}
package com.study.springboot.annotation;
import com.study.springboot.annotation.Printer;
import org.springframework.stereotype.Component;
@Component("printerB")
public class PrinterB implements Printer {
@Override
public void print(String message){
System.out.println("Printer B : " + message);
}
}
package com.study.springboot.annotation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@Autowired
Member member1; // New 생성자() 필요 없이 Spring 컨테이너 에서 Type에 따라 알아서 Bean을 주입 해준다
@Autowired
@Qualifier("printerB")
Printer printer;
@Autowired // New 생성자() 필요 없이 Spring 컨테이너 에서 Type에 따라 알아서 Bean을 주입 해준다
Member member2;
@RequestMapping("/") // http://localhost:8081/
public @ResponseBody String root(){
// 1.Member Bean 가져오기
member1.print();
// 2. PrinterB Bean 가져오기
member1.setPrinter(printer);
member1.print();
// 3. 싱클톤인지 확인
if (member1 == member2){
System.out.println("동일한 객체입니다.");
}
else {
System.out.println("서로 다른 객체입니다.");
}
return "Annotation 사용하기";
}
}
package com.study.springboot.annotation;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
@SpringBootApplication // @Configuration, @EnableAutoConfiguration, @ComponentScan 3가지를 하나의 애노테이션으로 합친 것
public class DI {
public static void main(String[] args) {
SpringApplication.run(DI.class, args);
}
}
👉 실행


스프링 부트 프로젝트에서
js,css,image등 정적인 요소를 사용
1.FreeMarker
2.Groovy
3. ⚡Thymleaf:View파일 👉HTML(동적으로 만들어 준다)⚡
4.Velocity
5. ⚡JSP: 제공되는 스타터가 없어Spring으로 추가⚡
❗폴더 겹치는 거 하나로 합칠 것




👉 static에 sub, images 폴더까지 생성
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello World <br>
안녕하세요 <br>
<img src="images/21355235.jpg">
</body>
</html>

<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body>
Hello(Sub)
</body>
</html>
실행하여 웹 실행








plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.webBasic'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'javax.servlet:jstl:1.2'
implementation 'org.apache.tomcat:tomcat-jasper:10.1.16'
}
tasks.named('test') {
useJUnitPlatform()
}
직접 만들어야 한다..



server.port=8081
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
out.println("Hello World");
%>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
<%
out.println("Hello World (sub)");
%>
</body>
</html>

package com.webBasic.webBasic;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyController {
@RequestMapping("/")
public @ResponseBody String root(){
return "JSP in Gradle";
}
@RequestMapping("/test1")
public String test1(){
return "test1";
}
@RequestMapping("/test2")
public String test2(){
return "sub/test2";
}
}



bulid.gradle
'javax.servlet:jstl:1.2': JSTL'org.apache.tomcat:tomcat-jasper:10.1.16': JSP
땡겨온다
application.propertiesserver.port=8081 spring.mvc.view.prefix=/WEB-INF/views/ 👉 MVE View 사전경로를 /WEB-INF/views/ spring.mvc.view.suffix=.jsp 👉 확장자 명을 .jsp로설정
3.WebBasicApplication.java
서버를 실행하고@SpringBootApplication로 확인 👉@Controller@SpringBootApplication public class WebBasicApplication {
MyController
1)@RequestMapping("/"): public@ResponseBody Stringroot() 👉 바로 문자가 넘어간다.
2)@RequestMapping("/test1"): publicStringtest1() 👉 /WEB-INF/views/test1.jspprefix,suffix로 넘어간다
3)@RequestMapping("/test2"): publicStringtest2() 👉 /WEB-INF/views/sub/test2.jspprefix,suffix로 넘어간다

❗폴더 겹치는 거 하나로 합칠 것
jstl api
Jakarta Servlet api
Jakarta Standard Tag Library
plugins {
id 'java'
id 'org.springframework.boot' version '3.2.0'
id 'io.spring.dependency-management' version '1.1.4'
}
group = 'com.Model'
version = '0.0.1-SNAPSHOT'
java {
sourceCompatibility = '17'
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
implementation 'jakarta.servlet.jsp.jstl:jakarta.servlet.jsp.jstl-api:3.0.0'
compileOnly 'jakarta.servlet:jakarta.servlet-api:6.0.0'
implementation 'org.glassfish.web:jakarta.servlet.jsp.jstl:3.0.1'
implementation 'org.apache.tomcat:tomcat-jasper:10.1.16'
}
tasks.named('test') {
useJUnitPlatform()
}
server.port=8081
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp


package com.Model.Model;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import java.util.ArrayList;
import java.util.List;
@Controller
public class MyController {
@RequestMapping("/")
public @ResponseBody String root(){
return "Model & View";
}
@RequestMapping("/test1")
public String test1(Model model){
// Model 객체를 이용해서, view로 Data 전달
// 데이터만 설정이 가능
model.addAttribute("name", "홍길동");
return "test1";
}
@RequestMapping("/mv")
public ModelAndView test2(){
// 데이터와 뷰를 동시에 설정이 가능
ModelAndView mv = new ModelAndView();
List<String> list = new ArrayList<>();
list.add("test1");
list.add("test2");
list.add("test3");
mv.addObject("lists", list); // jstl로 호출
mv.addObject("ObjectTest", "테스트입니다."); // jstl로 호출
mv.addObject("name", "홍길동"); // jstl로 호출
mv.setViewName("view/myView");
return mv;
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<title>Document</title>
</head>
<body>
<%
out.println("Model : Hello World");
%>
<br>
당신의 이름은 ${name} 입니다.
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset<="UTF-8">
<title>Document</title>
</head>
<body>
<%
out.println("Model(sub) : Hello World");
%>
<br>
${ObjectTest}
<br>
${lists}
<br>
<br>
<c:forEach var="mylist" items="${lists}">
${mylist} <br>
</c:forEach>
<br>
<br>
당신의 이름은 ${name}입니다.
</body>
</html>



1~3 은 위와 동일
4.MyController
1)test1의 동작@RequestMapping("/test1") public String test1(Model model){ // Model 객체를 이용해서, view로 Data 전달 // 데이터만 설정이 가능 model.addAttribute("name", "홍길동"); return "test1"; }❓메소드 + 메개변수??
⭐Model(UI Model, MVC Model과 다르다) :Spring에서 제공되는 클래스
url 호출 될 때 매개변수로 사용해도 에러 ❌
👉MVC에서Controller가View로 정보를 보낼 때 객체에 정보를 담아 보낸다.⭐2)
test2의 동작@RequestMapping("/mv") public ModelAndView test2(){ // 데이터와 뷰를 동시에 설정이 가능 ModelAndView mv = new ModelAndView(); List<String> list = new ArrayList<>(); list.add("test1"); list.add("test2"); list.add("test3"); mv.addObject("lists", list); // jstl로 호출 mv.addObject("ObjectTest", "테스트입니다."); // jstl로 호출 mv.addObject("name", "홍길동"); // jstl로 호출 mv.setViewName("view/myView"); return mv; }
ModelAndView: 데이터 모델과 화면 출력 View를 한 번에 하겠다.
⭐결국Model과ModelAndView는request.setAttribute()와 비슷한 역할이지만 한 단계 더 나아갔다.
보통Model을 많이 쓴다.⭐
