티스토리 뷰

반응형

[배워서 바로 쓰는 스프링 프레임워크 - www.yes24.com/Product/Goods/90051375]

 

6.1 소개

 

6.2 @Component - 스프링 빈 식별하기

  • @Component
    • 타입 수준의 애너테이션 이다
    • 클래스가 스프링 빈을 표현한다는 사실을 나타냄
    • 애플리케이션에서는 컨트롤러, 서비스 . 데이터 접근 객체(DAO)에 따라 특별한 @Component를 사용하도록 권장한다
    • @Controller, @Service, @Repository 애너테이션은 @Component로 메타 애너테이션되어 있음
    • @Component, @Controller, @Service, @Repository 은 스프링 컨테이너에 빈을 어떤 이름으로 등록할지 지정하는 value 속성을 받는다
      • <bean> 엘리먼트의 id 속성과 같은 역할
      • value 속성을 명시하지 않으면 스프링은 클래스 이름에서 첫 번째 글자를 소문자로 바꾼 이름을 빈 이름으로 사용함
    • 스프링의 classpath scanning 을 활성화하면 스프링 컨테이너는 @Component, @Controller, @Service, @Repository 를 설정한 빈 클래스를 자동으로 등록한다
      • 스프링 context 스키마에 <component-scan> 엘리먼트를 사용해서 활성화
        • base-package 속성 : 스프링 빈을 검색할 패키지를 콤마(,)로 나눠서 나열한 목록
        • include-filter, exclude-filter 엘리먼트 : 자동 등록시 사용할 컴포넌트 클래스와 제외할 컴포넌트 클래스를 더 간결하게 지정
          • type 속성
            • annotation : expression 속성은 빈 클래스에 설정한 애너테이션의 전체 클래스 이름을 지정
            • assignable : expression 속성은 빈 클래스가 대입 가능한 클래스나 인터페이스의 전체 이름을 지정
            • aspectj : expression 속성은 빈 클래스를 걸러내기 위해 AspectJ 식을 사용
            • regex : expression 속성은 빈 클래스 이름을 걸러낼 때 사용할 정규식(regular expression)을 지정
            • custom : 빈 클래스를 걸러내기 위해 org.springframework.core.type.TypeFilter 인터페이스에 대한 구현을 expression에 지정
  • 애너테이션을 설정한 빈 클래스에서는 @Autowired, @Inject 등의 애너테이션을 사용해 의존 관계를 기술

 

6.3 @Autowired - 객체 타입으로 의존 관계 자동 연결하기

  • @Autowired로 의존 관계를 '객체의 타입으로' 자동 연결
  • 생성자 수준, 메서드 수준, 필드 수준에서 사용 가능
  • 필드에 붙였을 때
    • 스프링의 AutowiredAnnotationBeanPostProcessor(BeanPostProcessor를 구현함)이 필드를 자동 연결
    • 필드나 필드에 대응하는 세터 메서드가 꼭 public이어야 할 필요는 없음
  • 메서드에 붙였을 때
    • 스프링의 AutowiredAnnotationBeanPostProcessor(BeanPostProcessor를 구현함)이 메서드 인수를 자동 연결
    • 메서드가 public일 필요는 없음
    • 빈 인스턴스가 생성된 다음에 @Autowired를 설정한 메서드가 자동으로 호출되고
      @Autowired를 설정한 필드에 일치하는 빈 인스턴스가 주입된다
  • 생성자에 붙였을 때
    • 스프링의 AutowiredAnnotationBeanPostProcessor(BeanPostProcessor를 구현함)이 생성자 인수를 자동 연결
    • @Autowired를 설정한 생성자가 public일 필요는 없음
    • 스프링 4.3부터 빈 클래스에 생성자가 단 하나만 있는 경우 이 유일한 생성자에 @Autowired를 설정할 필요가 없음
      • 스프링 컨테이너는 디폴트로 이런 유일한 생성자에 대한 자동 연결을 수행함
  • @Autowired를 사용할 때 자동 연결에 필요한 타입과 일치하는 빈을 찾을 수 없으면 예외가 발생함
  • @Autowired의 required 속성은 의존 관계가 필수적인지 여부를 지정함
    • required 속성값이 false인 경우 필요한 타입을 스프링 컨테이너 안에서 찾을 수 없어도 예외가 발생하지 않음
    • 디폴트 값은 true
    • 빈 클래스의 생성자에 required 속성이 true인 @Autowired를 설정하면 다른 생성자에 @Autowired를 설정할 수 없음
    • 빈 클래스에 required가 false인 @Autowired 애너테이션을 설정한 생성자가 여럿 있어도 된다
      • 스프링은 인스턴스를 생성할 때 만족할 수 있는 의존 관계 개수가 가장 큰 생성자를 선택함

 

