java 8 정리9

Java 정리 2021. 6. 17. 16:26

인프런 강의 11일차.

 - 더 자바, Java 8 (백기선 강사님)

 

1. 애노테이션의 변화

 - 애노테이션 관련 두가지 큰 변화

   > 자바 8부터 애노테이션을 타입 선언부에도 사용할 수 있게 됨.

   > 자바 8부터 애노테이션을 중복해서 사용할 수 있게 됨.

 

2. 타입 선언 부

 - 제네릭 타입

 - 변수 타입

 - 매개변수 타입

 - 예외 타입

 - ...

 

3. 타입에 사용할 수 있으려면

 - TYPE_PARAMETER : 타입 변수에만 사용할 수 있다.

 - TYPE_USE : 타입 변수를 포함하여 모든 타입 선언부에 사용할 수 있다.

 

4. 중복 사용할 수 있는 애노테이션을 만들기

 - 중복 사용할 애노테이션 만들기

 - 중복 애노테이션 컨테이너 만들기

   > 컨테이너 애노테이션은 중복 애노테이션과 @Retention 및 @Target 값이 같거나 더 넓어야 한다.

 

 

 

package me.whiteship.java8to11;

import java.util.Arrays;
import java.util.List;


@Chicken("양념")
@Chicken("마늘간장")
public class App {

    public static <List> void main(String[] args) {
        //Case 1. Type으로 가져오는 방법
        //chiken type이 해당하는 것을 다 가져온다.
        //즉, 양념, 마늘간장이 배열로 온다
        Chicken[] chickens = App.class.getAnnotationsByType(Chicken.class);
        Arrays.stream(chickens).forEach(c -> System.out.println(c.value()));

        //Case 2. Container로 가져오는 방법
        ChickenContainer chickenContainer = App.class.getAnnotation(ChickenContainer.class);
        Arrays.stream((chickenContainer).value()).forEach(cc -> System.out.println(cc.value()));

//        List<String> names = Arrays.asList("dhpark");
    }

    //특정 타입을 사용하는 제네릭 클래스 정의
    //이 때 사용하는 T, R 등이 타입 파라미터를 의미한다.
    //@Target 애노테이션은 해당 제네릭 타입에 사용할 수 있도록 선언하는 것
    //static class FeelsLikeChicken<@Chicken T> //@Target(ElementType.TYPE_PARAMETER)가 선언되어있어야 사용 가능
    /*
    static class FeelsLikeChicken<@Chicken T> {

        //TYPE_USE로 사용 시 타입을 사용하는 모든 곳에 사용 가능하다.
        //public static <C> void print(@Chicken c)
        public static <C> void print(C c) {
                System.out.println(c);
        }

    }
     */
}

 

package me.whiteship.java8to11;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
//TYPE_PARAMETER, TYPE_USE : java8에서 추가된 옵션
//@Target(ElementType.TYPE_PARAMETER)       //해당 애노테이션을 사용할 곳
@Target(ElementType.TYPE_USE)     //TYPE_PARAMETER를 포함한 TYPE을 쓰는 모든 곳에 사용 가능
@Repeatable(ChickenContainer.class)           //Repeatable 파라미터로 들어가는 class보다 같거나 더 넓은 영역을 커버해야한다.(여러개의 애노테이션을 감싸고 있을 컨테이너 필요)
public @interface Chicken {
    String value();
}

 

package me.whiteship.java8to11;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE_USE)
public @interface ChickenContainer {

    Chicken[] value();      //자기 자신이 감쌀 애노테이션의 변수를 가지고 있어야함.
}

'Java 정리' 카테고리의 다른 글

java 8 정리11  (0) 2021.07.01
java 8 정리10  (0) 2021.06.30
java 8 정리8  (0) 2021.06.02
java 8 정리7  (0) 2021.05.26
java 8 정리6  (0) 2021.05.21

스프링 입문 맛보기 3

Spring 정리 2021. 5. 4. 20:57

인프런 강의 3일차. 

 - 스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술 (김영한 강사님)

 

1. 테스트 클래스 생성(Ctrl + Shift + T)

 - 한글로 작성해도 상관없음 (빌드될 때 실제 코드에 포함되지 않는다)

 - 테스트 메소드 작성 시 추천하는 방법 (given, when, then)

  

2. AssertThrow

 - 메소드 실행 시 해당 에러가 발생해야 test 통과를 의미

 - A와 B의 테스트 결과는 같다.

A. try - catch exception

//given
Member member1 = new Member();
member1.setName("Spring");

Member member2 = new Member();
member2.setName("Spring");
        
