[강의기록] 스프링 입문 - 코드로 배우는 스프링 부트 [完]
스프링 입문 - 코드로 배우는 스프링 부트
상태: 완료
참고자료: https://www.inflearn.com/course/스프링-입문-스프링부트
날짜: 2025년 1월 11일 → 2025년 1월 16일
[지금 무료]스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 강의 | 김영한 - 인프런
김영한 | 스프링 입문자가 예제를 만들어가면서 스프링 웹 애플리케이션 개발 전반을 빠르게 학습할 수 있습니다., 스프링 학습 첫 길잡이! 개발 공부의 길을 잃지 않도록 도와드립니다. 📣 확
www.inflearn.com
→스프링 부트 기반으로 프로젝트 만들어주는 사이트
https://spring.io/projects/spring-boot
Spring Boot
spring.io
→ 여기서 찾아가면서 개발할 수 있음
gradlew.bat build
→ build 폴더 생성 및 jar 파일 만들어짐
→ 이거 서버에서 실행하면 돌아가는 것
- 정적(static) 컨텐츠
⇒ 그냥 HTML 그대로 인쇄 — JAVA X
- MVC & 템플릿
- @Controller @GetMapping
⇒ Controller가 템플릿(HTML)에 값을 전달해줌
- API
- @GetMapping @ResponseBody
⇒ JAVA가 그대로 값 전달— 객체를 전달하면 JSON 형태로 옴
3강 회원관리 예제 - 백엔드 개발
비즈니스 요구사항 정리
인터페이스 만들기 — why? 아직 데이터 저장소 고민중이라서 메모리 기반으로 사용
+) 실무에서는 동시성 문제를 고려해서 Map 사용 안하고 ConcurrentHashMap
, AtomicLong
사용함
**TEST 과정은 매우 중요함
JUnit 에서 test의 순서는 고려되지 않기 때문에 각각 독립적으로 동작해야함.
테스트 순서에 의존관계가 있는 것은 좋은 테스트가 아니다
@AfterEach
: 한번에 여러 테스트 실행하면 메모리 DB에 직전 테스트 결과 남으므로 이 이노테이션 사용해서 각 테스트가 독립적으로 동작하도록 유도
Test와 실제 코드 객체 통일화—
@BeforeEach
: 각 테스트 실행전에 호출, 테스트가 서로 영향이 없도록 항상 새로운 객체를 생성하고, 의존관계도 새로 맺어줌.
@Service
@Repository
@Controller
⇒ @Component
의 특수 케이스
이걸 달고 @Autowired
를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 의존성을 주입함!
OR — 자바 코드로 스프링 빈 직접 등록 가능
package hello.hellospring;
import hello.hellospring.repository.MemberRepository;
import hello.hellospring.repository.MemoryMemberRepository;
import hello.hellospring.service.MemberService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
return new MemoryMemberRepository();
}
}
⇒ 차후에 변경 사항이 있을 때에는 이렇게 설정하는 것이 더 유리할듯.
5. 회원 관리 예제 - 웹 MVC 개발
** 컨트롤러가 정적파일보다 우선순위가 높아서, Controller로 설정해두면 index.html 무시됨.
thymeleaf — 사용하면 html 템플릿으로 for each 문법 사용할 수 있음.
<tr th:each="member : ${members}">
<td th:text="${member.id}"></td>
<td th:text="${member.name}"></td>
</tr>
6. Spring DB 접근 기술
H2 연결
spring.datasource.url = jdbc:h2:tcp://localhost/~/test
spring.datasource.username=sa
spring.datasource.password=
Repository 바뀌어도, JdbcMemberRepository 클래스 생성하고
// SpringConfig 파일
@Configuration
public class SpringConfig {
private DataSource dataSource;
@Autowired
public SpringConfig(DataSource dataSource){
this.dataSource = dataSource;
}
@Bean
public MemberService memberService() {
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository() {
//return new MemoryMemberRepository();
return new JdbcMemberRepository(dataSource);
}
}
@Transactional
: 테스트 케이스에 이 애노테이션이 있으면, 테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백함
@SpringBootTest
: 스프링 컨테이너와 테스트를 함께 실행한다. ← 상대적으로 느리고, 단위 테스트가 아니기 때문에 자제하는 것이 좋음. (통합 테스트도 필요하지만, 단위 개념으로 테스트하는 것이 좋은 테스트)
Jdbc & Jdbc Template 까지는 쿼리문을 직접 작성해야함.
JPA — SQL도 JPA가 직접 만들어서 실행, 객체로 Select 가능!
public Optional <Member> findById(Long id){
Member member = em.find(Member.class, id);
return Optional.ofNullable(member);
} // item 하나만 뽑는건 간단히 가능 But 여러개 뽑는 건 불가능
public List<Member> findAll(){
return em.createQuery("select m from Member m", Member.class)
.getResultList();
}
public Optional<Member> findByName(String name){
List<Member> result = em.createQuery("select m from Member m where m.name = :name", Member.class)
.setParameter("name", name)
.getResultList();
return result.stream().findAny();
}
7장 AOP
package hello.hello_spring.aop;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class TimeTraceAop {
@Around("execution(* hello.hello_spring..*(..))")
public Object execute(ProceedingJoinPoint joinPoint) throws Throwable{
long start = System.currentTimeMillis();
System.out.println("START: " + joinPoint.toString());
try{
return joinPoint.proceed();
} finally{
long finish = System.currentTimeMillis();
long timeMs = finish - start;
System.out.println("END: " + joinPoint.toString() + " " + timeMs + "ms");
}
}
}
노션으로 작성한 걸 Markdown으로 옮겨온 거라 보기에 어색한 부분 있을 수도 있음
https://github.com/Yevin-WIN/hello-spring
GitHub - Yevin-WIN/hello-spring
Contribute to Yevin-WIN/hello-spring development by creating an account on GitHub.
github.com
강의보고 그대로 따라한 github