6.4 @Qualifier - 빈 이름으로 의존 관계 자동 연결하기

  • @Autowired와 @Qualifier를 함께 사용하면 의존 관계를 빈 이름으로 자동 연결할 수 있음
  • @Qualifier는 필드 수준, 메서드 수준, 생성자 수준에서 사용
  • @Qualifier의 value 속성은 인스턴스를 대입할 빈의 이름을 지정
  • 스프링은 먼저 @Autowired를 설정한 필드, 생성자 인수, 메서드 인수의 객체의 타입으로 후보 빈을 찾음
    -> 스프링은 @Qualifier를 사용해 자동 연결 후보 목록에서 유일한 빈을 구별함

6.4.1 지정자를 사용해 빈 자동 연결하기

  • 지정자란 @Qualifier를 사용해 빈을 연결할 때 사용하는 문자열을 뜻함
    • 클래스 선언할 때 빈에 지정자를 연관시키고 다른 곳에서 @Autowired를 사용해서 연결할 때 사용 
    • 유일할 필요는 없음
  • 타입 지정 컬렉션(typed collection)으로 지정자와 연관된 모든 빈을 자동 연결할 수 있음

6.4.2 커스텀 지정자 애너테이션 만들기

  • 애너테이션에 메타 애너테이션으로 @Qualifier를 지정해서 커스텀 지정자 애너테이션이라는 것을 나타냄
    • @Qualifier를 지정하지 않으면 스프링 CustomAutowirConfigurer빈(BeanFactoryProcessor 타입)을 사용해 명시적으로 커스텀 지정자 애너테이션을 등록해야 함

 

6.5 JSR 300 @Inject와 @Named 애너테이션

  • JSR 300(자바 의존 관계 주입)은 자바 플랫폼상의 의존 관걔 주입 애너테이션을 표준화한다
  • @Inject
    • @Autowired 애너테이션과 뜻이 같음
    • 객체의 타입으로 의존 관계를 자동 연결
    • 메서드 수준, 생성자 수준, 필드 수준에서 사용할 수 있음
    • 생성자 의존 관계 주입이 가장 먼저 일어나고 필드 주입이 그 다음에 일어나며, 메서드 주입은 가장 나중에 일어남
    • @Autowired의 required 속성과 같은 역할을 하는 부분이 없지만
      자바 8의 Optional 타입을 사용하면 똑같은 동작을 수행할 수 있음
  • @Named
    • 타입 수준에서 사용하면 @Component 애너테이션과 마찬가지로 작동함
    • 메서드 파라미터 수준에서 사용하거나 생성자 인수 수준에서 사용하면 스프링 @Qualifier 애너테이션처럼 작동
    • 클래스에 설정하면 스프링 context 스키마의 <component-scan> 엘리먼트가 클래스를 마치 @Component 애너테이션을 설정한 빈 클래스처럼 취급함

6.5.1 자바 8 Optional 타입

  • 스프링은 Optional 타입인 필드, 생성자 인수, 메서드 파라미터를 자동 연결할 수 있음

 

