wannaqueen
  • Initial page
  • Spring boot
    • 스프링부트의 소개
      • 8. 스프링 부트 소개 by ks
      • 9. 시스템 요구사항 by ks
      • 10. 스프링 부트 설치 by ks
      • 11. 첫 번째 Spring Boot 애플리케이션 개발하기 by ys
        • 11.1 POM 만들기
        • 11.2 클래스 패스 의존성 추가하기
        • 11.3 코드 작성하기
        • 11.4 예제 실행하기
        • 11.5 실행 가능한 jar 만들기
      • 12. 다음에 읽을 내용 by ys
      • 13. 빌드 시스템 by sh
        • 13.1 의존성 관리
        • 13.2 Maven
        • 13.3 Gradle
        • 13.4 Ant
        • 13.5 Starters
    • 스프링부트의 기능
      • 23. Spring Application by ys
        • 23.1 startup 실패
        • 23.2 배너를 내가 원하는 대로 바꾸기
        • 23.3 SpringApplication 커스터마이징하기
        • 23.4 Fluent Builder API
        • 23.5 어플리케이션 이벤트와 리스너들
        • 23.6 웹 환경
        • 23.7 Application 인자에 접근하기
        • 23.8 ApplicationRunner 또는 CommandLineRunner 사용
        • 23.9 어플리케이션 종료
        • 23.10 관리자 기능
      • 24. 외부화된 구성 by ys
        • 24.1 임의의 값 구성
        • 24.2 명령행 특성 액세스
        • 24.3 응용 프로그램 속성 파일
        • 24.4 프로파일 관련 프라퍼티들
        • 24.5 프라퍼티들에서 플레이스홀더들
        • 24.6 속성의 암호화
        • 24.7 속성대신 yaml 사용하기 - 다시
        • 24.8 Type-safe Configuration Properties
      • 25. 프로파일 by ks
        • 25.1 Active 프로파일 더하기
        • 25.2 프로그램적으로 프로파일 세팅
        • 25.3 프로파일 별 구성파일
      • 26. 로깅 by ks
        • 26.1 로그 형식
        • 26.2 콘솔 출력
        • 26.3 파일 출력
        • 26.4 로거 레벨
        • 26.5 로그 그룹
        • 26.6 사용자 정의 로그 설정
        • 26.7 로그백 확장
      • 27 국제화 by ks
      • 28. SQL 데이터베이스 작업 by sh
      • 29. NoSQL 기술 사용 by sh
      • 30. 메시징 by sh
      • 31. 이메일 전송 by sh
      • 28. JSON by sh (다시 시작!)
        • 28.1 Jackson
        • 28.2 Gson
        • 28.3 JSON-B
      • 29. 웹 응용 프로그램 개발 by sh
        • 29.1 The “Spring Web MVC Framework”
        • 29.2 The “Spring WebFlux Framework”
        • 29.3 JAX-RS and Jersey
        • 29.4 내장된 서블릿 컨테이너 지원
        • 29.5 내장된 반응형 서버 지원
        • 29.6 반응형 서버 리소스 구성
      • 30. Security by ys
        • 30.1 MVC 보안
        • 30.2 WebFlux 보안
        • 30.3 OAuth2
        • 30.4 Actuator 보안
      • 31. SQL 데이터베이스 작업 by ys
        • 31.1 Configure a DataSource
        • 31.2 JdbcTemplate 사용
        • 31.3 JPA와 스프링 데이터 JPA
        • 31.4 스프링 데이터 JDBC
        • 31.5 H2의 웹 콘솔 사용
        • 31.6 jOOQ 사용하기
      • 32. NoSQL 기술로 작업하기 by ks
      • 33 Caching by ks
      • 34. 메시징
        • 34.1 JMS by sh
        • 34.2 AMQP by sh
        • 34.3 Apache Kafka Support by ys
      • 35.REST 서비스 호출 RestTemplate
        • 35.1 RestTemplate 사용자 정의
      • 36. REST 서비스 호출 WebClient by ys
      • 37. 유효성 확인 by ys
      • 38. 이메일 보내기 by ys
      • 39. JTA를 이용한 분산 트랜잭션 by ys
      • 40.하젤캐스트(Hazelcast) by ys
      • 41. Quartz Scheduler by ys
      • 42. 작업 실행 및 스케줄링 by ys
      • 43. 스프링 통합 by ys
      • 44. Spring 세션 by ys
      • 45. JMX를 통한 모니터링 및 관리 by ys
      • 46. Testing by sh
        • 46.3 Testing Spring Boot Applications
          • 46.1~46.3.10
          • 46.3.11 자동 구성된 Spring WebFlux 테스트
          • 46.3.12 자동 구성된 Data JPA 테스트들
          • 46.3.13 자동 구성된 JDBC 테스트들
          • 46.3.14 자동 구성된 Data JDBC 테스트들
          • 46.3.15 자동 구성된 JOOQ 테스트들
          • 46.3.16 자동 구성된 Data MongoDB 테스트들
          • 46.3.17 자동 구성된 Data Neo4j 테스트
          • 46.3.18 자동 구성된 Data Redis 테스트들
          • 46.3.19 자동 구성된 Data LDAP 테스트들
          • 46.3.20 자동 구성된 REST 클라이언트
          • 46.3.21자동 구성된 Spring REST Docs 테스트
          • 46.3.22 추가적인 자동 구성 및 슬라이스
          • 46.3.23 사용자 구성 및 분할
          • 46.3.24 Spock을 사용하여 스프링 부팅 응용 프로그램 테스트
      • 47. 웹 소켓 by sh
      • 48. 웹 서비스 by sh
        • 48.1WebServiceTemplate로 웹 서비스 호출하기
      • 49. 자신만의 자동 구성 생성
        • 49.1 자동 구성된 빈 이해하기 by sh
        • 49.2 자동 구성 후보 찾기 by sh
        • 49.3 Condition 어노테이션들 by sh
        • 49.4 자동구성 테스팅 by ks
        • 49.5 자신만의 스타터 생성하기 by ks
      • 50. Kotlin support by ys
      • 51. What to Read Next by ys
      • 52. Production-ready 기능 활성화 by ys
      • 53. Endpoints
        • 53.1 엔드 포인트 활성화 by ys
        • 53.2 엔드 포인트 노출 by ys
        • 53.3 HTTP endpoints 보안 by ys
        • 53.4 Endpoints 구성
        • 53.5 액츄에이터 웹 엔드 포인트 용 하이퍼 미디어 by ys
        • 53.6 CORS 지원 by ys
        • 53.7 커스텀 엔드포인트 확장 by ks
        • 53.8 Health 정보 by ks
        • 53.9 어플리케이션 정보 by sh
      • 54. HTTP를 통한 모니터링 및 관리 by sh
        • 54.1 관리 엔드 포인트 경로 사용자 정의
        • 54.2 관리 서버 포트 사용자 정의
        • 54.3 관리 관련 SSL 구성
        • 54.4 관리 서버 주소 사용자 정의
        • 54.5 HTTP 끝점 사용안하기
  • spring 5.0
    • 1. IoC 컨테이너
      • 1.1 스프링 IoC 컨테이너와 빈의 도입 by sh
      • 1.2 컨테이너 by ys
      • 1.3 빈 개요 by ks
      • 1.4 의존성 by ks, ys, sh
        • 1.4.1 의존성 주입 by ks
        • 1.4.2 의존성과 configuration by ks
        • 1.4.3 depends-on 사용 by ys
        • 1.4.4 게으른-초기화된 bean by ys
        • 1.4.5 Autowiring Collaborators by ys
        • 1.4.6 메소드 주입 by sh
      • 1.5. 빈의 범위 by sh
      • 1.6 빈의 특성 커스터마이징하기 by ys
        • 1.6.1 라이프 사이클 콜백
        • 1.6.2 ApplicationContextAware과BeanNameAware
        • 1.6.3 기타 Aware인터페이스
      • 1.7 빈 정의 상속by ys
        • 1.7.1 빈 정의 상속
      • 1.8 컨테이너 확장 포인트 by ks
      • 1.9 어노테이션 기반의 컨테이너 구성 by sh
      • 1.10 클래스패스 스캔 및 관리 by ys
        • 1.10.1 @Component 및 추가 스테레오 타입 어노테이션
        • 1.10.2 meta-annotation 및 composed annotation 사용
        • 1.10.3 자동으로 클래스 검색 및 Bean 정의 등록
        • 1.10.4 스캐닝을 커스터마이징 하기위해 필터를 사용
        • 1.10.5 component 내에 Bean 메타 데이터 정의
        • 1.10.6 이름으로 자동탐지되는 컴포넌트
        • 1.10.7 범위로 자동 감지되는 컴포넌트
        • 1.10.8 annotation과 함께 한정된 메타데이터 제공
        • 1.10.9 후보 component의 index 생성
      • 1.11 JSR 330 표준 어노테이션 사용하기 by sh
      • 1.12 자바 기반의 컨테이너 구성 by sh, ks
        • 1.12.1 기본 개념: @Bean 및 @Configuration by sh
        • 1.12.2 AnnotationConfigApplicationContext를 사용한 스프링 컨테이너 인스턴스화 by sh
        • 1.12.3 @Bean 사용 by ks
        • 1.12.4 @Configuration 어노테이션 by ks
        • 1.12.5 자바 기반 Configuration구성 by ks
      • 1.13 환경 추상화 by ys
        • 1.13.1 빈 정의 프로파일
        • 1.13.2 PropertySource추출
        • 1.13.3 @PropertySource 사용
        • 1.13.4 Placeholder Resolution in Statements
      • 1.14 LoadTimeWeaver 등록 by ks
      • 1.15 ApplicationContext의 부가 수용가능성들 by ks, sh
        • 1.15.1 MesageSource를 사용한 국제화 by ks
        • 1.15.2 표준과 커스텀 이벤트 by ks
        • 1.15.3 로우 레벨 리소스에 대한 편리한 접근 by sh
        • 1.15.4 웹 어플리케이션에 대한 간편한 Application 인스턴스화 by sh
        • 1.15.5 스프링 ApplicationContext를 Java EE RAR 파일로 배포하가ㅣ by sh
        • 1.15.3 Low-level 리소스로 편리한 접근
        • 1.15.4 웹 어플리케이션을 위한 편리한 ApplicationContext 인스턴스화
      • 1.16 BeanFactory by sh
    • 2. Resource by ks
      • 2.1 소개
      • 2.2 Resource interface
      • 2.3 내장 리소스 확장
      • 2.4 ResourceReader
      • 2.5 ResourceLoaderAware 인터페이스
      • 2.6 Resources 의존성
      • 2.7 어플리케이션 컨텍스트와 리소스 경로
    • 3. 유효성 검사, 데이터 바인딩 및 유형 변환 by ys, sh
      • 3.1. Spring의 Validator 인터페이스를 사용하여 유효성 검사 by ys
      • 3.2. 오류 메시지로 코드 해결 by ys
      • 3.3. bean 조작과 BeanWrapper by ys
        • 3.3.1. 기본 및 중첩 된 프로퍼티를 설정 및 가져 오기
        • 3.3.2. 내장 된 PropertyEditor구현
      • 3.4 스프링 타입 변환 by sh
        • 3.4.1 Converter SPI
        • 3.4.2 ConverterFactory 사용하기
        • 3.4.3 GenericConverter 사용하기
        • 3.4.4 ConversionService API
        • 3.4.5 ConversionService 구성
        • 3.4.6 프로그래밍 방식으로 ConversionService 사용하기
      • 3.5 스프링 필드 포맷팅 by sh
        • 3.5.1 Formatter SPI
        • 3.5.2 Annotation 기반의 포맷팅
        • 3.5.3 FormatterRegistry SPI
        • 3.5.4 FormatterRegistrar SPI
        • 3.5.5 스프링 MVC에서 포맷팅 구성하기
      • 3.6 전역 Date and Time 포맷 구성 by sh
      • 3.7 스프링 유효성 검사 by sh
        • 3.7.1 by sh
        • 3.7.2 by sh
        • 3.7.3 by sh
    • 4 스프링 표현식 언어 (SpEL)
      • 4.1 평가 by sh
      • 4.2 빈 정의에 있는 표현식 by sh
      • 4.3 Language Reference
        • 4.3.1 리터럴 표현식 by ys
        • 4.3.2 프로퍼티,배열,목록,지도 및 인덱서 by ys
        • 4.3.3 인라인 목록 by ys
        • 4.3.4 인라인 Maps by ys
        • 4.3.5 배열 구성 by ys
        • 4.3.6 행동 양식 by ys
        • 4.3.7 연산자 by ys
        • 4.3.8 유형 by ys
        • 4.3.9 생성자 by ys
        • 4.3.10 변수 by ks
        • 4.3.11 함수 by ks
        • 4.3.12 빈 참조 by ks
        • 4.3.13 삼항 연산자 (If-Then-Else) by ks
        • 4.3.14 엘비스 연산자 by ks
        • 4.3.15 안전한 네비게이션 연산자 by ks
        • 4.3.16 컬렉션 셀렉션 by ks
        • 4.3.17 컬렉션 프로젝션 by ks
        • 4.3.18 표현 템플릿 by ks
    • 5 spring을 이용한 aspect 지향 프로그래밍
      • 5.1 AOP 개념 by ys
      • 5.2 Spring AOP 기능 및 목표 by ys
      • 5.3 AOP 프록시 by ys
      • 5.4 @AspectJ 지원 by ys,ks
        • 5.4.1 @AspectJ 지원 활성화 by ys
        • 5.4.2 Aspect 선언하기 by ys
        • 5.4.3 Pointcut 선언하기 by ys
        • 5.4.4 Advice 선언 by ks
        • 5.4.5 소개 by ks
        • 5.4.6 Aspect 초기화 모델 by ks
        • 5.4.7 AOP 예제 by ks
      • 5.5 스키마 기반 AOP 지원 by sh
        • 5.5.1 Aspect 선언 by sh
        • 5.5.2 Pointcut 선언 by sh
        • 5.5.3 Advice 선언 by sh
        • 5.5.4 인트로덕션 by sh
        • 5.5.5 Aspect 인스턴스화 모델 by sh
        • 5.5.6 Advisors by sh
        • 5.5.7 AOP 스키마 예제 by sh
    • 6 Spring AOP API
      • 6.1 Spring의 Pointcut API
        • 6.1.1 개념들 by ys
        • 6.1.2 Pointcuts에 대한 작업 by ys
        • 6.1.3 AspectJ Expression Pointcuts by ys
        • 6.1.4 편리한 Pointcut 구현 by ys
        • 6.1.5 포인트 컷 수퍼 클래스 by ys
        • 6.1.6. 사용자 정의 Pointcut by ys
      • 6.2 Spring의 Advice API
        • 6.2.1. 조언 라이프 사이클 by ys
        • 6.2.2 Spring의 advice 유형 by ys
      • 6.3 Spring의 Advisor API by ks
      • 6.4 ProxyFactoryBean을 사용해서 AOP 프록시 생성 by ks
        • 6.4.1 기본
        • 6.4.2 자바빈 프로퍼티
        • 6.4.3 JDK 및 CGLIB 기반 프록시
        • 6.4.4 프록시 인터페이스
        • 6.4 5 프록시 클래스
        • 6.4.6 "Global" advisor 사용
      • 6.5 간결한 프록시 정의 by sh
      • 6.6 ProxyFactory를 사용하여 프로그래밍 방식으로 AOP 프록시 만들기 by sh
      • 6.7 Advised 객체들 조작하기 by sh
      • 6.8 "자동 프록시" 기능 사용 by sh
      • 6.9 TargetSource구현체 사용하기 by sh
      • 6.10 새로운 Advice 타입 정의하기 by sh
    • 7. 데이터 버퍼와 코덱 by ks
