• Home
  • About
    • back
    • Junseok photo

      Junseok

      개발자 블로그

    • Learn More
    • Facebook
    • Instagram
    • Github
  • Posts
    • back
    • All Posts
    • All Tags
  • Java
    • back
    • java-basic
    • java-solid
    • java-pattern
    • java-logging
  • Javascript
  • Angular
  • spring
    • back
    • spring-framework
    • spring-boot
    • spring-test
  • server
    • back
    • jeus
    • webtob
    • tomcat
  • test
    • back
    • junit
    • assertj
    • hamcrest
    • dbunit
    • spring
  • docker
  • unix
  • maven
  • db
  • network
  • eclipse
  • intellij
  • microservices
  • etc

Bean Scanning

08 Jan 2018

Reading time ~3 minutes

Bean Scanning

일반적으로 XML bean 설정 파일에 모든 bean이나 컴포넌트를 선언하여
Spring 컨테이너가 bean이나 컴포넌트를 감지하고 등록 할 수 있도록한다.
사실, Spring은 사전 정의 된 프로젝트 패키지에서 빈을 자동 스캔, 감지 및 인스턴스화 할 수 있으며,
XML 파일에서 지루한 빈 선언을 수행 할 필요가 없다.

##### Spring에서 수동으로 구성 요소 선언과 자동 구성 요소 검색 사이의 다른 점

### 구성 요소를 수동으로 선언

Spring에서 bean을 선언하는 일반적인 방법

  • Normal bean.
    public class CustomerDAO
    {
     @Override
     public String toString() {
      return "Hello , This is CustomerDAO";
     }
    }
    
  • DAO layer.
    import com.mkyong.customer.dao.CustomerDAO;
    public class CustomerService
    {
     CustomerDAO customerDAO;
     public void setCustomerDAO(CustomerDAO customerDAO) {
      this.customerDAO = customerDAO;
     }
     @Override
     public String toString() {
      return "CustomerService [customerDAO=" + customerDAO + "]";
     }
    }
    
  • 빈 환경 설정 파일 (Spring-Customer.xml)은 Spring의 일반적인 환경 설정이다. ~~~xml
 * Run it
~~~java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mkyong.customer.services.CustomerService;
public class App
{
    public static void main( String[] args )
    {
     ApplicationContext context =
       new ClassPathXmlApplicationContext(new String[] {"Spring-Customer.xml"});
     CustomerService cust = (CustomerService)context.getBean("customerService");
     System.out.println(cust);
    }
}
  • output
    CustomerService [customerDAO=Hello , This is CustomerDAO]
    

    ### Auto Components Scanning

  • @Component annotation을 달아 클래스가 자동 스캔 구성 요소임을 나타낸다.
    import org.springframework.stereotype.Component;
    @Component
    public class CustomerDAO
    {
     @Override
     public String toString() {
      return "Hello , This is CustomerDAO";
     }
    }
    
  • DAO 계층에 @Component를 추가하여 자동 스캔 구성 요소임을 나타낸다.
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import com.mkyong.customer.dao.CustomerDAO;
    @Component
    public class CustomerService
    {
     @Autowired
     CustomerDAO customerDAO;
     @Override
     public String toString() {
      return "CustomerService [customerDAO=" + customerDAO + "]";
     }
    }
    

    “context : component”를 빈 환경 설정 파일에 넣으면 Spring에서 자동 스캐닝 기능이 활성화된다.
    base-package는 구성 요소가 어디에 저장되어 있는지 알려주고, Spring은이 폴더를 검색하여
    (@Component로 annotation 처리 된) 빈을 찾고 Spring 컨테이너에 등록한다.
    ~~~xml

 * Run it
~~~java
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.mkyong.customer.services.CustomerService;
public class App
{
    public static void main( String[] args )
    {
     ApplicationContext context =
        new ClassPathXmlApplicationContext(new String[] {"Spring-AutoScan.xml"});
     CustomerService cust = (CustomerService)context.getBean("customerService");
     System.out.println(cust);
    }
}
  • output
    CustomerService [customerDAO=Hello , This is CustomerDAO]
    

    이것은 Auto Components Scanning이 Spring에서 작동하는 방법이다.  


### Custom auto scan component name (사용자 정의 component명 auto scan)

기본적으로 Spring은 컴포넌트의 첫 문자를 ‘CustomerService’에서 ‘customerService’로 줄인다.
그리고 ‘customerService’라는 이름으로이 구성 요소를 검색 할 수 있다.

구성 요소의 사용자 정의 이름을 작성하려면 다음과 같이 사용자 정의 이름을 입력.

@Service("AAA")
public class CustomerService
...

이제 ‘AAA’라는 이름으로 검색 할 수 있다.

CustomerService cust = (CustomerService)context.getBean("AAA");
  • Auto Components Scan Annotation Types

Spring 2.5에는 4 가지 유형의 Auto Components Scan Annotation이 있다.

  • @Component - 자동 스캔 구성 요소를 나타낸다.
  • @Repository - 지속성 계층의 DAO 구성 요소를 나타낸다.
  • @Service - 비즈니스 계층의 서비스 구성 요소를 나타낸다.
  • @Controller - 프리젠 테이션 레이어의 컨트롤러 구성 요소를 나타낸다.

그래서, 어느 것이 사용할 것인가? 그건 중요하지 않다. @Repository, @Service 또는 @Controller의 소스 코드를 보자.

  • @Repository
    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Component
    public @interface Repository {
     String value() default "";
    }
    
  • @Service ~~~java @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Service { /**
  • The value may indicate a suggestion for a logical component name,
  • to be turned into a Spring bean in case of an autodetected component.
  • @return the suggested component name, if any */ String value() default “”; } ~~~

  • @Controller ~~~java @Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Component public @interface Controller { /**
  • The value may indicate a suggestion for a logical component name,
  • to be turned into a Spring bean in case of an autodetected component.
  • @return the suggested component name, if any */ String value() default “”; } ~~~

@ Repository, @ Service 또는 @Controller가 모두 @Component로 annotation 처리되었음을 알게 될 것이다. 자동 스캔을 위해 모든 구성 요소에 @Component 만 사용할 수 있나? 예, 가능합니다. 그리고 Spring은 @Component가 annotation 된 모든 구성 요소를 자동으로 스캔한다. 잘 작동하지만 좋은 방법은 아니다. 가독성을 위해 다음과 같이 코드를 더 읽기 쉽게 만들기 위해 지정된 레이어에 대해 @ Repository, @ Service 또는 @Controller를 항상 선언해야 한다.

  • DAO layer
    import org.springframework.stereotype.Repository;
    @Repository
    public class CustomerDAO
    {
     @Override
     public String toString() {
      return "Hello , This is CustomerDAO";
     }
    }
    
  • Service layer
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    import com.mkyong.customer.dao.CustomerDAO;
    @Service
    public class CustomerService
    {
     @Autowired
     CustomerDAO customerDAO;
     @Override
     public String toString() {
      return "CustomerService [customerDAO=" + customerDAO + "]";
     }
    }
    


springframeworkbean Share Tweet +1