j. Annotation Based Configuration - kimxavi/spring_tutorial GitHub Wiki

Spring 2.5 ๋ถ€ํ„ฐ dependency injection ์„ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ด์šฉํ•ด์„œ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋๋‹ค. bean wiring์„ XML๋กœ ํ•˜๋Š” ๋Œ€์‹ ์— ์ปดํผ๋„ŒํŠธ ํด๋ž˜์Šค์— annotations์„ ์จ์„œ ๊ด€๋ จ ํด๋ž˜์Šค, ๋ฉ”์˜๋“œ, ํ•„๋“œ ์„ ์–ธ์˜ ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•˜๋‹ค. ์–ด๋…ธํ…Œ์ด์…˜ ์ฃผ์ž…์€ XML injection๋ณด๋‹ค ๋จผ์ € ์ˆ˜ํ–‰๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ, XML injection์ด ์–ด๋…ธํ…Œ์ด์…˜ ์ฃผ์ž…์„ ๋ฎ์–ด์“ด๋‹ค. ์–ด๋…ธํ…Œ์ด์…˜์€ ์Šคํ”„๋ง ์ปจํ…Œ์ด๋„ˆ์˜ ๊ธฐ๋ณธ ๊ฐ’์ด ์•„๋‹ˆ๋‹ค. ๊ทธ๋ž˜์„œ, ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— ์Šคํ”„๋ง ์„ค์ • ํŒŒ์ผ์— ์•„๋ž˜์™€ ๊ฐ™์ด ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์•ผํ•œ๋‹ค.

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>
   <!-- bean definitions go here -->

</beans>

context:annotation-config ๊ฐ€ ์„ค์ •๋˜๋ฉด, ์ฝ”๋“œ์˜ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ž๋™์œผ๋กœ ์ฐพ์•„์ค€๋‹ค.

@ Required

์ด ์–ด๋…ธํ…Œ์ด์…˜์€ setter๋ฉ”์†Œ๋“œ์— ์ ์šฉ๋œ๋‹ค. ์„ค์ • ์‹œ์ ์— XML ์„ค์ • ํŒŒ์ผ์— ์„ค์ •ํ•˜๋„๋ก ์š”๊ตฌํ•œ๋‹ค. ์—†์œผ๋ฉด BeanInitializationException ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. Student.java

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Required;

public class Student {
   private Integer age;
   private String name;

   @Required
   public void setAge(Integer age) {
      this.age = age;
   }
   public Integer getAge() {
      return age;
   }

   @Required
   public void setName(String name) {
      this.name = name;
   }
   public String getName() {
      return name;
   }
}

MainApp.java

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      Student student = (Student) context.getBean("student");

      System.out.println("Name : " + student.getName() );
      System.out.println("Age : " + student.getAge() );
   }
}

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for student bean -->
   <bean id="student" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />

      <!-- try without passing age and check the result -->
      <!-- property name="age"  value="11"-->
   </bean>

</beans>

PRINT

Property 'age' is required for bean 'student'

@Requiredํ•œ ์š”์†Œ๋ฅผ ์„ธํŒ… ์•ˆํ•ด์„œ ์œ„์™€ ๊ฐ™์ด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for student bean -->
   <bean id="student" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>
   </bean>

</beans>

์œ„์™€ ๊ฐ™์ด ๋ฐ”๊ฟ”์ค€๋‹ค.

@Autowired

@Autowired ์–ด๋…ธํ…Œ์ด์…˜์€ ์–ด๋””์—,์–ด๋–ป๊ฒŒ autowiring์ด ์„ฑ์ทจ๋˜๋Š”์ง€ ์ข‹์€ ์ œ์–ด๋ฅผ ์ œ๊ณตํ•œ๋‹ค. XML ์„ค์ •ํŒŒ์ผ์˜ property๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  @Autowired๋ฅผ setter ๋ฉ”์†Œ๋“œ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ฉ”์†Œ๋“œ์—์„œ byType autowiring์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค.

TextEditor.java

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }
   public SpellChecker getSpellChecker( ) {
      return spellChecker;
   }
   public void spellCheck() {
      spellChecker.checkSpelling();
   }
}

SpellChecker.java

package com.tutorialspoint;

public class SpellChecker {
   public SpellChecker(){
      System.out.println("Inside SpellChecker constructor." );
   }

   public void checkSpelling(){
      System.out.println("Inside checkSpelling." );
   }
   
}

MainApp.java

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      TextEditor te = (TextEditor) context.getBean("textEditor");

      te.spellCheck();
   }
}

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for textEditor bean without constructor-arg  -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>