//when
memberService.join(member1);		//member1 회원가입
try {
     memberService.join(member2);	//member2 회원가입, 이 때 name이 둘 다 Spring이므로 익셉션발생.
     fail();
}catch (IllegalStateException e){
     assertThat(e.getMessage()).isEqualTo("이미 존재하는 회원입니다"); //발생한 에러 메시지가 "이미 ~ "와 같다면 테스트 통과
}

B. AssertThrow

//given
Member member1 = new Member();
member1.setName("Spring");

Member member2 = new Member();
member2.setName("Spring");

//when
memberService.join(member1);		//member1 회원가입
//member2 회원가입 시 IllegalStateException 발생 시 assertThrow 발생. 즉, 테스트 통과
assertThrows(IllegalStateException.class, () -> memberService.join(member2));

 

3. Dependency Injection

 - 각 테스트를 실행하기 전 같은 인스턴스를 사용하기 위해 인스턴스 생성 때 외부에서 인스턴스를 인자로 넣어줌

//MemberService.java
private final MemberRepository memberRepository;

public MemberService(MemberRepository memberRepository){
	this.memberRepository = memberRepository;	//생성자에서 DI
}


//MemberServiceTest.java
MemberService memberService;
    MemoryMemberRepository memberRepository;

    @BeforeEach
    public void beforeEach(){
        memberRepository = new MemoryMemberRepository();
        memberService = new MemberService(memberRepository);		//Dependency Injection
    }

 

4. 스프링 빈과 의존 관계 설정

 - 스프링이 빈이 관린된다는 의미 : 스프링이 최초 실행될 때 스프링 컨테이너가 생성되는데, 이 때 @Controller 가 있으면 해당 Controller 객체를 생성해서 스프링이 넣어두고 관리한다.

 - 스프링이 관리는 객체의 경우 스프링에서 관리할 수 있게끔 생성자에 @Autowired을 붙여서 관리해야한다.

 - 생성자에 @Autowired가 있으면 스프링이 연관된 객체를 스프링 컨테이너에서 찾아서 넣어준다. 이렇게 객체 의존 관계를 외부에서 넣어주는 것을 DI, 의존성 주입이라 한다.

 - 3번에서는 개발자가 직접 넣어주었고, 아래 소스는 @Autowired에 의해 스프링이 주입해준다.

@Controller
public class MemberController {

    private final MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService){
        this.memberService = memberService;
    }
    //위 코드 실행 시 아래 오류 발생
    /*
      Parameter 0 of constructor in hello.hellospring.controller.MemberController required 
      a bean of type 'hello.hellospring.Service.MemberService' that could not be found.
    */
    
    //memberService는 스프링 빈에 등록되어 있지 않기 때문에 최초 스프링 컨테이너 실행 때 찾을 수 없는 객체이다.
    //memberService클래스에 @Service를 사용하여 스프링 빈에 등록해주면 정상적으로 실행된다.
    //Repository도 마찬가지로 @Repository를 사용하여 스프링 빈에 등록해주어야 한다.
}

 

5. 스프링 빈을 등록하는 2가지 방법

 - 컴포넌트 스캔과 자동 의존관계 설정

 - 자바 코드로 직접 스프링 빈 등록하기

 

6. 컴포넌트 스캔과 자동 의존관계 설정

 - @Component : 애노테이션이 있으면 스프링 빈으로 자동 등록된다.

 - 스프링 시작 시 Component 애노테이션이 있으면 자동으로 객체를 생성해서 스프링 컨테이너에 가지고 있다.

 - @Autowired가 있을 시 해당 객체들을 연결시켜둔다.

 - @Component를 포함하는 다음 애노테이션도 스프링 빈으로 자동 등록된다.

     ->@Contoller, @Service, @Repository : 해당 애노테이션에 들어가보면 @Component로 선언되어있다.

 - 단, 이 때 스캔하는 대상은 @SpringBootApplication 에 등록된 하위 패키지만 스캔한다.

     -> @SpringBootApplication 애노테이션에 들어가보면 @ComponentScan 애노테이션이 있다.

 - 스프링은 스프링 컨테이너에 스프링 빈을 등록할 때 기본으로 싱글톤으로 등록한다(하나의 인스턴스만 등록해서 공유)

 - 설정을 통해 싱글톤이 아니게 할 수 있지만 특별한 경우가 아니면 전부 싱글톤을 사용한다.

 

 

 

* Ctrl + R : 가장 최근에 실행한 테스트 재실행

'Spring 정리' 카테고리의 다른 글

스프링 입문 맛보기 6  (0) 2021.08.04
스프링 입문 맛보기 5  (0) 2021.07.14
스프링 입문 맛보기 4  (0) 2021.07.06
스프링 입문 맛보기 2  (0) 2021.04.29
스프링 입문 맛보기  (0) 2021.04.28