Spring, XML 과 Annotation 의 설정 및 대체

infoqoch·2021년 5월 23일
0

스프링

목록 보기
3/5

들어가며

  • Spring과 함께 XML 기반의 DI, AOP를 정의하는 방식은 그 당시 혁신이라 한다. 그러나 XML을 통한 외부 설정이 아닌 내부 클래스를 통한 설정을 요구받게 되었고, 이에 따라 Annotation 기반 설정 방식으로 점차 대체 중에 있다.
  • 현재 글은 빈 생성 과정에서 XML과 Annotation을 통한 설정 방법에 대해 비교위주로 간단하게 설명하고자 한다.

< Bean> 과 @Component

  • XML에서는 객체를 생성할 때 < Bean>을 사용한다. 클래스에서는 Annotation을 사용한다.
  • @Component는 @Controller, @Service, @Repository 등 MVC 패턴에 따른 다양한 형태로 확장된다.
  • XML에서 Bean을 생성하고 이에 필요한 객체를 DI 할 때, 생성자 혹은 세터를 통해 객체를 주입할 수 있다. 클래스에서 @Autowired와 같다.

@Autowired와 @Qualifier

  • @Autowired는 그것을 부품으로 사용하는 객체의 세터, 생성자, 필드값 셋 중 아무곳에서나 선언 가능하며, 보통은 필드 위에 한다.
  • Autowired는 required=false로 옵션을 줄 수 있다. 이 경우 필요로한 객체가 존재하지 않아도 해당 객체를 찾을 수 없다는 예외가 발생하지 않는다.
  • @Qualifier는 같은 클래스로 만든 두 개 이상의 객체가 있을 때, 원하는 객체를 선택하기 위위한 Autowired를 위한 옵션이다.

어너테이션으로 설정한 객체를 스프링은 어떻게 찾을까?

  • xml에 명시적으로 선언한 객체는 스프링이 어떤 문제 없이 잘 찾는다. 하지만 클래스에 선언된 것은 어떻게 찾을까?

context:annotation-config

  • xml에 < context:annotation-config >을 선언한다.
  • xml에 선언된 어떤 bean이 있고, 그 bean의 객체를 완성하기 위한 부품으로의 객체가, 해당 bean의 클래스에서 내부에 어너테이션으로 정의되었으므로, 해당 bean 클래스에 들어가서 찾으라는 의미이다. 이를 통해 DI를 완성한다.
  • 그러므로 이 경우 객체 생성과 DI의 과정이 XML과 Annotation 두 개가 혼용됨을 알 수 있따.

context: component-scan

  • xml에 < context:component-scan base-package="com.spring.test" > 의 형태로 선언한다.
  • xml에서는 더 이상 빈을 정의하지 않는다. 스프링이 xml에서 선언한 패키지를 탐색하여, Component와 Autowired로 선언된 객체를 DI한다.

XML을 완전하게 제거하기

  • XML을 제거하기 위해서는 XML을 대체하는 클래스를 생성해야 한다. @Configuration이 그러하다.

@Configuration 클래스 생성하기

  • XML을 대체하는 클래스는 아래와 같이 생성한다.
@Configuration
    ↑ XML 파일 대체
@ComponentScan({"com.spring.test", "com.spring.test2"})
    ↑ <context:component-scan base-package="com.spring.test"> 대체 
public class AppConfig{
    
    @Bean
    public TestDAO testDAO(){
        return new TestFirstDAO();
    }
        ↑ <bean id="testDAO" class="test.spring.test.TestFirstDAO"> 를 대체. 매서드의 이름은 id의 값(변수명)과 같다. 컨테이너는 위의 빈을 가지게 된다.  
} 

ApplicationContext를 생성

  • XML의 경우 ApplicationContext를 생성할 때 해당 설정파일을 ClassPathXmlApplicationContext을 사용했다. 그러나 어너테이션을 기반으로 생성할 경우 AnnotationConfigApplicationContext을 사용한다.
public class Test{
    public static void main(String[] args){
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        TestDAO testDAO = (TestDAO) context.getBean(TestDAO.class);
    }
}

나아가며

  • SpringBoot을 사용하면서 생각없이 사용했던 @Controller, @Bean, @Configuration 에 대해서 이해할 수 있는 좋은 기회가 되었다.
  • 스프링부트를 개발 할 때 @Bean을 사용한 경험이 있다. 나는 이러한 기반지식이 없었기 때문에 왜 @RequiredArgsConstructor 혹은 @Autowired를 사용하지 않지? 라는 의문이 있었다. 이렇게 공부하니까 알게 됐다. 그 클래스가 @Configuration 이었기 때문이다.... 아. 설정 파일을 DI 하려고 했다니.. 아주 참신한 시도였다.
  • 스프링부트에는 위와 같은 @Configuration 설정 파일이 없고, 기본 Application 클래스에도 그러한 것이 없다. 그런데 어떻게 Component 객체들을 생성하고 DI를 할까? 스프링부트는 그냥 모든 클래스를 검색하는 것일까? 이 부분은 해소가 되지 않았다.
profile
JAVA web developer

0개의 댓글