Spring Setter-based Dependency Injection
(원문 위치 : http://www.tutorialspoint.com/spring/setter_based_dependency_injection.htm)
Example:
[003] HelloWorld Example을 참조하여 프로젝트를 생성한다.
TextEditor.java:
package com.tutorialspoint; public class TextEditor { private SpellChecker spellChecker; // a setter method to inject the dependency. public void setSpellChecker(SpellChecker spellChecker) { System.out.println("Inside setSpellChecker." ); this.spellChecker = spellChecker; } // a getter method to return spellChecker public SpellChecker getSpellChecker() { return spellChecker; } public void spellCheck() { spellChecker.checkSpelling(); } }
setter 함수의 명명규칙을 점검할 필요가 있다. spellChecker 변수를 설정하기 위하여 java POJO class와 유사한 setSpellChecker() 함수를 사용하고 있다.
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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <!-- Definition for textEditor bean --> <bean id="textEditor" class="com.tutorialspoint.TextEditor"> <property name="spellChecker" ref="spellChecker"/> </bean> <!-- Definition for spellChecker bean --> <bean id="spellChecker" class="com.tutorialspoint.SpellChecker"> </bean> </beans>
Beans.xml file에 정의되어진 생성자 기반 삽입(constructor-based injection)과 setter기반 삽입(setter-based injection)의 차이에 유의해야 한다. 유일한 차이점은 생성자 기반은 <bean>요소 내부에 <constructor-arg> tag를 사용하고 setter 기반은 <property> tag를 사용하는 것이다.
두번째 유의할 점은 객체의 참조를 전달하는 경우, <property> tag에 ref 속성을 사용해야 하고 값을 직접적으로 전달하면 value속성을 사용해야 하는 것이다.
프로젝트 실행 결과는 아래와 같다.
Inside SpellChecker constructor. Inside setSpellChecker. Inside checkSpelling.
XML Configuration using p-namespace:
만약 많은 setter함수를 사용해야 한다면 XML 설정 파일에서 p-namespace를 사용하는 것이 편리하다. 차이점을 보자.
<property> tag가 있는 표준 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" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="john-classic" class="com.example.Person"> <property name="name" value="John Doe"/> <property name="spouse" ref="jane"/> </bean> <bean name="jane" class="com.example.Person"> <property name="name" value="John Doe"/> </bean> </beans>
위 XML 설정은 p-namespace를 사용하여 더 깔끔하게 아래처럼 다시 쓸 수 있다.
<?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:p="http://www.springframework.org/schema/p" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd"> <bean id="john-classic" class="com.example.Person" p:name="John Doe" p:spouse-ref="jane"/> </bean> <bean name="jane" class="com.example.Person" p:name="John Doe"/> </bean> </beans>
p-namespace로 객체와 기본값을 명시하는데 차이를 두지 말아야 한다. -ref 부분은 이것이 직접적인 값이 아니고 다른 bean을 참조하다는 것을 나타낸다.
(spouse에 대한 것은 좀 더 찾아봐야 할 듯...)