一般物件與物件間會有所謂的相依性(dependency),例如教室相依於學生
package com.example; public class Classroom { private Student stu=null ; public Classroom(){ stu=new Student() ; } }
但是為了保持物件間的相依關係和物件各自獨立的情況下(保持低耦合Decoupling),則會有所謂的相依性注入(Dependency Injection)
package com.example; public class Classroom { private Student stu=null ; public Classroom(Student stu){ this.stu=stu ; } }
Spring 所採用的是DI來實現控制反轉(Inversion of Control;IOC),DI主要意義就是透過抽象介面來注入相依的物件。主要有兩種DI,如下所示:
Constructor-based dependency injection
Classroom.java
package com.example; public class Classroom { private Student student=null ; public Classroom(Student student){ this.student=student ; } public void getClean(){ student.clean() ; } }
Student.java
package com.example; public class Student { public void clean(){ System.out.println("Student clean classroom"); } }
Main.java
package com.example ; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); Classroom classroom = (Classroom) context.getBean("Classroom"); classroom.getClean(); } }
利用Beans.xml可參照物件中的相依關係
Beans.xml
結果顯示如下所示:
Student clean classroom
setter-based dependency injection
Classroom.java
package com.example; public class Classroom { private Student student ; public Student getStudent() { return student; } public void setStudent(Student student) { this.student = student; } public void goClean(){ student.clean() ; } }
Student.java
package com.example; public class Student { public void clean(){ System.out.println("Student clean classroom"); } }
Main.java
package com.example ; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); Classroom classroom = (Classroom) context.getBean("Classroom"); classroom.goClean(); } }
Beans.xml
結果顯示如下所示:
Student clean classroom
Beans.xml中Bean的constructor-arg也有以下設定方式:
Customer.java
package com.example ; public class Customer { private String name ; private int age ; public Customer(String name,int age){ this.name=name ; this.age=age ; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
Main.java
package com.example ; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); Customer cust = (Customer) context.getBean("Customer"); System.out.println("name:"+cust.getName()) ; System.out.println("age:"+cust.getAge()) ; } }
Beans.xml
Paul 31
另外,也可針對不同變數type去做設定
Customer.java
package com.example ; public class Customer { private String name ; private Integer age ; public Customer(String name,Integer age){ this.name=name ; this.age=age ; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(int age) { this.age = age; } }
Main.java
package com.example ; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); Customer cust = (Customer) context.getBean("Customer"); System.out.println("name:"+cust.getName()) ; System.out.println("age:"+cust.getAge()) ; } }
Beans.xml
Paul 31
結果顯示如下所示:
name:Paul age:31
要使用Constructor-based dependency injection或是Setter-based dependency injection就是取決於物件建立時所有資源都準備好,或是物件建立完後由setter來進行設定。利用setter的方式比較明確知道注入的物件會是什麼,且在記憶上也是較容易記憶的,而constructor則是物件建構完後,一併完成DI的建立。
留言列表