
Spring

POJO란?
Plain Old Java Object의 약자로, 일반적인 자바 언어와 꼭 필요한 API외에는 특정 구현 기술에 종속되지 않으며 특정 데이터 베이스나 서버에 의존하지 않는 자바 클래스만으로 구성해도 프로그래밍 가능
참고
의존성 주입?
- 객체 간의 관계를 관리할 때 사용하는 기법
- 객체 또는 구성 요소 사이의 의존관계를 직접 생성하거나 제어하는 것이 아니라 외부의 Bean 설정 파일을 활용해 스프링 컨테이너가 자동으로 연결해주는 방식을 의미
- 생성자 주입 방식 : 생성자에서 초기화 하는 것
메서드 주입 방식 : 메서드를 만들어서 초기화 하는 것 (setter 느낌) - 이게 더 많이 쓰임.
참고
AOP란..?
AOP는 관점(Aspect)지향 프로그래밍으로, 관점을 기준으로 다양한 기능을 분리하여 보는 프로그래밍이다. 관점(Aspect)이란, 부가 기능과 그 적용처를 정의하고 합쳐서 모듈로 만든 것이다.
=> 핵심적인 기능에서 부가적인 공통 관심사를 분리하여 공통 모듈로 만들어서 설계하고 개발하는 방법
참고
트랜잭션 이란?
- 쪼갤 수 없는 최소 단위의 작업
- 어떤 작업을 하나로 묶어 실행할 때, 하나의 작업이라도 실패하면 모두 실패 처리를(RollBack), 성공하면 모두 성공처리를(Commit) 해주는 것
스프링 웹 MVC

스프링의 웹 MVC의 구성요소

Spring 프로젝트 생성 (InteliJ 사용)
1) 프로젝트 생성


2) 서버 구성 수정


-Dfile.encoding=UTF-8 : D 접두어는 실행시점에 뒤에 있는 부분을 읽어오라는 뜻
3) 파일 - 설정




4) spring 관련 라이브러리 설정
Project Lombok
* 컴파일, 어노테이션 프로세서, 테스트컴파일, 테스트 어노테이션 전부 포함해서 갖고올 수 있음.
<?xml version="1.0" encoding="UTF-8" ?>
<configuration status="INFO">
<Appenders>
<Console name="CONSOLE" target="SYSTEM_OUT">
<PatternLayout charset="UTF-8" pattern="%d{hh:mm:ss} %5p [%c] %m%n" />
</Console>
</Appenders>
<loggers>
<logger name="org.springframework" level="INFO">
<append-ref ref="CONSOLE" />
</logger>
<logger name="org.fullstack4" level="INFO">
<append-ref ref="CONSOLE" />
</logger>
<root level="INFO" additivity="false">
<AppenderRef ref="CONSOLE" />
</root>
</loggers>
</configuration>위 라이브러들 다 build.gradle에 내용 넣기!
dependencies {
compileOnly('javax.servlet:javax.servlet-api:4.0.1')
testImplementation("org.junit.jupiter:junit-jupiter-api:${junitVersion}")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${junitVersion}")
// https://mvnrepository.com/artifact/org.springframework/spring-core
implementation group: 'org.springframework', name: 'spring-core', version: '5.3.34'
// https://mvnrepository.com/artifact/org.springframework/spring-context
implementation group: 'org.springframework', name: 'spring-context', version: '5.3.34'
// https://mvnrepository.com/artifact/org.springframework/spring-test
testImplementation group: 'org.springframework', name: 'spring-test', version: '5.3.34'
// https://mvnrepository.com/artifact/org.projectlombok/lombok
compileOnly 'org.projectlombok:lombok:1.18.32'
annotationProcessor 'org.projectlombok:lombok:1.18.32'
testCompileOnly 'org.projectlombok:lombok:1.18.32'
testAnnotationProcessor 'org.projectlombok:lombok:1.18.32'
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.23.1'
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-api
implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.23.1'
// https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-slf4j-impl
testImplementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.23.1'
// https://mvnrepository.com/artifact/jstl/jstl
implementation group: 'jstl', name: 'jstl', version: '1.2'
}
혹시 build.gradle 에 열심히 넣었는데 코끼리 아이콘이 안뜬다면?
여기서 직접 빌드/클린해서 적용할 수 있습니다.
5) 컨텍스트 루트 파일 추가해보기
* tomcat9이후부터는 web-app이 프로젝트 루트!
그 중 WEB-INF 내부의 경우 해당 경로로 직접 접근이 안되고, 컨테이너에 요청을 해서만 접근이 가능하다.


=> 만들어놓은 root_context.xml 을 이용해서 의존성 주입 연습 예정
6) 테스트해보기
1) SampleDAO 만들기
package org.fullstack4.springmvc.sample;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.springframework.stereotype.Repository;
@Repository
public class SampleDAO {
}
2) SampleServise 만들기
package org.fullstack4.springmvc.sample;
import lombok.ToString;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
@ToString
public class SampleService {
@Autowired
private SampleDAO sampleDAO;
}
3) root-context.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 https://www.springframeword.org/schema/context/spring-context.xsd">
<bean class="org.fullstack4.springmvc.sample.SampleDAO" />
<bean class="org.fullstack4.springmvc.sample.SampleService" />
</beans>
4) 테스트 코드 작성(경로 : test > java > 패키지명 > SampleTests)
package org.fullstack4.springmvc.sample;
import lombok.extern.log4j.Log4j2;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@Log4j2
@ExtendWith(SpringExtension.class)
@ContextConfiguration(locations = "file:src/main/webapp/WEB-INF/root-context.xml")
public class SampleTests {
@Autowired
private SampleService sampleService;
@Test
public void testService() {
log.info("-----------------sampleService Test : " + sampleService);
Assertions.assertNotNull(sampleService);
}
}
5) 테스트 결과