</beans>

@Autowired on Properties

setter ๋ฉ”์†Œ๋“œ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ํ”„๋กœํผํ‹ฐ์— @Autowired๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. autowired ํ”„๋กœํผํ‹ฐ์˜ ๊ฐ’์„ property๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ „๋‹ฌํ•  ๋•Œ, ์Šคํ”„๋ง์€ ์ž๋™์œผ๋กœ ํ”„๋กœํผํ‹ฐ๋ฅผ ํ• ๋‹นํ•˜๊ณ  ๊ฐ’์ด๋‚˜ ๋ ˆํผ๋Ÿฐ์Šค๋ฅผ ์ „๋‹ฌํ•œ๋‹ค. TextEditor.java

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   @Autowired
   private SpellChecker spellChecker;

   public TextEditor() {
      System.out.println("Inside TextEditor constructor." );
   }
   
   public SpellChecker getSpellChecker( ){
      return spellChecker;
   }
   
   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for textEditor bean -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>

</beans>

@Autowired on Constructors

@Autowired๋ฅผ ์ƒ์„ฑ์ž์— ์ ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค. XML ํŒŒ์ผ์˜ bean์— constructor-arg๊ฐ€ ์—†์„์ง€๋ผ๋„ bean์ด ์ƒ์„ฑ๋  ๋•Œ autowiring ๋œ๋‹ค.

TextEditor.java

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Autowired;

public class TextEditor {
   private SpellChecker spellChecker;

   @Autowired
   public TextEditor(SpellChecker spellChecker){
      System.out.println("Inside TextEditor constructor." );
      this.spellChecker = spellChecker;
   }

   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for textEditor bean without constructor-arg  -->
   <bean id="textEditor" class="com.tutorialspoint.TextEditor">
   </bean>

   <!-- Definition for spellChecker bean -->
   <bean id="spellChecker" class="com.tutorialspoint.SpellChecker">
   </bean>

</beans>

@Autowired with (required=false) option

๊ธฐ๋ณธ์ ์œผ๋กœ @Autowired๋Š” @Required ์–ด๋…ธํ…Œ์ด์…˜๊ณผ ์œ ์‚ฌํ•˜๊ฒŒ ์˜์กด์„ฑ์ด ์š”๊ตฌ๋จ์„ ์˜๋ฏธํ•œ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ @Autowired(required=false)๋ฅผ ์คŒ์œผ๋กœ์จ ์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ๊บผ์ค„ ์ˆ˜๊ฐ€ ์žˆ๋‹ค.

@Qualifier

๋™์ผํ•œ ์œ ํ˜•์˜ ํ•˜๋‚˜ ์ด์ƒ์˜ ๋นˆ์„ ์ƒ์„ฑํ•˜๊ณ  ๊ทธ ํ”„๋กœํผํ‹ฐ ์ค‘ ํ•˜๋‚˜๋งŒ์„ wire ํ•  ๋•Œ์˜ ์ƒํ™ฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฒฝ์šฐ, ํ˜ผ๋ž€์„ ์—†์• ๊ธฐ ์œ„ํ•ด์„œ ์ •ํ™•ํžˆ bean์„ ๋ช…์‹œํ•จ์œผ๋กœ์จ @Qualifier๋ฅผ @Autowired์™€ ํ•จ๊ป˜ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

Student.java

package com.tutorialspoint;

public class Student {
   private Integer age;
   private String name;

   public void setAge(Integer age) {
      this.age = age;
   }
   
   public Integer getAge() {
      return age;
   }

   public void setName(String name) {
      this.name = name;
   }
   
   public String getName() {
      return name;
   }
}

Profile.java

package com.tutorialspoint;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Profile {
   @Autowired
   @Qualifier("student1")
   private Student student;

   public Profile(){
      System.out.println("Inside Profile constructor." );
   }

   public void printAge() {
      System.out.println("Age : " + student.getAge() );
   }

   public void printName() {
      System.out.println("Name : " + student.getName() );
   }
}

MainApp.java

package com.tutorialspoint;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {
      ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml");

      Profile profile = (Profile) context.getBean("profile");

      profile.printAge();
      profile.printName();
   }
}

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <!-- Definition for profile bean -->
   <bean id="profile" class="com.tutorialspoint.Profile">
   </bean>

   <!-- Definition for student1 bean -->
   <bean id="student1" class="com.tutorialspoint.Student">
      <property name="name"  value="Zara" />
      <property name="age"  value="11"/>
   </bean>

   <!-- Definition for student2 bean -->
   <bean id="student2" class="com.tutorialspoint.Student">
      <property name="name"  value="Nuha" />
      <property name="age"  value="2"/>
   </bean>