6.6 JSR 250 @Resource 애너테이션

  • @Resource로 필드와 세터 메서드를 '빈 이름으로' 자동 연결하도록 지원한다
    • CommonAnnotationBeanPostProcessor(BeanPostProcessor 인터페이스를 구현함)가 @Resource 애너테이션을 처리함
    • name 속성은 자동 연결한 빈의 이름을 지정
    • 생성자 인수나 여러 인수를 받는 메서드 인수를 자동 연결하는 경우에는 @Resource 애너테이션을 사용할 수 없음
  • 빈 이름으로 자동 연결해야하는 경우 @Autowired와 @Qualifier 애너테이션을 사용하는 대신 @Resource를 사용해야 함
    • @Autowired와 @Qualifier 조합을 통해 빈 이름으로 자동 연결을 시도하면 스프링이 먼저 필드 타입(또는 메서드 인수 타입이나 생성자 인수 타입)과 일치하며 자동 연결할 수 있는 빈을 찾고 그후 @Qualifier로 지정한 이름을 사용해 후보 빈을 줄임
    • @Resource를 사용하면 스프링은 name 속성값에 지정한 이름을 사용해 단 하나의 빈을 찾아냄
      • 스프링은 @Resource를 처리할 때는 자동 연결할 필드(또는 세터 메서드 인수) 타입을 고려하지 않음
  • 빈 자체가 Map 타입인 경우 @Autowired 애너테이션은 제대로 작동하지 않음
    • 이런 경우 @Resource를 이용해 자동 연결해야 함
  • @Resource의 name 속성값을 지정하지 않으면 필드나 프로퍼티 이름을 name 속성의 디폴트값으로 사용함
    • name 속성값과 같은 이름의 빈을 먼저 찾고 없으면 타입이 name 속성 값과 같은 빈을 찾음

 

6.7 @Scope, @Lazy, @DependsOn, @Primary 애너테이션

애너테이션 설명
@Scope 빈 스코프를 지정한다(<bean> 엘리먼트의 scope 속성과 같다)
@Lazy 스프링 컨테이너가 빈을 지연해서 생성할지 지정한다(<bean> 엘리먼트의 lazy-init 속성과 같다)
@DependsOn 빈의 암시적 의존 관계를 설정한다(<bean> 엘리먼트의 depends-on 속성과 같다)
@Primary 빈을 자동 연결 제1후보로 지정한다(<bean> 엘리먼트의 primary 속성과 같다)

6.7.1 @Scope

  • 스프링 @Scope 애너테이션은 빈 스코프를 지정한다
    • 스프링 빈의 디폴트 스코프는 싱글턴 스코프로 다른 스코프를 지정하고 싶으면 @Scope로 지정해야 한다
    • @Scope는 <bean> 엘리먼트의 scope 속성과 같은 역할을 한다
  • @Scope는 빈 스코프를 지정하는 value 속성을 받음
    • 문자열로 넣어도 되고 ConfigurableBeanFactory(singleton과 prototype 스코프에 대한 상수를 정의함)와
      WebApplicationContext 인터페이스(application, session, request 스코프에 대한 상수를 정의함)에
      정의된 SCOPE_* 상수를 사용해 value 값을 지정할 수도 있다
    • value 속성 대신 scopeName 속성을 사용해 빈 스코프를 지정할 수도 있다

6.7.2 @Lazy

  • 기본적으로 싱글턴 스코프 스프링 빈은 즉시 초기화된다
  • 싱글턴 빈을 나중에 생성하고 싶다면 싱글턴 빈 클래스에 @Lazy 애너테이션을 붙인다
  • @Lazy 애너테이션의 value 속성은 빈을 나중에 초기화할지 바로 초기화할지 지정한다
    • value 속성값을 true로 하거나 지정하지 않으면 빈을 나중에 초기화하는 것으로 간주한다
  • @Lazy 애너테이션을 지연 자동 연결(lazy autowire) 의존 관계에 사용할 수도 있다

