Skip to content

Latest commit

 

History

History
144 lines (94 loc) · 8.17 KB

TIL220307.md

File metadata and controls

144 lines (94 loc) · 8.17 KB

Daily to do list

Java


Spring


CS


알고리즘


오늘의 회고

오랜만에 올리는 TIL은 swift가 아닌 Spring이다. 퇴사를 하고 난 뒤 개발이라는 것 자체에 대한 생각을 많이 갖게 되었다. 코딩 테스트와 면접에서 여러번 떨어지기를 반복하며 취업에 유리한 그저 돈을 벌기 위한 생각만 가득한 개발을 생각하고 있었다. 그러다보니 어느새 번아웃 비슷하게 오고 QC일에 우선 집중을 하면서 개발이라는 것 자체를 돌아보는 시간을 가졌다. 그렇게 나의 결론은 Spring이였다. 개발이 좋다 하지만 나에게 안정감을 주는 취업도 그만큼 중요하다. 내가 좋아하는 개발과 현재 불안한 감정을 둘 다 버리기 위해선 최선의 선택이고 후회는 없다. TIL을 Spring으로 새로 시작할까를 고민하였지만 이러한 나의 고민의 흔적들을 나중에 본다면 도움이 될 것이라 생각하여 그대로 이어 나간다. 화이팅


220308 spring

DI 의존관계 주입

@controller 어노테이션 사용하면 스프링 컨테이너가 뜰 때 컨트롤러를 생성하여 관리함

스프링 컨테이너에 등록하면 하나만 쓰게 된다. + 부가적인 효과가 있다. 생성자로 연결, @Autowired = 연결을 시켜줌

controller > Service > repository = 정형화된 패턴, 어노테이션으로 spring이 실행될 때 가져오도록

컨트롤러와 서비스를 생성자에서 오토와이어를 쓰면 컨트롤러가 생성이 될 때 스프링 빈에 설정되어 있는 서비스를 주입해준다 = 의존성 주입 , 서비스에서 오토와이어가 쓰여 있으면 리포지토리를 주입해준다. = 의존성 주입

&& 스프링 빈을 등록하는 두가지 방법, 둘 다 알아야함 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때, 기본적으로 싱글톤으로 등록 (유일하게 하나만 등록해서 공유)

  • 컴포넌트 스캔과 자동 의존관계 설정 @Component 애노테이션이 있으면 스프링 빈으로 자동 등록 된다, 메인파일과 동일 폴더, 하위 폴더만 스캔 어노테이션으로 controller, service, reoository(컴포턴트 애노테이션이 붙어 있음) 를 설정 시 스프링이 실행되면 어노테이션들을 객체로 만들어서 스프링 컨테이너에 올려준다. + @Autowired를 생성자에 쓰면 이 객체들의 선을 연결해준다.

  • 자바 코드로 직접 스프링 빈 등록하기 메인과 같은 폴더에 SpringConfig라는 파일을 만들고 @Configuration, @Bean으로 서비스와 리포지토리를 컨테이너에 등록하고 오토와이어같이 서비스를 리포지토리에 연결해준다. 그리고 컨트롤러는 어쩔 수 없이(이유 찾아봐야함) 컴포넌트 스캔으로 찾으므로 @Controller, @Autowired를 사용하여 컨테이너에 등록, 서비스와 연결을 한다.

DI의 장점으로 자바 코드로 직접 DI하면 코드를 조금만 고쳐도 DB변경이 가능함. 개방-폐쇄 원칙 : 확장에는 열려있고, 수정에는 닫혀있다. 스프링의 DI을 사용하면 기존 코드를 전혀 손대지 않고, 설정만으로 구현 클래스를 변경할 수 있다. 회원을 등록하고 DB에 결과가 잘 입력되는지 확인,

DI의 3가지 방법 = *제일 좋음 = 생성자 주입(어플리케이션 조립이 될 때 하므로 안전, 생성자가 하나면 애노테이션 생략 가능), 필드 주입(잘안쓰임 나중에 못바꿈), setter 주입(누군가 멤버 호출 시 public하게 노출이 됨) 외존관계가 실행 중에 동적으로 변하는 경우는 없다. 생성자 주입을 권장

실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔, 정형화 되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록(예) 데이터베이스가 바뀐다던지?

@Autowired를 통한 DI는 스프링이 관리하는 객체에서만 동작, 스프링 빈으로 등록하지 않고 내가 직접 생성하는 객체에서는 동작하지 않는다.

