1. 程式人生 > >spring IOC/DI思想

spring IOC/DI思想

傳統使用new 類注入的方式造成程式碼的耦合,例如: StudentAction類,依賴StudentBiz,並呼叫服務層StudentBiz中的getName()方法

public student StudentAction{

StudentBiz studentBiz=new StudentBiz();

public vooid printSTUDENTnAME(){

      System.out.println("學生:"+studentBiz.getName())

}

}

服務層StudentBiz又通過new例項化StudnetDao,依賴studnetDao,並呼叫了studnetDao的getName()方法。

這樣類與類之間層層的依賴會造成,當修改一個類時,其相關依賴的類都要重新編譯才能使用,可謂是牽一髮而動全身,付出的代價太大,故spring推出了依賴注入的解決方案。

1.工廠模式:(使用工廠模式建立物件)

public interface IStudentBiz{}

public class StudentBiz implements IStudentBiz{}

public class StudentBizFactory{ public static IStudentBiz getInstance(){return new StudentBiz();}}

public class StudentAction{IStudnetBiz studnetBiz=studnetFactory.getInstance()}

此時,服務類studentBiz發生變化,只需調整studengFactory程式碼,studentAction不用動。

2.spring的控制反轉(ioc)或依賴注入(DI)

spring可以管理很多類(java不就是類與類之間的運作嗎,需要預先宣告bean,即在application.xml中配置bean,類之間的依賴關係,如:A依賴B,則在A類中需要定義對B類賦值的setter方法,這是spring對管理類的唯一的要求。)舉例如下:

public interface IstudentDao{public String getName()}

public class StudnetDao implemtns IstudentDao{@override public String getName(return ''李四"//實際中李四是從資料庫中取出來//studentDao.getName())  }

//業務層

public interface IStudnetBiz {public String getName()}

public class StudnetBiz implemtns IStudentBiz{ IStudentDao studntDao; @Override public String getName(){return studnetDao.getName();}}

//與studnetDao.getName()對應的setter方法是:

public void setStudnetDao(IStudnetDao studentDao){this.studentDao=studentDao}

web層的setter:

public class StudentAction{ IstudentBiz studentBiz;    public void setStudnetDao(IStudnetDao studentDao){this.studentDao=studentDao}       public void printName(System.out.println(studentBiz.getName())}

spring中的配置:

<bean id="studentDao" class="xxx.xxx.impl.StudentDao"/>

//id是bean的標記

<bean id="studentBiz" class="xxx.xxx.impl.StudentBiz">

//呼叫setStudentDao(),為studentBiz的studentDao屬性賦值

   <property name=""studentDao>

<ref bean="studentDao"/>

</property>

//properties是子標記,定義了對應類的setter方法

//ref是子標記,定義了需要傳遞給setter方法的例項物件

main方法測試:

ApplicationContext ctx=new ClassPathXmlApplicationContext(xx/xx/application.xml)

StudentAction studentAction=(StudentAction)ctx.getBean("studentAction");

studentAction.printName();

依賴注入到此結束。

下面是代理模式:

被代理類:student(或客戶,明星比如劉德華)

代理類:studentProxy(律師,代理人,經紀人)

二者必須都要實現同一個介面Istudent

public interface Istudent{ public void writework()}

public class Student implements Istudent{@Override public vioid writehomework(println("我是被代理類,我在寫作業"))}

注意,傳參是傳被代理的介面。

public class StudentProxy implements Istudent{private Istudent student; public StudentProxy(Isudent student){this.student=student}   @Override public vioid writehomework{(println("執行前的日誌列印"),student.write.wroteHomwork();,println("執行後的日誌列印")},

測試程式碼:

Istudent studnet=new Studnet();

student.writeHomework();

Istudent studentProxy=new Studnet StudnetProxy(studnet);

studnetProxy.writeHomework();

總結:

最後做事情的是代理類,代理類按照被代理類的意願做了事情,並列印了日誌,它在不修改被代理類的前提下對他加入了日誌功能,而且日誌完全由代理類進行控制,做到了日誌功能和也業務功能的分離,還需增加功能時,按同樣的方式建立代理類即可。