6.7.3 의존 관계를 지연 자동 연결하기

  • @Lazy와 자동 연결 애너테이션(@Autowired, @Inject, @Resource 등)을 함께 사용하면 의존 관계의 자동 연결을 늦출 수 있다
    • 의존하는 빈이 의존 관계에 접근해야만 의존 관계를 자동 연결한다
  • 예제
    • 싱글턴 빈을 자동 연결할 때 @Lazy 애너테이션을 사용하면 빈이 생성될 때가 아니라 빈 메서드에서 해당 빈을 최초로 접근할 때 생성되고 그 후로 계속 사용된다
    • 프로토타입 빈을 자동 연결할 때 @Lazy 애너테이션을 사용하면 빈이 메서드에서 접근할 때마다 새로운 프로토타입 빈 인스턴스가 생성되어 사용된다

6.7.4 @DependsOn

  • @DependsOn 애너테이션은 암시적으로 빈 의존 관계를 지정할 수 있다
    • @DependsOn이 붙은 클래스를 생성하기 전에 @DependsOn의 value 속성에 있는 빈을 생성하라고 스프링 컨테이너에 지시한다

6.7.5 @Primary

  • 어떤 의존 관계에 대해 자동 연결할 수 있는 후보가 여럿 있다면 @Primary 애너테이션을 사용해 한 빈을 자동 연결의 제1후보로 지정할 수 있다

 

6.8 @Value 애너테이션을 사용해 빈 클래스 설정하기

  • 애너테이션을 설정한 스프링 빈은 XML 파일에 정의되지 않기 때문에 <property>나 <constructor-arg> 엘리먼트의 value와 같은 역할을 하는 스프링 @Value를 사용해야 한다
  • @Value는 필드 수준, 메서드 수준, 메서드 파라미터 수준, 생성자 인수 수준에서 사용할 수 있다
  • 스프링 AutowiredAnnotationBeanPostProcessor가 @Value 애너테이션도 처리한다
  • @Value 애너테이션의 value 속성은 필드의 디폴트 값으로 지정한다
    • value 속성으로 문자열이나 SpEL 식을 지정할 수 있다

6.8.1 @Value 애너테이션에 SpEL 사용하기

  • SpEL 식은 실행 시점에 객체에 대한 질의를 수행하고 객체를 조작할 때 사용하는 표현 언어(expression language)다
  •  AutowiredAnnotationBeanPostProcess(BeanPostProcessor)가 @Value에 지정한 SpEL 식을 처리한다
  • SpEL 식은 <빈 이름>.<필드 또는 프로퍼티 또는 메서드> 형식을 사용해 값을 읽을 수 있다

6.8.2 @Value 애너테이션을 메서드 수준과 메서드 파라미터 수준에서 사용하기

  • @Value 애너테이션은 @Autowired, @Resource, @Inject 애너테이션이 설정된 메서드에 대해서만 사용할 수 있다
  • 인수를 받는 메서드를 호출하기 위해 SpEL을 사용할 수 있다

6.8.3 SpEL에서 수학, 관계, 논리 연산자 사용하기

  • SpEL에서 수학, 관계, 논리 연산자를 사용할 수 있다

6.8.4 SpEL을 사용해 빈 참조 얻기

  • @Value 애너테이션에 빈 이름만 사용하면 빈에 대한 참조를 얻을 수 있다

6.8.5 SpEL 안에서 정규식 사용하기

  • SpEL에서 matches 연산자를 통해 정규식을 쓸 수 있다

6.8.6 SpEL에서 맵과 리스트 다루기

  • SpEL에서 맵과 리스트를 다룰 수도 있다

6.8.7 XML 기반 빈 정의에서 SpEL 사용하기

  • XML 파일에 들어 있는 빈 정의에서도 SpEL을 쓸 수 있다

 