Powered by GitBook
On this page

Was this helpful?

  1. spring 5.0
  2. 1. IoC 컨테이너
  3. 1.12 자바 기반의 컨테이너 구성 by sh, ks

1.12.5 자바 기반 Configuration구성 by ks

스프링의 자바 기반 configuration 기능은 configuration의 복잡성을 줄일 수 있는 어노테이션들을 구성하게 한다.

@Import 어노테이션의 사용

<Import/> 요소가 스프링 XML 파일에서 configuration 모듈화하는데 도움을 주고, @Import 어노테이션은 @Bean 정의를 다른 configuration 클래스로부터 부른다.

@Configuration
public class ConfigA {

    @Bean
    public A a() {
        return new A();
    }
}

@Configuration
@Import(ConfigA.class)
public class ConfigB {

    @Bean
    public B b() {
        return new B();
    }
}

이제, ConfigA.class와 ConfigB.class 둘다 지정하지 않아도 컨텍스트를 초기화할때 오직 ConfigB 명시적으로 공제공한다.

말을 어렵게 했는데, 결국은 ConfigB 클래스가 ConfigA를 import하기 때문에 ConfigB만 불러온 것이 명시적이란 이야기.

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(ConfigB.class);

    // now both beans A and B will be available...
    A a = ctx.getBean(A.class);
    B b = ctx.getBean(B.class);
}