</beans>

PRINT

Inside Profile constructor.
Age : 11
Name : Zara

@Qualifier("student1")๋กœ ๋ช…์‹œํ–ˆ๊ธฐ ๋•Œ๋ฌธ์— bean id="student1"๊ฐ€ ์„ธํŒ…๋˜์—ˆ๋‹ค.

JSR-250 Annotations

@PostConstruct, @PreDestroy, @Resource ์–ด๋…ธํ…Œ์ด์…˜.

@PostConstruct and @PreDestroy Annotations

bean์˜ ์„ค์น˜, ๋ถ„ํ•ด ์ •์˜์—์„œ ์šฐ๋ฆฌ๋Š” ๊ฐ„๋‹จํžˆ init-method ์™€/๋˜๋Š” destroy-method๋ฅผ ์„ ์–ธํ–ˆ๋‹ค. @PostConstruct์™€ @PreDestroy๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํ•ด๋‹น ์ฝœ๋ฐฑ๋“ค์„ ๋Œ€์ฒดํ•  ์ˆ˜๊ฐ€ ์žˆ๋‹ค. HelloWorld.java

package com.tutorialspoint;
import javax.annotation.*;

public class HelloWorld {
   private String message;

   public void setMessage(String message){
      this.message  = message;
   }

   public String getMessage(){
      System.out.println("Your Message : " + message);
      return message;
   }
   @PostConstruct
   public void init(){
      System.out.println("Bean is going through init.");
   }
   @PreDestroy
   public void destroy(){
      System.out.println("Bean will destroy now.");
   }
}

MainApp.java

package com.tutorialspoint;

import org.springframework.context.support.AbstractApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class MainApp {
   public static void main(String[] args) {

      AbstractApplicationContext context = 
                          new ClassPathXmlApplicationContext("Beans.xml");

      HelloWorld obj = (HelloWorld) context.getBean("helloWorld");
      obj.getMessage();
      context.registerShutdownHook();
   }
}

Beans.xml

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
    http://www.springframework.org/schema/context
    http://www.springframework.org/schema/context/spring-context-3.0.xsd">

   <context:annotation-config/>

   <bean id="helloWorld" 
       class="com.tutorialspoint.HelloWorld"
       init-method="init" destroy-method="destroy">
       <property name="message" value="Hello World!"/>
   </bean>

</beans>

PRINT

Bean is going through init.
Your Message : Hello World!
Bean will destroy now.

@Resource Annotation

ํ•„๋“œ์™€ setter๋ฉ”์†Œ๋“œ์— @Resource๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. @Resource ์–ด๋…ธํ…Œ์ด์…˜์€ ์ฃผ์ž…๋˜์–ด์ง€๋Š” bean์˜ ์ด๋ฆ„์œผ๋กœ ํ•ด์„๋˜์–ด์ง€๋Š” name ์–ดํŠธ๋ฆฌ๋ทฐํŠธ์—์…” ๊ฐ€์ ธ์˜จ๋‹ค. by-name autowiring์˜ ์˜๋ฏธ๋กœ ์•Œ ์ˆ˜ ์žˆ๋‹ค.

package com.tutorialspoint;

import javax.annotation.Resource;

public class TextEditor {
   private SpellChecker spellChecker;

   @Resource(name= "spellChecker")
   public void setSpellChecker( SpellChecker spellChecker ){
      this.spellChecker = spellChecker;
   }
   public SpellChecker getSpellChecker(){
      return spellChecker;
   }
   public void spellCheck(){
      spellChecker.checkSpelling();
   }
}

๋งŒ์•ฝ 'name'์ด ์ •ํ™•ํžˆ ๋ช…์‹œ ๋ผ์žˆ์ง€ ์•Š๋‹ค๋ฉด, ๊ธฐ๋ณธ ์ด๋ฆ„์€ ํ•„๋“œ๋ช…์ด๋‚˜ setter ๋ฉ”์†Œ๋“œ๋ฅผ ๊ทผ์›์œผ๋กœ ํ•œ๋‹ค. ํ•„๋“œ์— ์žˆ์„ ๋•Œ ํ•„๋“œ๋ช…์„ ๊ฐ€์ ธ์˜จ๋‹ค. setter์— ์žˆ์„ ๋•Œ bean ํ”„๋กœํผํ‹ฐ ์ด๋ฆ„์„ ๊ฐ€์ ธ์˜จ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