第1章 SpringIOC概述
Spring是一個輕量級的控制反轉(IOC)和麵向切面(AOP)的容器框架。
1.1 控制反轉IOC
IOC(inversion of controller)是一種概念,是把我們程式中的類與類之間的依賴關係交給容器去處理,一般有兩種方式(面試):
- 依賴查詢DL(dependency lookup):程式提供查詢方式,交給容器去查詢(相當於se中的回撥函式);
- 依賴注入DI(dependency injection):程式不提供查詢方式,提供合適的構造方法或者set方法,讓容器進行注入來解決依賴關係。
Spring的控制反轉就是通過依賴注入來實現。
1.2 依賴
依賴:簡單的說,一個類實現某個功能需要依靠另外一個類的幫助。
1.3 回顧:基於介面程式設計的開發方式
當一個方法有多種實現的情況下,我們一般是基於介面的方式進行程式設計。
簡單模擬使用者登入的功能,這裡省略後臺資料庫連線部分。
1)DAO層
介面IUserDao:
package com.steven.spring.sysmanage.dao;
/**
* 用於登入驗證的DAO的介面
* @author Administrator
*
*/
public interface IUserDao{
public boolean loginUser(String userName, String password);
}
//介面實現的兩種方式:UserDaoImplJdbc.java和UserDaoImplOther.java
package com.steven.spring.sysmanage.dao.impl;
import com.steven.spring.sysmanage.dao.IUserDao;
public class UserDaoImplJdbc implements IUserDao {
public boolean loginUser(String userName, String password) {
System.out.println("這是通過JDBC進行登入驗證的DAO方法");
return true;
}
}
package com.steven.spring.sysmanage.dao.impl;
import com.steven.spring.sysmanage.dao.IUserDao;
public class UserDaoImplOther implements IUserDao {
public boolean loginUser(String userName, String password) {
System.out.println("這是通過其它方式進行登入驗證的DAO方法");
return true;
}
}
2) 服務層
package com.steven.spring.sysmanage.service;
import com.steven.spring.sysmanage.dao.IUserDao;
/**
* 用於使用者登入、增刪改查的服務類
* @author Administrator
*
*/
public class UserService {
boolean flag = false;
IUserDao userDao;
public UserService(){
}
//方式1:通過構造器的方式
public UserService(IUserDao userDao){
this.userDao = userDao;
}
//方式2:通過set方式,這種方式更靈活
public void setUserDao(IUserDao userDao) {
this.userDao = userDao;
}
/**
* 通過呼叫與資料庫互動的UserDao裡面的loginUser方法,判斷是否驗證成功
* @param userName
* @param password
* @return
*/
public boolean loginUser(String userName, String password){
flag = userDao.loginUser(userName, password);
return flag;
}
}
3)測試類
package com.steven.spring.sysmgr.action;
import org.junit.Test;
import com.steven.spring.sysmgr.dao.impl.UserDaoImplJdbc;
import com.steven.spring.sysmgr.service.UserService;
public class LoginTest {
@Test
public void loginUsingJava(){
//方式1:使用構造方法
// UserService userService = new UserService(new UserDaoImplOther());
//方式2:使用set方法
UserService userService = new UserService();
userService.setUserDao(new UserDaoImplJdbc());
userService.loginUser("abc", "123");
}
}
由於Java是一種編譯性語言,維護時直接改編碼,需要再次編譯才能上線使用,這樣就增大了維護的工作難度和工作量。 ----> 而更改配置檔案就不需要重新編譯!
1.4 依賴注入
依賴注入DI是指一個物件需要另外一個物件時,無需在程式碼中建立所需求物件,而是依賴於外部容器,由外部容器建立後傳遞給程式。
依賴注入是目前為止最好的解耦方式,因為依賴關係是依靠配置檔案的方式組織在一起,而不是在程式中的硬編碼。
1.5 Spring的IOC
Spring的IOC容器通過依賴注入來實現程式之間的依賴關係,達到解耦的作用。
老專案:3.2版本;新專案:4.2版本
1)Spring專案環境搭建依賴的jar包
java工程jar包放在專案根目錄的libs資料夾下;web工程jar包放在WebContent/WEB-INF/libs資料夾下。
再加上junit的jar包:(注意junit4.10以後是拆分了兩個包)
再加上日誌包:
2)配置檔案applicationContext.xml,加上bean約束
在spring-framework-4.2.1.RELEASE\docs\spring-framework-reference\html下有xsd-configuration.html檔案中有初始配置。
IOC的實現原理:反射
無反射無框架,無代理無框架
在上面例子的基礎上,增加spring配置xml檔案,更改實現層。
1)spring配置檔案applicationContext.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.xsd">
<!-- 相當於Java程式碼中的 IUserDao userDaoImplJdbc = new UseDaoImplJdbc() -->
<bean id="userDaoImplJdbc" class="com.steven.spring.sysmanage.dao.impl.UserDaoImplJdbc"></bean>
<bean id="userDaoImplOther" class="com.steven.spring.sysmanage.dao.impl.UserDaoImplOther"></bean>
<bean id="userService" class="com.steven.spring.sysmanage.service.UserService">
<!-- 方式1:通過構造方法的方式注入 -->
<constructor-arg ref="userDaoImplOther"></constructor-arg>
<!-- 方式2:通過set方法的方式注入,注意這裡的的name的值需與set方法名後面的部分保持一致,且首字母小寫-->
<property name="userDao" ref="userDaoImplOther"/>
</bean>
</beans>
2)更改測試類
package com.steven.spring.sysmgr.action;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.steven.spring.sysmgr.dao.impl.UserDaoImplJdbc;
import com.steven.spring.sysmgr.service.UserService;
public class LoginTest {
@Test
public void loginUsinSpring(){
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService userService = (UserService)ac.getBean("userService");
userService.loginUser("abc", "123");
}
}