03:29:10 INFO [org.fullstack4.springmvc.sample.SampleTests] -----------------sampleService Test : SampleService(sampleDAO=org.fullstack4.springmvc.sample.SampleDAO@4ee33af7)
내용을 보면 만든적 없는 사용자 생성자로 SampleService가 만들어진걸 볼 수 있음 @AutoWired 어노테이션을 이용해서, 의존성을 주입한 것임
=> spring에게 @AutoWired를 통해 해당 클래스를 생성하는 시점에 생성자에 @AutoWired로 작성한 내용을 넣어서 실행해달라고 요청한 것!!
=> 만약 @AutoWired 여러개 있으면, 해당 내용을 모두 생성자에 넣어서 생성해달라고 요청하는 것임!
root-context.xml 처럼 xml을 이용해서 하나씩 Bean으로 설정하는 방법
(이렇게 사용하려면 주입할 개체 클래스에서 @Repository 추가 필요 - 스프링에서 Bean으로 관리될 수 있도록 설정)
ApplicationContext 스프링이 Bean들을 관리하는 공간!
ApplicationContext : 스프링의 핵심 컨테이너로서, 스프링 애플리케이션 전체에 걸쳐 스프링 빈의 생성, 관리, 라이프사이클을 담당 (BeanFactory도 유사개념 추후 학습 예정)
따라서, @Autowired를 사용하기 위해서는 ApplicationContext(root-context.xml)에 Bean으로 설정되어있어야 함.
참고(공부용)*선생님의 깨알 CS지식(?) 특강
- WAS 내에는 도메인 당 한개의 application이 존재하며, applicaiton에는 하나의 ApplicationContext가 존재 (application은 서버의 리소스의 범위만큰 만들 수 있다.)
- ApplicationContext : ServletContext => 1:1로 존재
🌟<context:component-scan>을 이용해서 한번에 빈으로 등록 (스프링 2.5부터 지원)
<context:component-scan>을 이용해서 패키지를 지정해서 해당 패키지 내 클래스의 인스턴스들을 스프링의 빈으로 등록할 수 있음
특정 어노테이션을 이용해서 스프링의 빈으로 관리될 객체를 표시해주면 <context:component-scan>이 알아서 스캔해가는 방식!
- @Controller : MVC의 컨트롤러를 위한 어노테이션
- @Servise : 서비스 계층의 객체를 위한 어노테이션
- @Repository : DAO와 같은 객체를 위한 어노테이션 (DB에 접근하는애들 DAO일 수도 File관련일 수도)
- @Component : 일반 객체나 유틸리티 객체를 위한 어노테이션 (공통유틸 등)
=> 위 1번 방법은 개발자가 개별로 하나하나 등록해서 관리하는 방식이고, 2번 방식은 특정 어노테이션으로 표시만 해주고 spring이 알아서 관리하도록 하는 방식!!
📒
<context:component-scan>사용해서 의존성 주입해보기<?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 https://www.springframeword.org/schema/context/spring-context.xsd"> <!-- 1. `root-context.xml` 처럼 xml을 이용해서 의존성 주입하는 방법 --> <!-- <bean class="org.fullstack4.springmvc.sample.SampleDAO" />--> <!-- <bean class="org.fullstack4.springmvc.sample.SampleService" />--> <!-- 2. `<context:component-scan>`을 이용하는 방법 --> <context:component-scan base-package="org.fullstack4.springmvc.sample" /> </beans>이렇게만 바꿔주면 spring에서 알아서
@Controller@Servise@Repository@Component로 설정된 것들을 알아서 Bean으로 등록해 줌.
private final로 작성합니다.@RequiredArgsConstructor 로 알아서 만들어지게 설정함)lombok의 여러 생성자 어노테이션
- @RequiredArgsConstructor : 초기화 되지않은 final 필드나, @NonNull 이 붙은 필드만 파라미터로 갖는 생성자를 만들어 줍니다.
- @NoArgsConstructor : 파라미터가 없는 기본 생성자를 생성해 줍니다.
- @AllArgsConstructor : 어노테이션은 모든 필드 값을 파라미터로 받는 생성자를 만들어줍니다
@어노테이션어떤건 class위에 써주고 어떤건 method위에 써주고.. 뭐가 다름?
- class위
: class가 생성(컴파일)되는 시점에 어노테이션이 실행 됨 => 해당 class 전체에 어노데이션에 영향을 받으며, 주로 의존성 주입으로 사용 됨
이러한 경우 class가 컴파일 되는 시점에 작성한 어노테이션에 오류가 있을 경우 컴파일 자체에서 에러가 발생함- method 위
: 해당 메서드가 호출된 시점에 어노테이션이 실행 됨. => 해당 메서드에만 적용할 경우에 사용 됨
메서드에만 적용할 경우 오류가있어도 컴파일 시점에 에러가 발생하지 않으며, 해당 메서드를 호출할 때 에러가 발생합니다.