이러한 접근은 @Configuration 이 동작하는 동안 잠재적으로 많은 클래스를 기억하도록 요구하는거 보다 하나의 클래스만 처리해야해서 컨테이너 인스턴스화를 단순화한다.

스프링 4.2에서 @Import는 또한 보통 컴포넌트 클래스 참조를하는 것이 AnnotationConfigApplicationContext.register 메소드와 유사하다. 이는 특히 컴포넌트 스캐닝을 피하려고 한다면 유용하다. 모든 컴포넌드들을 명시적으로 정의하기 위해 엔트리 포인트들 로서 적은 configuration 클래스들을 사용하는 것으로.

하나의 클래스만 명시적으로 적는 것으로 단순화 & 기능별로 config 클래스를 나눠서 스캐닝을 원하지 않는 패키지들을 분리할 수 있다.

임포트된 @Bean 정의에 의존성 주입

아래 예제는 간단하게 동작한다. 대부분 실용성있는 시나리오에서는 빈들은 또 하나의 cross configuration 클래스들의 의존성을 가진다. XML을 사용할때 컴파일러가 연루되지 않기 때문에 이건 이슈가 안되고, ref="someBean"을 선언할 수 있고, 컨테이너가 초기화되는 동안 스프링이 일하는 것을 믿을 수 있다. @Configuration클래스를사용하면, 자바 컴파일러가 configuration 모델에 제약을 주기 때문에 다른 빈들로 참조하는 것이 자바 신택스에 유효해야만 한다.

