✅ 스프링 프로젝트에서 설정해야할 의존성을 사전에 조합하여 제공된다. 즉, 의존성 설정을 보다 쉽게 할 수 있다.
의존성 상속관계(전이)도 스타터에선 자동으로 정리해줌.
starter버전과 boot버전은 맞추어 줘야 한다
![[Pasted image 20231226094509.png]]
ompileOnly: 컴파일 타임에만 의존성을 주입한다.
runtimeOnly: 런타임에만 의존성을 주입한다. (deprecated: runtime)
implementation: 컴파일 타임과 런타임에 모두 쓰이는 의존성을 주입한다. (deprecated: compile)
annotationProcessor: 어노테이션 프로세서로써 컴파일 시 사용되는 의존성을 주입한다.
testImplementation: 테스트 시에만 의존성을 주입한다. (deprecated: testCompile)
의존성은 그룹명:이름:버전 순으로 명시해서 주입할 수 있으며, 버전명은 optional로, 꼭 명시하지 않아도 된다.
@SpringBootApplication - Spring Boot Application의 시작 클래스에 붙인다
@SpringBootApplication = @Configuration + @EnableAutoConfiguration + ComponentScan@Configuration -자바 설정 클래스(xml로설정, 자바클래스 설정방법)
@ComponentScan - 자동빈 스캔할 때
@EnableAutoConfiguration - 자동 설정 가능 - 스프링부트 자동으로 빈등록 -> @AutoConfigurationPackage -> @Import({Register.class})
자바설정 파일 클래스 -> @Import({AutoConfigurationImportSelector.class}):선택적으로 결정Starter - 라이브러리를 패키지로 자동결정해줌
@EnableAutoConfiguration - 빈설정을 자동으로 결정
✅ Model 클래스는 애플리케이션의 비즈니스 로직이나 데이터를 가지고 있으며, 이를 뷰에 전달하여 사용자에게 보여지도록 합니다.
데이터의 영속성을 활용한 결과값들은 viewModel에 꼭 필요하다. (클래스 이름 추가 시)
문자열 출력이 아닌 화면 출력을 하는 @Controller 사용 클래스의 UI 사용을 위해서 Model과 @RequestParam을 사용한다
클래스 이름 추가할 때 화면(table : 로우 + 컬럼)과 데이터는 밀접한 관계가 있다.
MVVM 디자인 패턴
✅ Spring AOP (Aspect-Oriented Programming) 는 공통 관심사를 분리하여 관리하는 프로그래밍 접근방법이다.(관점지향프로그래밍 지원 기술)
메소드 안의 기능을 핵심기능, 부가기능으로 나누었을 때, 부가기능을 공통된 하나의 장소에 모아서 관리하는 방식이 AOP 방식이다.
부가기능 : 보안, 로깅(사용자 접속내용 기록), [[트랜잭션]]관리(커밋, 롤백)
수평적 관점(횡단 관심사 cross-cutting concerns): 동등한 관점
예시 설명: 예를 들어, 프로그램에 로깅 기능이 필요한데 이를 모든 코드에 반복해서 작성하는 대신, AOP를 사용하여 로깅 기능을 한 곳에서 관리하고 다른 코드에 적용할 수 있습니다.
<->[[OOP]]가 객체를 중심으로 데이터와 기능을 구성한다면, AOP는 부가기능(advice)을 동적으로 추가해주는 기술이 필요하였다. (공통된 관심사)
java.util.regex.*
execution(* com.example.demo.*Logic.cud*(..))
어떤 반환타입이든지/패키지명/Logic으로 끝나는 클래스/cud로 시작하는 메소드들/매개변수 상관없음
예 : cudEmp, cudBoard, cudNotice(o) / getBoardList, getNoticeList(x)
@Around("execution(* com.example.*.*(..))")
advice 공통 부가기능 담은 클래스 생성 후 아래와 같은 메소드에 전, 후 설정 및 출력을 할 수 있음.
//@Transational
public List<Map<String, Object>> memberList(Map<String, Object> rmap) {
//before advice con.setAutoCommit(false);
logger.info("Dao-memberList");
List<Map<String, Object>> mList = null;
mList = sqlSessionTemplate.selectList("memberList", rmap);
//after advice con.commit();
//con.SetAutoCommit(true); return mList;
}
[!quote] 메소드 안의 기능을 핵심기능, 부가기능으로 나누었을 때, 부가기능을 공통된 하나의 장소에 모아서 관리하는 방식이 AOP 방식이다.
뷰 -> 커맨드 팔레트 -> spring initializr -> 3.1.7 -> 기본값->spring dev tool, web, lobmoc
부가기능을 공통코드로 추가할 때, 중간지점은 약속하기 어려우니 코드의 앞 혹은 뒤에 배치하는 것이 가능
SomeClass(반복되는 코드가 그대로 구현되어있는 클래스)
AnyClass(target 관심사를 분리헤 적용할 클래스)
- 부가기능 적용(m으로 시작) : methodA, methodB,
- 부가기능 적용 x : others
AnyAdvice(pointcut 관심사 분리를 위해 설계한 구현체 클래스-정규식 표현식 사용-m으로 시작하는 메소드)
- target이 되는 AnyClass 에 m으로 시작하는 메소드가 있다면 그 앞과 뒤에 공통코드를 넣도록 설계함으로서 관점지향 프로그래밍에 대해 이해해보자!
AnyMain(메소드 이름 같으면 처리하는 실행 여부 확인하는 클래스)
package com.example.aopdemo;
import java.lang.reflect.Method;
public class AnyMain {
public static void main(String[] args) throws Exception{
Class<?> myClass = Class.forName("com.example.aopdemo.AnyClass");
Object obj = myClass.newInstance();
AnyAdvice anyAdvice = new AnyAdvice();
for(Method m:myClass.getDeclaredMethods()){
anyAdvice.invoke(m,obj,null);
}
}
}
@Transactional
public void methodA(){
System.out.println("methodA 처리 구현");
}
public void methodB(){
System.out.println("methodB 처리 구현");
}
public void others(){
System.out.println("others 처리 구현");
}
@Component
@Aspect // 해당 클래스를 Aspect로 사용하겠다는 것을 명시
class LoggingAdvice {
//대상 “메서드” 실행 전, 후 또는 예외 발생 시에 Advice를 실행
@Around("execution(* com.example.aopdemo.*Target.cud*(..))")
public Object logMethod(ProceedingJoinPoint pj) throws Throwable {
//시작되는 공통코드 - 부가기능 로깅(시작 : 시작시간, 끝 : 결과값 & 처리시간)
// (핵심기능은 AvyTarget의 메소드임)
//시작시간 계산
long start = System.currentTimeMillis();
System.out.println("{{start}}" + pj.getSignature().getName()
+ Arrays.toString(pj.getArgs()));
Object result = pj.proceed();//AnyTarget 처리메소드(핵심기능) 호출
//끝부분 추가 공통코드 - AnyTarget 끝부분에 추가될 코드
System.out.println("account: "+ result);
//현재시간 - 스타트 시간 : 실행(처리)시간을 로그에 찍기
System.out.println("{{end}}" + (System.currentTimeMillis()-start)+"ms");
return result;
}
}
관련 어노테이션
테이블 설계 분리(조인, 트랜잭션)
작성자 인증(세션으로부터 자동입력)
- 어떤 값을 세션에 담을까?
- 어떤 값을 쿠키에 담을까?
- 리액트로 화면을 처리할 때 세션이 지원되지 않는다?
댓글 처리를 구현해 본다면?
- 원글 & 댓글 & DB 설계에 어떻게 그려져야 하는가?
- 상세보기 1건, 댓글 n건
public List<Map<String, Object>> memberDetail(Map<String, Object> rmap) {
logger.info("Logic-memberList");
List<Map<String, Object>> mList = null;
mList = memberDao.memberList(rmap);
// 게시글 & 댓글 입력을 위한 코드 구성
List<Map<String, Object>> cList = null;
Map<String,Object> rmap = new HashMap<>();
cList = memberDao.commentList(rmap);
rmap.put(1,cList);
mList.add(rmap);
return mList;
}
}
package com.example.demo.step1;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan(basePackages = {"pk.gym.controller"})
@ComponentScan(basePackages = {"pk.gym.logic"})
@ComponentScan(basePackages = {"pk.gym.dao"})
@ComponentScan(basePackages = {"pk.gym.config"})
public class RootConfig {
}