6.9 스프링 Validator 인터페이스를 사용해 객체 검증하기

  • 스프링 Validator 인터페이스는 스프링 검증 API(Validation API)의 일부분이며 인터페이스를 사용해 객체를 검증할 수 있다
  • Validator를 사용해 애플리케이션의 어느 레이어에서나 객체를 검증할 수 있다
  • Validator 인터페이스에는 supports와 validate 메서드가 들어 있다
    • supports 메서드는 제공받은 타입(clazz 속성으로 표현)의 객체 인스턴스를 검증할 수 있는지 검사한다
      • supports가 true를 반환하면 validate 객체를 사용해 객체를 검증한다
    • validate 메서드가 객체를 검증한다
      • validate 메서드는 검증할 객체 인스턴스와 Erros 인스턴스를 인수로 받는다
      • 검증하는 동안 발견한 오류를 저장하기 위해 Erros 인스턴스의 reject 메서드를 사용한다

 

6.10 JSR 380(빈 검증 2.0) 애너테이션을 사용해 제약 사항 지정하기

  • JSR 380(빈 검증 2.0) 애너테이션을 사용하면 자바빈즈(JavaBeans) 컴포넌트에 대해 제약 사항을 애너테이션으로 기술할 수 있다
    • JSR 380과 스프링을 함께 사용할 때는 빈 프로퍼티, 메서드, (컬렉션이나 맵과 같은) 컨테이너 엘리먼트에 JSR 380 애너테이션을 설정하고, 스프링은 애너테이션을 설정한 빈에 대한 검증을 수행하여 결과를 제공한다
  • JSR 380 애너테이션을 사용해 필드에 적용할 수 있는 제약 사항을 깔끔하게 지정할 수 있다
    • 스프링 검증 API를 사용해 객체를 검증하면 제약 사항 정보가 Validator 안에 들어간다
  • 예시
JSR 380 제약 사항 설명
@NotNull @NotNull 애너테이션의 필드값은 null이 아니어야 한다
@Min @Min 애너테이션이 지정한 필드값은 최솟값보다 크거나 같아야 한다
@Max @Max 애너테이션이 지정한 필드값은 최댓값보다 작거나 같아야 한다
@NotBlank @NotBlank 애너테이션을 설정한 필드는 null이나 빈 값이 아니어야 한다
@Size @Size 애너테이션이 붙은 필드의 크기(길이)는 지정한 min과 max 사이여야 한다
  • 하이버네이트 검증기 프레임워크(Hibernate Validator Framework)는 JSR 380 애너테이션과 함께 사용할 수 있는 다른 제약 사항 애너테이션을 추가로 제공한다(@Currency, @CreditCardNumber 등)

6.10.1 스프링의 JSR 380 지원

  • LocalValidaotrFactoryBean
    • 스프링은 JSR 380 제약 사항을 사용하는 객체를 LocalValidatorFactoryBean을 통해 검증할 수 있다
    • LocalValidaotrFactoryBean 클래스는 애플리케이션 클래스경로에 JSR 380 프로바이더(하이버네이트 검증기 등)가 존재하는지 인식해서 초기화한다
    • LocalValidaotrFactoryBean는 JSR 380의 Validator와 ValidatorFactory 인터페이스를 구현하는 동시에
      스프링 Validator 인터페이스도 구현한다
      • 검증을 위해 JSR 380 API를 사용하지 않아도 된다
        • 개발자가 JSR 380에 한정된 API를 사용하지 않아도 되도록 중간에서 방패 역할을 한다
      • 검증을 위해 JSR 380 API를 사용할 수도 있다
        • ex) Set<ConstraintViolation<검증할 클래스>> violations = validator.validate(검증할 객체);
          • validate 메서드는 JSR 380 프로바이더가 보고한 제약 사항 위배 내용이 들어 있는 java.util.Set 객체를 반환한다
          • 각각의 제약 조건 위반은 ConstraintViolation 객체에 의해 표현된다