XML로 선언한 것과 자바 코드로 선언한 것들은 서로 참조할 수 있고, 자바 코드는 유효해야(빌드가 되어야하니까) 사용가능하다는 조건이 있지만 XML은 그렇지 않다는 이야기.

@Configuration
public class ServiceConfig {

    @Bean
    public TransferService transferService(AccountRepository accountRepository) {
        return new TransferServiceImpl(accountRepository);
    }
}

@Configuration
public class RepositoryConfig {

    @Bean
    public AccountRepository accountRepository(DataSource dataSource) {
        return new JdbcAccountRepository(dataSource);
    }
}

@Configuration
@Import({ServiceConfig.class, RepositoryConfig.class})
public class SystemTestConfig {

    @Bean
    public DataSource dataSource() {
        // return new DataSource
    }
}

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
    // everything wires up across configuration classes...
    TransferService transferService = ctx.getBean(TransferService.class);
    transferService.transfer(100.00, "A123", "C456");
}

이는 같은 결과인 또다른 방법이다. @Configuration 클래스들은 궁극적으로 컨테이너에서 오직 하나의 빈이다.: 이는 @Autowired와 @Value 주입의 이점이 될 수 있고 다른 기능들은 다른 빈들과 같다.

가장 간단한 방법으로 주입하는 의존성을 확인하자. @Configuration 클래스들은 컨텍스트의 초기화 동안 꽤 빨리 동작하고, 이 방법은 기대하지 않게 빨리 초기화하는 걸로 이끌지도 모른다. 가능하다 파라미터 기반 주입을 하자.