————————— 컨텐츠 찾는 순서 : 스프링 컨테이너 먼저 찾고 없으면 정적 컨텐츠를 찾음.

  • getter setter 개념 다시 확인

——————— @SpringBootTest : 스프링 컨테이너와 테스트를 함께 실행한다. @Transactional : 테스트 케이스에 이 애노테이션이 있으면, 테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백한다. 단위 테스트 : 순수 자바 코드만 갖고 하는 테스트 = @Test 통합 테스트 : 서버, 디비등 같이 돌리는 테스트 = @SpringBootTest

——————————— 스프링 DB접근 기술

H2, JDBC, JPA

  • 순수 JDBC 순수 JDBC = 완전.. 구식 소스량이 장난 아님

  • JDBC Template 스프링 JdbcTemplate = Mybatis와 같은 템플릿 JdbcTemplate = 이전 엄청 긴 JDBC코드를 압축한 라이브러리

  • JPA ORM Ojbect RelationshipMapping JPA = SQL과 데이터 중심의 설계에서 객체 중심의 설계로 패러다임으로 전환 개발 생산성을 크게 높일 수 있다. , hibernate = 구현 기술 JPA는 자바 진형의 표준 인터페이스임, Hibernate가 구현체,구현기술임 다양하게 구현 기술이 있음.

EntityManager를 만들어 준다. 이걸 주입 받아서 쓴다

PK기반의 하나를 찾는 경우 간단하게 가능하지만 그게 아니면 jpql이라는 객체지향의 쿼리문을 날려줘서 찾아야 한다. (예) ID는 간단하게 가능하지만 Name은 jpql을 필수로 쓴다.

jpql을 쓸려면 항상 @Transactional 애노테이션을 꼭 달아줘야 한다.

  • 스프링 데이터 JPA CRUD기능도 스프링 데이터 JPA가 모두 제공. 실무에서 관계형 데이터베이스를 사용하면 스프링 데이터 JPA가 중요 JpaRepository가 findAll,findById,save 등등 CRUD의 기본적인 것들을 전부 다 만들어져 있음. 그래서 불러오기만하면 됨. 하지만 findByName 등 공통이 아닌 것들은 추가해야함 근데 인터페이스 이름만으로도 간단하게 여러가질 구현할 수 있음 (예) findByNameAndEmail 처럼 메서드 이름 만으로도 조회 가능 페이징 기능 자동 제공

실무에서는 JPA와 스프링 데이터 JPA를 기본, 복잡한 동적 쿼리는 Querydsl이라는 라이브러리 사용, 정말 복잡하다면 네이티브 쿼리를 사용하거나 JdbcTemplate를 사용하면 된다.

——— interface가 interface를 받을 때는 extends, class가 interface를 받을 때는 implement.

처음에 서버 로딩 후 기능 첫실행 시 클래스 메타데이터 로딩 등 시간이 더 걸려 속도가 중요한 프로젝트는 warm up으로 한번 씩 실행을 해주기도 함 ———————————— AOP = Aspect Oriented Programming

AOP가 필요한 상황 예)? 모든 메소드의 호출 시간을 측정하고 싶다면? 핵심 기능은 아니고, 공통 관심사항임, 시간을 측정하는 로직을 공통의 로직으로 만들기 어렵다. 모든 로직을 찾아가면서 다 추가해야 한다.

만약 AOP를 쓴다면? 공통 관심 사항과 핵심 관심 사항을 분리

AOP를 사용하면 ComponentScan을 사용하기 보다는 공통으로 적용이 되기 때문에 AOP를 사용한다는 것을 알리기 위해 SpringConfig 같은 곳에 선언해주는 것을 선언한다.

@Around("execution(* hello.hellospring..*(..))") // 하면 지정패키지 밑으로 다 지정한다는 뜻 , 패키지 단위로 사용이 가능하다

사용 후 장점 공통 관심 사항 분리, 시간을 측정하는 롲기을 별도의 공통 로직으로 만들 수 있음 핵심 관심 사항을 깔끔하게 유지, 변경이 필요하면 이 AOP만 변경하면 된다. 원하는 적용 대상을 선택할 수 있다.

AOP 동작 방식

기존 : helloController >> memberService

AOP적용 후 : helloController >> (프록시memberService) joinPoint.proceed() >> memberService

AOP적용이 된 곳에 프록시를 만들어서 먼저 실행이 된 뒤 joinPoint.proceed()로 실제 객체?로 넘어감