티스토리 뷰
[배워서 바로 쓰는 스프링 프레임워크 - 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에 지정
- type 속성
- 스프링 context 스키마에 <component-scan> 엘리먼트를 사용해서 활성화
- 애너테이션을 설정한 빈 클래스에서는 @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 속성을 사용해 빈 스코프를 지정할 수도 있다
- 문자열로 넣어도 되고 ConfigurableBeanFactory(singleton과 prototype 스코프에 대한 상수를 정의함)와
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 메서드를 사용한다
- supports 메서드는 제공받은 타입(clazz 속성으로 표현)의 객체 인스턴스를 검증할 수 있는지 검사한다
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 객체에 의해 표현된다
- ex) Set<ConstraintViolation<검증할 클래스>> violations = validator.validate(검증할 객체);
- 검증을 위해 JSR 380 API를 사용하지 않아도 된다
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에서 사용할 수 있는 JSR 349에 없는 기능
- 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 요약
'study > 배워서 바로 쓰는 스프링 프레임워크' 카테고리의 다른 글
Chapter05. 빈과 빈 정의 커스텀화하기 (0) | 2021.07.12 |
---|---|
Chapter04. 의존 관계 주입 (0) | 2021.07.11 |
Chapter03. 빈 설정 (0) | 2021.05.24 |
Chapter02. 스프링 프레임워크 기초 (0) | 2021.05.10 |
Chapter01. 스프링 프레임워크 소개 (0) | 2021.01.16 |
- Total
- Today
- Yesterday
- 코틀린
- 쿠버네티스
- springboot
- Spring
- k8s
- docker for mac
- 도커
- 자바
- 클린코드
- gasmask
- JavaScript
- ddd
- linuxkit
- IntelliJ
- 스프링
- docker pull limit
- Kubernetes
- kotlin
- gradle
- 자바스크립트
- back merge
- ImagePullBackOff
- java
- cacheable
- docker
- 스프링부트
- QuickTimePlayer
- clean code
- 도메인주도설계
- kotlin In Action
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |