DIの実現には以下の方法がある。
- Setter Injection
- Constructor Injection
Setter Injection
依存オブジェクトを注入してみる。メインのクラスにセッターを用意して、そこにクラスを設定することでオブジェクトの注入を表す。
設定ファイル作成
CarクラスにEngineクラスを設定する。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="car" class="com.daipresents.spring204.test.Car" >
<property name="engine">
<ref bean="engine"/>
</property>
</bean>
<bean id="engine" class="com.daipresents.spring204.test.Engine" />
</beans>
コンポーネントの作成
Carクラスに、依存するEngineクラスを注入する。
CarクラスにはEngineのセッター・ゲッターを用意するだけ。注入されたオブジェクトにアクセスするためにdriveStartメソッドを用意した。
public class Car {
private Engine engine;
public void driveStart(){
Engine en = getEngine();
if(en != null){
en.startEngine();
}else{
System.out.println("エンジンがないので動きません。");
}
}
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
}
Engineクラスはエンジンをスタートすることができるクラス。
public class Engine {
public void startEngine(){
System.out.println("ぶおーん!");
}
}
実行クラス作成
Carクラスを生成し、EngineクラスにdriveStartメソッドからアクセスする。今回はClassPathResourceを使って、クラスパスの通った場所に配置した設定ファイルを読み込んでみた。
public class ClasspathFactory {
public static void main(String[] args) {
Resource resource = new ClassPathResource("/com/daipresents/spring204/beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);
Car car = (Car)factory.getBean("car");
car.driveStart();
}
}
実行結果
ぶおーん!
設定ファイルを書き換えることで「EngineクラスをのせかえることのできるCarクラス」を作ることができた。
Constructor Injection
コンストラクタを利用して依存性を注入してみる。
設定ファイル作成
コンストラクタの引数にEngineクラスを指定する。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="car" class="com.daipresents.spring204.test.Car" >
<constructor-arg>
<ref bean="engine"/>
</constructor-arg>
</bean>
<bean id="engine" class="com.daipresents.spring204.test.Engine" />
</beans>
コンポーネントの作成
Carクラスにコンストラクタを追加。
public class Car {
private Engine engine;
public Car(Engine en) {
setEngine(en);
}
public void driveStart(){
Engine en = getEngine();
if(en != null){
en.startEngine();
}else{
System.out.println("エンジンがないので動きません。");
}
}
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
}
Engineクラスは変わらないでそのまま使う。
public class Engine {
public void startEngine(){
System.out.println("ぶおーん!");
}
}
実行クラス作成
実行クラスも変わらない。
public class ClasspathFactory {
public static void main(String[] args) {
Resource resource = new ClassPathResource("/com/daipresents/spring204/constractor-beans.xml");
XmlBeanFactory factory = new XmlBeanFactory(resource);
Car car = (Car)factory.getBean("car");
car.driveStart();
}
}
static factory methodを使った方法
constractor-injectionと同じだが、インスタンス生成にstaticなfactoryメソッドを使う方法もある。
設定ファイル作成
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN 2.0//EN" "http://www.springframework.org/dtd/spring-beans-2.0.dtd">
<beans>
<bean id="car"
class="com.daipresents.spring204.test.factorymethod.Car"
factory-method="createInstance" >
<constructor-arg ref="engine" />
</bean>
<bean id="engine" class="com.daipresents.spring204.test.factorymethod.Engine" />
</beans>
コンポーネント作成
設定ファイルで指定したfactoryメソッドを実装する。コンストラクタをprivateにして、createInstanceメソッドからしかアクセスできないようにする。
public class Car {
private Engine engine;
private Car(Engine en) {
setEngine(en);
}
public static Car createInstance(Engine en){
return new Car(en);
}
public void driveStart(){
Engine en = getEngine();
if(en != null){
en.startEngine();
}else{
System.out.println("エンジンがないので動きません。");
}
}
public Engine getEngine() {
return engine;
}
public void setEngine(Engine engine) {
this.engine = engine;
}
}
Engineクラスはそのまま。
public class Engine {
public void startEngine(){
System.out.println("ぶおーん!");
}
}
実行クラス作成
public class ApplicationContextFactory {
public static void main(String[] args) {
ApplicationContext context =
new ClassPathXmlApplicationContext("/com/daipresents/spring204/factorymethod-beans.xml");
Car car = (Car)context.getBean("car");
car.driveStart();
}
}
実行結果
ぶおーん!