또한, 특히 @Bean 을 통해 BeanPostProcessor와 BeanFactoryPostProcessor 정의하는 것에 주의해야한다. 이것들은 static @Bean메소드에 보통 선언되어야 하고 configuration클래스를 컨테이닝하는 초기화를 트리거링 하면 안된다. 그렇지 않으면, @Autowired와 @Value는 configuration 클래스에서 스스로 동작하지 않는다. 빈인스턴스가 너무 빨리 동작하기 때문에.

아래 예제는 하나의 빈이 다른 빈에 Autowired될 수 있는 방법이다.

@Configuration
public class ServiceConfig {

    @Autowired
    private AccountRepository accountRepository;

    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl(accountRepository);
    }
}

@Configuration
public class RepositoryConfig {

    private final DataSource dataSource;

    @Autowired
    public RepositoryConfig(DataSource dataSource) {
        this.dataSource = dataSource;
    }

    @Bean
    public AccountRepository accountRepository() {
        return new JdbcAccountRepository(dataSource);
    }
}

@Configuration
@Import({ServiceConfig.class, RepositoryConfig.class})
public class SystemTestConfig {

    @Bean
    public DataSource dataSource() {
        // return new DataSource
    }
}

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
    // everything wires up across configuration classes...
    TransferService transferService = ctx.getBean(TransferService.class);
    transferService.transfer(100.00, "A123", "C456");
}

