Spring | Annotation을 이용한 bean 생성하기

brightbell·2023년 9월 26일

Spring

목록 보기
4/12

@Configuration

클래스 레벨 애노테이션
@Configuration 이 명시된 클래스는 Bean 으로 등록 됨
@Bean 을 등록하기 위해서는 반드시 @Configuration 을 등록

@Bean

메소드 레벨 애노테이션
@Bean 이 명시된 메소드가 반환하는 값이 Bean 으로 등록 됨
개발자가 직접 Bean 을 만들어서 반환하는 방식
스프링은 메소드 이름을 Bean 의 이름으로 등록함
@Bean 을 사용하는 메소드가 포함된 클래스는 반드시 @Configuration 을 사용해야 함

@Component

클래스 레벨 애노테이션
@Component 가 명시된 클래스는 자동으로 Bean 으로 등록 됨
@Component 가 명시된 클래스를 찾기 위해서는 반드시 미리 컴포넌트를 찾을 위치를 등록해야 하는데 이를 Component Scan 이라고 함
Spring Legacy Project 는 servlet context.xml 에 Component Scan 이 등록되어 있어 별도의 설정이 필요 없고 Spring Boot Project 는 @SpringBootApplication 에 Component Scan 이 포함되어 있어 별도의 설정이 필요 없음
스프링에서 가장 권장 하는 Bean 생성 방식임

  • AnnotationConfigApplicationContext 활용 예제
@Configuration  // IocContainer에 bean을 등록하는 클래스이다.
public class AppConfig {

  // 메소드를 bean으로 등록하기 위해서 @Bean을 추가한다.
  
  @Bean
  public Calculator calc() {
    return new Calculator();
  }
}

사칙연산 기능을 가진 Calculator 클래스

public class Calculator {

  // no field
  
  // default constructor  :  new Calculator()
  
  // method
  public void add(int a, int b) {
    System.out.println(a + "+" + b + "=" + (a + b));
  }
  public void sub(int a, int b) {
    System.out.println(a + "-" + b + "=" + (a - b));
  }
  public void mul(int a, int b) {
    System.out.println(a + "*" + b + "=" + (a * b));
  }
  public void div(int a, int b) {
    System.out.println(a + "/" + b + "=" + (a / b));
  }
}

결과확인

public class MainWrapper {

  public static void main(String[] args) {

    // AppConfig.java에 등록된 bean 생성하기
    AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    
    // bean 가져오기
    Calculator calc = ctx.getBean("calc", Calculator.class);
    
    // 확인
    calc.add(1, 2);
    calc.sub(3, 4);
    calc.mul(5, 6);
    calc.div(7, 8);
    
    // ctx 닫기
    ctx.close();
  }
}

다른 클래스를 필드로 가진 클래스

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Person {
  private String name;
  private int age;
  private Calculator calculator;
}

@Bean Annotation 붙여서 객체 만들기

@Configuration  // IocContainer에 bean을 등록하는 클래스이다.
public class AppConfig {

  // 메소드를 bean으로 등록하기 위해서 @Bean을 추가한다.
  
  @Bean
  public Calculator calc() {  // 메소드이름 == bean이름
    return new Calculator();
  }
  
  // setter 이용
  @Bean
  public Person man() {
    Person person = new Person();
    person.setName("뽀로로");
    person.setAge(20);
    person.setCalculator(calc());
    return person;
  }
  
  // 생성자 이용
  @Bean
  public Person woman() {
    return new Person("루피", 20, calc());
  }
}

결과확인

  public static void ex() {
    
    // com.gdu.app01.anno01 패키지에 정의된 bean 생성
    AbstractApplicationContext ctx = new AnnotationConfigApplicationContext("com.gdu.app01.anno01");
    
    // bean 가져오기
    Person man = ctx.getBean("man", Person.class);
    Person woman = ctx.getBean("woman", Person.class);
    
    // 확인
    System.out.println(man.getName() + ", " + man.getAge());
    man.getCalculator().add(2, 3);
    System.out.println(woman.getName() + ", " + woman.getAge());
    woman.getCalculator().add(1, 2);
    
    // ctx 닫기
    ctx.close();
  }
  

Collection을 필드로 가진 Student 클래스

@NoArgsConstructor
@AllArgsConstructor
@Data
public class Student {
  private List<String> subjects;
  private Set<String> contacts;
  private Map<String, String> friends;
}

@Bean Annotation 붙여서 객체 만들기

@Configuration
public class AppConfig {

  @Bean
  public Student student() {
    Student student = new Student();
    student.setSubjects(Arrays.asList("국어","영어","수학"));
    student.setContacts(new HashSet<String>(Arrays.asList("010-0000-0000", "010-9999-9999")));
    student.setFriends(Map.of("동네친구", "루피", "학교친구", "뚜비", "사회친구", "포비"));
    return student;
  }
}

결과확인

public class MainWrapper {

  public static void main(String[] args) {
    
    // AppConfig.java에 등록된 bean 생성
    AbstractApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    
    // bean 가져오기
    Student student = ctx.getBean("student", Student.class);
    
    // 확인
    for(String subject : student.getSubjects()) {
      System.out.println(subject);
    }
    for(String contact : student.getContacts()) {
      System.out.println(contact);
    }
    for(Map.Entry<String, String> entry : student.getFriends().entrySet()) {
      System.out.println(entry.getKey() + ", " + entry.getValue());
    }
    
    // ctx 닫기
    ctx.close();
  }

}

0개의 댓글