skarltjr / Memory_Write_Record

나의 모든 학습 기록
0 stars 0 forks source link

Spring #9

Open skarltjr opened 3 years ago

skarltjr commented 3 years ago

Spring

화면 캡처 2021-01-20 234241

spring ?

- 가장 중요한 스프링의 탄생배경과 핵심 : 왜 spring?

- 객체 지향의 특징

- 핵심은 유연하게, 변경이 용이하게 -> 언제든지 쉽게 갈아끼울 수 있는

- 다형성 - 역할과 구현을 구분하자 - 인터페이스 / 오버라이딩

- 객체는 협력관계

- 스프링과 객체지향. 제어의역전 IOC - 의존관계 주입 DI 를 통해 역할과 구현을 구분

- 좋은 객체지향 설계의 5원칙 / SOLID

- 스프링을 통해서

skarltjr commented 3 years ago

- IOC 제어의 역전 & DI 의존관계 주입

화면 캡처 2021-01-21 010747

의존 관계 주입을 사용하지 않는 경우 --> 생성자에서 new를 통해 구체적인 대상을 직접

public class Soldier {
    private Gun gun;

    public Soldier() {
        gun = new Gun();
    }
}

그러나 우리는 구체화가 아닌 추상화에 집중해야한다

Screen Shot 2021-07-22 at 5 24 01 PM

추상( 인터페이스인 discountPolicy에 의존하지 구체클래스인 fix or rate discount policy에 의존하지 않는다.)

둘 중 사용하고자 하는 구체 클래스를 @Component로 등록함으로써 언제든지 갈아끼울 수 있다. // 혹은 @Primary .. @Qualifier ...

IOC란 즉 내가 흐름을 제어하는것이 아닌 다른 대상(스프링에게 맡긴다)에게 맡기는 것

ex)스프링이 빈으로 관리하는 클래스를( 여기선 rateDiscountPolicy를 빈으로 등록했다고 가정했을 때 ) 필요할 때 알아서 주입시켜준다.

@Service
public class OrderService {

  private DiscountPolicy discountPolicy;

  @Autowired
  public void setDiscountPolicy(DiscountPolicy discountPolicy) {
    this.discountPolicy = discountPolicy;
  }
}

- DI컨테이너 - ioc컨테이너 - 스프링컨테이너

@Configuration
public class AppConfig {
 @Bean
 public MemberService memberService() {
 return new MemberServiceImpl(memberRepository());
 }
 @Bean
 public OrderService orderService() {
 return new OrderServiceImpl(
 memberRepository(),
 discountPolicy());
 }
 @Bean
 public MemberRepository memberRepository() {
 return new MemoryMemberRepository();
 }
 @Bean
 public DiscountPolicy discountPolicy() {
 return new RateDiscountPolicy();
 }
}

- 스프링 컨테이너

화면 캡처 2021-01-21 012124 화면 캡처 2021-01-21 012141

화면 캡처 2021-01-21 012403

skarltjr commented 3 years ago

싱글톤 컨테이너

- 싱글톤 패턴

스프링 빈이 바로 싱글톤으로 관리되는 빈이다.

싱글톤 컨테이너

싱글톤 방식의 주의점 : STATELESS !!

Bean과 Configuration

skarltjr commented 3 years ago

ComponentScan + @Component + 의존관계 자동주입 Autowired

화면 캡처 2021-01-21 014538

자동등록과 수동등록 - 중복등록의 충돌

  1. 자동 빈 등록 vs 자동 빈 등록
    • ConflictingBeanDefinitionException 예외 발생
  2. 수동 빈 등록 vs 자동 빈 등록
    • 이 경우 수동 빈 등록이 우선권을 가진다.(수동 빈이 자동 빈을 오버라이딩 해버린다.)
skarltjr commented 3 years ago

의존관계 자동주입

주의 - 당연하게도 의존관계 자동 주입은 스프링 컨테이너가 관리하는 스프링 빈이어야 동작한다

생성자 주입을 선택해라!

의존관계 자동주입 시 조회하는 빈이 2개 이상이라면 ?

@Component
public class FixDiscountPolicy implements DiscountPolicy {}
@Component
public class RateDiscountPolicy implements DiscountPolicy {

처럼 2개의 구현체가있을 때

@Autowired
private DiscountPolicy discountPolicy

@Autowired 필드 명, @Quilifier, @Primary

@Component
@Primary
public class RateDiscountPolicy implements DiscountPolicy {}

@Compnent로 자동으로 빈을 등록하는 것이 선호되지만 분명히 수동으로 등록이 필요한 경우가 있다.

skarltjr commented 3 years ago

빈 생명주기 콜백

빈 스코프 : 말 그대로빈이 존재할 수 있는 범위

@Scope("prototype")
@Component
public class HelloBean {}

싱글톤 빈 스코프

화면 캡처 2021-01-22 005236

프로토타입 빈 스코프

화면 캡처 2021-01-22 005314 화면 캡처 2021-01-22 005326

skarltjr commented 3 years ago

트랜잭션과 영속성컨텍스트 - 스프링과 jpa

Transaction ?

선언적 트랜잭션 @Transactional을 써주는 이유?

화면 캡처 2021-01-28 004632

정리 !!

요청 당 하나의 스레드 - 같은 스레드는 같은 트랜잭션 - 같은트랜잭션은 같은 영속성컨텍스트!!

skarltjr commented 3 years ago

Spring의 AOP

public ~ method1(){
   AAA()
   ~~ 여긴 123
   BBB()
}

public ~ method2(){
   AAA()
   ~~ 여긴 456
   BBB()
}

public ~ method3(){
   AAA()
   ~~ 여긴 789
   BBB()
}
@Controller
class OwnerController {

    private static final String VIEWS_OWNER_CREATE_OR_UPDATE_FORM = "owners/createOrUpdateOwnerForm";

    private final OwnerRepository owners;

    ... 여기선 다 필요없고

        ★여기 @LogExecutionTime!!!을 보자 - 위에서 해당 어노테이션이 붙은곳에선 어떤 동작을 수행하도록 설정
            즉 해당 어노테이션이 붙은. 어떤 독립적인 기능을 수행할 코드를 꽂아 넣어 줄 곳을 지정하고 지정된 곳에서 그 기능을 수행  -> 필요한곳마다 독립적인 기능을 수행하는 코드를 작성할 필요 없이

    @GetMapping("/owners/new")
    @LogExecutionTime
    public String initCreationForm(Map<String, Object> model) {
        Owner owner = new Owner();
        model.put("owner", owner);
        return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
    }

    @PostMapping("/owners/new")
    @LogExecutionTime
    public String processCreationForm(@Valid Owner owner, BindingResult result) {
        if (result.hasErrors()) {
            return VIEWS_OWNER_CREATE_OR_UPDATE_FORM;
        }
        else {
            this.owners.save(owner);
            return "redirect:/owners/" + owner.getId();
        }
    }

    @GetMapping("/owners/find")
    @LogExecutionTime
    public String initFindForm(Map<String, Object> model) {
        model.put("owner", new Owner());
        return "owners/findOwners";
    }

....