RepositoryConfig에서 accountRepository bean이 ServiceConfig에서 AccountRepository에 autowired됐어. config도 다 하나의 빈이라고 했으니 다른 곳에서 선언된 빈이 또다른 곳에서 autowired되어있는 모습이야.

@Configuration 클래스에서 생성자 주입은 오직 스프링 4.3에서 지원하는 내용이다. 만약 타겟 빈이 오직 한 생성자를 정의한다면 @Autowired가 필요없다. @AUtowired는 RepositoryConfig 생성자에서는 필요가 없다.

위의 예제를 보면 빈의 생성 시기에 따라 문제가 생길수도 있는 부분이라서, 생성자 주입 말고 setter 주입을 권장한다는 이야기.

쉽게 안내하기 위해 임포트된 빈에 자격을 주는 것

이 모호성이 받아들여지지않고 직접 IDE안에서 @Configuration 클래스에서 다른 것으로 직접 안내하고싶은 경우에 configuration 클래스를 연결하는것을 고려해보자.

@Configuration
public class ServiceConfig {

    @Autowired
    private RepositoryConfig repositoryConfig;

    @Bean
    public TransferService transferService() {
        // navigate 'through' the config class to the @Bean method!
        return new TransferServiceImpl(repositoryConfig.accountRepository());
    }
}

이런 상황에서 AccountRepository는 완전하게 명시적으로 정의된다. 하지만 ServiceConfig는 이제 타이트하게 RepositoryConfig랑 커플링된다. 그것은 거래다. 이 타이트한 커플링은 다소 인터페이스나 추상클레스 기반 @Configuration 클래스보다 나을 수 있다. (!직접 어디의 클래스인지 명시적으로 작성)

@Configuration
public class ServiceConfig {

    @Autowired
    private RepositoryConfig repositoryConfig;

    @Bean
    public TransferService transferService() {
        return new TransferServiceImpl(repositoryConfig.accountRepository());
    }
}

@Configuration
public interface RepositoryConfig {

    @Bean
    AccountRepository accountRepository();
}

@Configuration
public class DefaultRepositoryConfig implements RepositoryConfig {

    @Bean
    public AccountRepository accountRepository() {
        return new JdbcAccountRepository(...);
    }
}

@Configuration
@Import({ServiceConfig.class, DefaultRepositoryConfig.class})  // import the concrete config!
public class SystemTestConfig {

    @Bean
    public DataSource dataSource() {
        // return DataSource
    }

}

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(SystemTestConfig.class);
    TransferService transferService = ctx.getBean(TransferService.class);
    transferService.transfer(100.00, "A123", "C456");
}

interface에도 @Configuration을 사용할 수 있고, 이를 확장해서 구현함으로서 아까 위의 예제보다 결합도를 낮춘 방식으로 작성한 예제야.

이제 ServiceConfig는 루즈하게 DefaultRepositoryCOnfig를 쌓는 것과 커플링되고 IDE 내장 툴은 여전히 유용하다. : 쉽게 RepositoryConfig 확창체의 상하관계 타입을 얻을 수 있다. 이 방법으로 @Configuration클래스를 안내하는것과 의존성은 인터페이스 기반 코드를 안내하는 과정보다 다르지 않기 시작한다.

만약 특정 빈의 생성 순서에 영향을 끼치고 싶다면, @Lazy 를 쓰는것을 고려해보거나 (시작 대신에 처음 접근으로 생성) 특정한 다른 빈들에 @DependsOn을 쓰는 것을 고려해보자.(구체적인 다른 빈들이 현재 빈보다 전에 생성되고 늦게 생성된 것들을 직접적으로 의존하도록 하는)

조건부 @Configutaion 클래스들과 @Bean 메소드를 포함

@Profile : 상황에 맞게 설정이 바뀌어야하는 것을 지원. 이전에는 property 파일에 저장해두고 활용했는데 이 방법을 통해서도 같은 기능을 구현할 수 있다. (!Maven에서 상황에 맞게 빌드할 수 있는 거에서 난 활용했었어!)

@Conditional : auto-configuration. @Profile 클래스를 확인해보면 @Conditional 어노테이션이 붙어있다.

@Conditional(ProfileCondition.class)

public @interface Profile{...}

