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 ๊ฐ ์ค์ ๋๋ฉด, ์ฝ๋์ ์ด๋ ธํ ์ด์ ์ ์๋์ผ๋ก ์ฐพ์์ค๋ค.
์ด ์ด๋ ธํ ์ด์ ์ 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>
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 ์ด๋ ธํ ์ด์ ์ ์ด๋์,์ด๋ป๊ฒ 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>
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๋ฅผ ์์ฑ์์ ์ ์ฉํ ์๋ ์๋ค. 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๋ @Required ์ด๋ ธํ ์ด์ ๊ณผ ์ ์ฌํ๊ฒ ์์กด์ฑ์ด ์๊ตฌ๋จ์ ์๋ฏธํ๋ค. ๊ทธ๋ฌ๋ @Autowired(required=false)๋ฅผ ์ค์ผ๋ก์จ ์ด๋ฌํ ๊ธฐ๋ฅ์ ๊บผ์ค ์๊ฐ ์๋ค.
๋์ผํ ์ ํ์ ํ๋ ์ด์์ ๋น์ ์์ฑํ๊ณ ๊ทธ ํ๋กํผํฐ ์ค ํ๋๋ง์ 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>
Inside Profile constructor.
Age : 11
Name : Zara
@Qualifier("student1")๋ก ๋ช ์ํ๊ธฐ ๋๋ฌธ์ bean id="student1"๊ฐ ์ธํ ๋์๋ค.
@PostConstruct, @PreDestroy, @Resource ์ด๋ ธํ ์ด์ .
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>
Bean is going through init.
Your Message : Hello World!
Bean will destroy now.
ํ๋์ 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 ํ๋กํผํฐ ์ด๋ฆ์ ๊ฐ์ ธ์จ๋ค.