티스토리 뷰

728x90

1. 스프링에서 XML설정과 함께 annotation을 사용하면 xml 설정을 줄일 수 있다.

  1-1. 스프링에서 annotation을 사용하려면 xml에 component scanning 설정이 필요하다.

  1-2. 아래처럼 최상위 package 경로를 설정하여 어디를 scan해야 하는지 지정해야 한다.

<context:component-scan base-package="pe.pilseong.springbasic"></context:component-scan>

 

2. @Component를 스프링이 관리할 클래스에 추가하면 xml의 <bean></bean>설정을 할 필요가 없다.

  2-1 @Component("") 방식도 사용가능한데 "" 내에 컨테이너가 관리할 이름을 넣어주면 된다.

  2-2 지정 이름을 사용하면 실제 사용시에도 정확한 이름으로 getBean을 호출해야 한다.

  2-3 @Component를 지정할 때 Scope도 같이 지정할 수 있다.

    2-3-1 @Component과 별개로 지정해 주어야 하고 당연히 default는 singleton이다. 아래 코드를 참조하면 된다.

 

@Component
@Scope("prototype")
public class HappyFortuneService implements FortuneService {

 

3. @Autowired를 사용하면 xml의 <bean></bean>에서 필요한 dependency injection 설정을 할 필요가 없다.

 

4. @Autowired은 어떤 메소드에도 사용할 수 있다. 굳이 생성자나 setter로 한정되지 않고 어떤 메소드도 가능하다.

 

5. @Autowired를 사용할 경우 주입할 타입의 객체가 컨테이너에 여러 개가 있을 경우

  5-1 @Autowired와 함께 @Qualifier("instanceName")  방식으로 객체 이름을 지정해야 한다.

    5-1-1 중복이 있을 경우는 NoUniqueBeanDefinitionException이 발생한다.

  5-2 @Qualifier를 생성자에서 사용할 경우는 파라메터에 붙여주어야 한다. 예제 참고

  5-3 생성자가 아닌 경우는 속성이나 setter에 붙여주면 된다.

 

@Autowired
public TennisCoach(@Qualifier("randomFortuneService") FortuneService theFortuneService) {
    fortuneService = theFortuneService;
}

 

6. @Component를 사용할 때 인스턴스 이름이 지정되지 않은 경우

  6-1 default 이름은 해당 클래스의 이름의 첫글자를 소문자로 바꾼 값을 이름으로 설정한다.

  6-2 첫 두개의 글자가 모두 대문자일 경우는 클래스 이름 그대로 사용한다.

    6-2-1 첫 두 글짜가 대문자일 경우에는 @Component 설정시 이름을 붙여 주는 것이 안전하다.

 

7. properties 파일에서 값을 읽어 사용하고 싶은 경우, placeholder를 이용한다.

  7-0 전 포스와는 다르게 클래스 내에서 사용하는 방법을 보여준다. 

  7-1 xml 설정에서 읽어올 속성파일의 경로를 지정한다.

  7-2 bean 테그를 더 이상 사용하지 않으므로 실제 사용할 클래스에 속성에 @Value("${ }")를 붙여 값을 가지고 온다.

  7-2 xml설정에서 component scan설정에서 scan이 된 클래스에만 적용된다.

  <context:component-scan base-package="pe.pilseong.springbasic"></context:component-scan>
  <context:property-placeholder location="classpath:pilseong.properties"/>
  @Value("${pilseong.email}")
  private String email;
  
  @Value("${pilseong.address}")
  private String address;

 

8. annotation설정에서 컨테이너가 객체를 생성 시 init method, destroy method를 지정할 수 있다.

  8-0 각각 @PostConstruct와 @PreDestroy이다.

  8-1 이 두개의 annotation가 포함된 javax.annotation 패키지가 자바9 이후에서 기본 classpath에서 제외되었다.

  8-2 javax.annotation-api-version.jar파일을 받아서 classpath에 걸어줘야 한다.

  8-3 maven repo에서 javax annotation을 dependency에 추가한다.

  8-4 scope이 prototype인 경우 당연히 PreDestroy로 지정된 메소드는 호출되지 않는다.

    8-4-1 이것도 복잡하기 때문에 실제 사용될 때까지 정리하지는 않을 예정이다.

 

<!-- https://mvnrepository.com/artifact/javax.annotation/javax.annotation-api -->
<dependency>
	<groupId>javax.annotation</groupId>
	<artifactId>javax.annotation-api</artifactId>
	<version>1.3.2</version>
</dependency>
package pe.pilseong.springbasic;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.springframework.stereotype.Component;

@Component
public class HappyFortuneService implements FortuneService {
  
  @Override
  public String getFortune() {
    return "You will be happy all the time";
  }
  
  public HappyFortuneService() {
    System.out.println("HappyFortuneService constructor is called");
  }
  
  @PostConstruct
  public void initService() {
    System.out.println("HappyFortuneService PostConstruct is called ");
  }
  
  @PreDestroy
  public void destroyService() {
    System.out.println("HappyFortuneService PreDestroy is called");
  }
}

 

728x90
댓글