@Profile 어노테이션은 사실 @Conditional이라고 리는 것 보다 훨씬 더 유용한 것으로 확장된 것이다. @Conditional 어노테이션은 @Bean이 등록되기 전에 상담해야만 하는 구체적인 org.springframework.context.annotation.Condition 확장체들을 가리킨다.

Condition 인터페이스의 확장체는 true 나 false를 반환하는 matches(...) 메소드를 제공한다. 예를 들어서, @Profile을 사용해서 실질적인 Condition 확장체를 보여준다.

@Override
public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) {
    if (context.getEnvironment() != null) {
        // Read the @Profile annotation attributes
        MultiValueMap<String, Object> attrs = metadata.getAllAnnotationAttributes(Profile.class.getName());
        if (attrs != null) {
            for (Object value : attrs.get("value")) {
                if (context.getEnvironment().acceptsProfiles(((String[]) value))) {
                    return true;
                }
            }
            return false;
        }
    }
    return true;
}

자바와 XML configuration 의 결합

스프링의 @Configuration 클래스 지원은 스프링 XML을 완전하게 대체하는 것을 목표로 하진 않는다. 스프링 XML 네임 스페이스 같은 일부 기능은 컨테이너를 구상하는 이상적인 방법이다. XML이 편리하거나 필요한 경우에는, 선택이 있다 : "XML-centric" 에서 컨테이너를 인스턴스화하거나(예를 들어서 ClassPathXmlApplicationContext) "Java-centric"에서 초기화 하는 방법이 있다.(AnnotationConfigApplicationContext와 @ImportResource어노테이션으로 필요한 XMl을 임포트하는)

XML 중심의 @Configuration 사용 (XML-centric)

XMl로 스프링 컨테이너 부트 스트랩을 선호할 수 있고, @Configuration 클래스를 ad-hoc방식으로 포함하고 싶을 수 있다. 예를 들어서 스프링 XML을 사용한 크게 존재하는 코드베이스에서 @Configuration 클래스는 as-needed 기반에서 생성하기 휩고 존재하는 XML 파일들로부터 그것들을 포함시킨다. 이 섹션 마지막에 @Configuration 클래스를 사용해서 "XML-centric"의 종류에서 옵션을 다뤄본다.

ad-hoc : 어떤 이론이나 학설, 논리에 대한 부정적인 근거나 반박이 나왔을떄 오직 그것에 대해서 반박하기 위해서만 필요한 가

기본 스프링 <bean/>요소로서 @Configuration 클래스를 선언

@Configuration 클래스들은 궁극적으로 컨테이너에 빈을 정의하기 위한 것임을 기억하자. 이 시리즈 예를 들면, 우리는 AppConfig라는 이름의 @Configuration 클래스를 생성하고 system-test-config.xml 에서 <bean/>정의로서 포함한다. <context:annotation-config/> 는 이 기능을 켜기 때문에 컨테이너는 @Configuration 어노테이션을 인식하고 AppConfig를 적절하게 전언한 @Bean 메소드를 작업한다.

아래는 configuration 클래스 예제다.

@Configuration
public class AppConfig {

    @Autowired
    private DataSource dataSource;

    @Bean
    public AccountRepository accountRepository() {
        return new JdbcAccountRepository(dataSource);
    }

    @Bean
    public TransferService transferService() {
        return new TransferService(accountRepository());
    }
}

아래는 샘플 system-test-config.xml파일의 일부분이다.

<beans>
    <!-- enable processing of annotations such as @Autowired and @Configuration -->
    <context:annotation-config/>
    <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>

    <bean class="com.acme.AppConfig"/>

    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

아래는 jdbc.properties 파일이다.

jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
jdbc.username=sa
jdbc.password=

public static void main(String[] args) {
    ApplicationContext ctx = new ClassPathXmlApplicationContext("classpath:/com/acme/system-test-config.xml");
    TransferService transferService = ctx.getBean(TransferService.class);
    // ...
}

system-test-config.xml 파일에서 AppConfig<bean/>은 id 를 선언하지 않는다. 이렇게 하는게 허용될 수 있지만 다른 빈이 컨테이너를 참조하지 않는다면, 컨테이너는 불필요하다. 컨테이너에서 이름을 명시적으로 가져올 가능성은 없다. 유사하게 DataSource 빈은 오직 타입에 의해 자동연결되어서, 명시적인 빈 id는 강하게 요구되지 않는다.

