close

一般物件與物件間會有所謂的相依性(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的建立。

arrow
arrow
    全站熱搜

    Codeless 發表在 痞客邦 留言(0) 人氣()