[우아한테크코스] 4월 20일 TIL
오늘 배운 것
- 체스 스프링 피드백 적용
- spring core
- step into (f7): 함수 안으로 들어가기
- step over (f8): 다음 라인 넘어가기
- step out (shift+f8): 함수 밖으로 나오기
체스 스프링 피드백
[Spring] CollectionUtils 활용
CollectionUtils.isEmpty(~~)
을 사용해 빈 collection인지 확인할 수 있다.
contains, find 등과 같은 처리도 할 수 있다.
[Test] 단위테스트에서 mysql 대신 h2 사용
application-test.properties
spring.datasource.url=jdbc:h2:mem:testdb;MODE=MySQL;DB_CLOSE_DELAY=-1
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
test class 상단 어노테이션
@JdbcTest
@TestPropertySource("classpath:application-test.properties")
public class ChessServiceTest {
[Exception] 에러처리는 컨트롤러가 아닌 한 곳에서 처리
@ControllerAdvice, @RestControllerAdvice
@ExceptionHandler가 하나의 클래스에 대한 처리라면, @ControllerAdvice는 모든 곳에서 발생할 수 있는 예외를 잡아서 처리해준다.
구현 방식은 따로 클래스를 만들어서 그 안에서 exceptionhandler를 가지도록 한다.
-
@ControllerAdvice
controllerAdvice는 controller에서 발생한 exception들을 잡아서 처리한다.
비지니스 로직에 두지 않고 분리함으로써 비즈니스 로직에 더욱 집중할 수 잇다. -
@RestControllerAdvice
RestControllerAdvice는 RestController처럼 ControllerAdvice 어노테이션과 ResponseBody 어노테이션을 합쳐놓은 어노테이션이다.
responseBody로 전달한다면 restControllerAdvice를 사용하면 된다.
또한 controllerAdvice에는 modelAttribute를 추가해 model을 보다 넓게 사용할 수 있다.
@ControllerAdvice
public class chessAdvice {
@ExceptionHandler(PieceMoveException.class)
public ResponseEntity<String> domainExceptionHandle(PieceMoveException e) {
return ResponseEntity.badRequest().body(e.getMessage());
}
@ExceptionHandler(SQLException.class)
public ResponseEntity<String> sqlExceptionHandle(SQLException e) {
return ResponseEntity.badRequest().body("sql 에러가 발생했습니다.");
}
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> runtimeExceptionHandle(RuntimeException e) {
return ResponseEntity.badRequest().body("프로그램 실행 중 문제가 발생햇습니다.");
}
}
[Spring] dao와 repository
리뷰어는 jdbcTemplate을 주입받아서 사용하는 것 자체가 jdbcTemplate이 dao의 역할을 수행해주고 있는 것으로 보인다고 하였다.
그도 그럴 것이 db에서 받은 정보를 jdbcTemplate이 실행해서 값으로 넘겨주기 때문에 data access object의 역할을 한다고 볼 수 있다.
[Spring] core
-
의존성 추가
직접 의존을 추가할 수도 있지만 귀찮고 이전에 강한 결합이 생기고 변경이 힘들어진다는 단점이 있다.
그래서 스프링에서는 대신 의존성을 추가해줄 수 있다.
스프링 컨테이너에 빈들이 존재하고 이들 사이에는 특정한 관계가 존재한다. -
bean 등록
@Repository, @Service, @Component와 같은 어노테이션이 등록되면 bean으로 등록된다.
@Configuration은 @Bean 태그를 달아서 bean을 등록할 수 있도록 해준다.
@ComponentScan을 사용한 bean 등록 가능
bean으로 등록하려면 상태가 없어야 한다. 상태가 없는 것을 bean으로 등록하자
bean으로 등록하는 객체의 기준: 상태가 없는 것
bean으로 등록하고 싶은 businuess objects(POJO)를 Configuration Metadata를 이용해 spring container에 등록
spring이 객체를 관리하게 하려면 객체 관리 대상 지정
, 의존성 설정
-
컨테이너 설정 방법 - bean 등록 방법
@Component라는 어노테이션이 붙으면 bean이 설정된다(사실 @Service, @Repository와 같은 애들도 뜯어보면 @Component 사용중)
@ComponentScan 어노테이션을 붙이면 등록할 bean을 찾을 classpath를 지정한다. 보통 application 클래스에 선언 -
의존성 주입 방법
xml을 통해, @Autowired를 통해, java class를 통해- 생성자 위에 @Autowired 어노테이션 붙이기
- setter에 @Autowired 어노테이션 붙이기
@Test
void componentScan() {
ApplicationContext context = getApplicationContext(); //spring에서 관리하는 컨테이너가 실존하는 것
LineDao dao = context.getBean("lineDao", LineDao.class);
assertThat(dao).isNotNull();
LineService service = context.getBean("lineService", LineService.class);
assertThat(service).isNotNull();
}
private ApplicationContext getApplicationContext() {
ApplicationContext context = new AnnotationConfigApplicationContext(HelloApplication.class); //HelloApplication > @SpringBootApplication 설정을 통해 이미 ComponentScan 설정
String[] beanDefinitionNames = context.getBeanDefinitionNames(); //context에 들어있는 bean들에 접근
System.out.println(Arrays.toString(beanDefinitionNames));
return context;
}
}
-
스프링 빈이 공유하면 안되는 객체를 의존할 경우 Service에서 선언된 상태는 service를 사용하는 모든 컨테이너가 공유하게 된다.
-
POJO는 JAVA BEAN을 포함하는 개념
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
@Override
public void addViewControllers(ViewControllerRegistry registry){
registry.addViewController("/").setViewName("index");
}
}
- 알아볼 것:
- bean으로 등록되면 static 처럼 떠있는건가?
- configuration metadata
- view controller
- spring validation