@Configuration 클래스를 뽑기위해 <context:component-scan/>을 사용하는 것

@Configuration 은 @Component와 메타-어노테이트되어있기 때문에 @Configuration 으로 어노테이트된 클래스들은 자동적으로 컴포넌트 스캔의 후보가 된다. 같은 시나리오를 이전 예제에서 묘하한것 처럼 사용하는 것은, 컴포넌트 스캔의 이점을 취하기 위해 system-test-config.xml 을 재정의 할 수 있다. 이 경우에 명시적으로 <context:annotation-config/>를 선언할 필요가 없다. <context:component-scan/>이 같은 기능을 하기 때문에.

아래는 수정된 system-test-config.xml이다.

<beans>
    <!-- picks up and registers AppConfig as a bean definition -->
    <context:component-scan base-package="com.acme"/>
    <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>

    <bean class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.username}"/>
        <property name="password" value="${jdbc.password}"/>
    </bean>
</beans>

@ImportResource 를 사용하 XML 의 Class중심적 @Configuration 사용

@Configuration 클래스들은 컨테이너에서 configuring하기 위한 우선적 메카니즘이고, 최소한으로 XML을 사용할 가능성이 높다. 이 시나리오에선, @ImportResource를 사용할 수 고 필요한 만큼 XMl에서 정의할 수 있다. 그렇게 하는것은 컨테이너를 configuring하기 위해, 그리고 최소한으로 XML을 유지하기 위해 "Java-centric" 접근을 성취한다.아래 예지는(configuration 클래스, 빈을 정의한 XML파일 포함, 프로퍼티스 파일, 그리고 main 클래스)는 어떻게 @ImportResource어노테이션을 "Java-centric"을 사용하는지 보여준다.

@Configuration
@ImportResource("classpath:/com/acme/properties-config.xml")
public class AppConfig {

    @Value("${jdbc.url}")
    private String url;

    @Value("${jdbc.username}")
    private String username;

    @Value("${jdbc.password}")
    private String password;

    @Bean
    public DataSource dataSource() {
        return new DriverManagerDataSource(url, username, password);
    }
}

properties-config.xml
<beans>
    <context:property-placeholder location="classpath:/com/acme/jdbc.properties"/>
</beans>

jdbc.properties
jdbc.url=jdbc:hsqldb:hsql://localhost/xdb
jdbc.username=sa
jdbc.password=

public static void main(String[] args) {
    ApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    TransferService transferService = ctx.getBean(TransferService.class);
    // ...
}
Previous1.12.4 @Configuration 어노테이션 by ksNext1.13 환경 추상화 by ys

Last updated 6 years ago

Was this helpful?

운이 좋게도, 이 문제를 푸는것은 간단하다. 우리가 이미 얘기 했듯이 ( ), @Bean 메소드는 빈 의존성을 서술하는 여러 임의의 파라미터를 가질 수 있다. 아래는 더 현실적인 시나리오이다.

시나리오를 예측하면, @Autowired 를 사용하는 것은 잘 동작하고 모듈화를 제공하지만 정의가 선언된 자동연결된 빈을 정확하게 결정하는 것은 여전히 모호하다. 예를 들어서, 개발자가 ServiceConfig를 찾을때 어떻게 정확하게 어디에 @Autowired AccountRepository 빈이 선언되어있는지 알 수 있을까? 이건 코드 내부에서 명시적이지 않고, 그냥 괜찮을지도 모른다. 는 어떻게 모든것들이 연결되는지 보여주는 그래프를 랜더링하는 툴을 제공하는 것을 기억해라. 또한 자바 IDE는 쉽게 모든 선언들을 찾을수 있고, AccountRepository 타입의 사용도 알 수 있다. 그리고 빠르게 그 타입을 반환하는 @Bean 메소드의 위치를 보여준다.

임의의 시스템 상태를 기반으로 전체 @Configuration 클래스나 개별 @Bean 메소드를 조건부로 활성화 하거나 비활성화하는 것이 유용한 경우가 많다. 예를 들어서 @Profile 어노테이션을 구체적인 프로필이 스프링 Environment에 사용 가능하도록할 때 빈들을 활성화하기 위해 쓴다.( 참조)

사용 예제 :

참조

we already discussed
Spring Tool Suite
Bean Definition Profiles
https://jdm.kr/blog/81
@Conditional