6.10.2 메서드 검증

  • 메서드 검증 : 메서드의 인수와 반환값을 검증하는 것
    • JSR 380은 메서드 검증을 지원한다
    • 메서드 검증을 활성화하려면 스프링 MethodValidationPostProcessor를 설정해야 한다
      • MethodValidationPostProcessor는 BeanPostProcessor 인터페이스를 구현하며 메서드 검증을 JSR 380 프로바이더에게 위임한다
      • MethodValidationPostProcessor는 @Validated가 설정된 빈 클래스를 검색해 JSR 380 제약 사항 애너테이션을 사용하는 메서드의 검증 지원을 추가한다
    • JSR 380 제약 사항은 상속된다

6.10.3 JSR 380에서 바뀐 부분

  • 스프링5는 JSR 349와 JSR 380을 모두 지원하지만 JSR 380을 사용하는 것이 좋다
    • JSR 380에서 사용할 수 있는 JSR 349에 없는 기능
      • 컨테이너 엘리먼트(컬렉션, 맵 등)에 있는 원소의 제약 사항을 지정할 수 있다
      • java.util.Optional 타입 변수의 제약 사항을 지정할 수 있다
      • @NotBlank, @Email, @Positive, @PositiveOrZero 등 새로운 제약 사항이 추가됐다
  • JSR 380을 사용하면 애플리케이션에서 커스텀 제약 조건을 만들어 사용할 수 있다

 

6.11 빈 정의 프로파일

  • 프로파일 : 빈으로 이뤄진 집합에 부여한 이름
    • 스프링의 빈 정의 프로파일(bean definition profile) 기능을 사용하면 빈 집합과 프로파일(profile)을 연결시킬 수 있음
    • 어떤 프로파일이 활성화되면 스프링 컨테이너는 그 프로파일과 연관된 빈을 생성한다
      • 프로파일을 활성화하려면 spring.profiles.active 프로퍼티 값으로 프로파일 이름을 지정해야 한다
      • spring.profiles.active 프로퍼티를 시스템 프로퍼티, 환경 변수, JVM 시스템 프로퍼티, 서블릿 컨텍스트 파라미터, JNDI 항목 등으로 정의할 수 있다
    • 보통 환경에 따라 서로 다른 빈을 사용하고 싶을 때 프로파일과 빈을 연관시킨다

6.11.1 빈 정의 프로파일 예제

 

6.11.2 개발과 프로덕션 환경에서 다른 데이터 베이스 사용하기

  • <beans> 태그는 하나 이상의 프로파일과 연관된 빈들을 정의한다
    • profile 속성은 빈들이 속한 프로파일을 하나 이상 지정한다

6.11.3 하이버네이트와 마이바티스 모두 지원하기

  • 클래스에 @Profile 애너테이션으로 어떤 프로파일이 활성화되었을 때 빈을 등록할지 정할 수 있음

6.11.4 프로파일 활성화하기

  • 프로파일을 지정하지 않으면 스프링 컨테이너는 default 프로파일을 활성화된 프로파일로 간주한다
  • spring.profiles.default 프로퍼티를 설정하면 디폴트 프로파일 이름을 default에서 다른 이름으로 바꿀 수 있다
  • XML 파일에 정의된 모든 빈이 똑같은 프로파일(또는 똑같은 여러 프로파일)에 속하면 최상위 <beans> 엘리먼트의 profile 속성을 사용해 모든 빈이 속하는 프로파일을 하나 이상 지정할 수 있다
  • 프로파일을 연관시키지 않은 빈은 현재 활성화된 프로파일과 관계없이 항상 스프링 컨테이너에 등록된다
  • 프로파일 이름에 ! 연산자를 붙이면 해당 프로파일이 활성화되지 않아야 빈이 스프링 컨테이너에 등록된다

 

6.12 요약

반응형
댓글
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31
글 보관함