初探Spring框架
在開始接觸Spring之前來先看看之前寫的程式碼
這是IUserService接口裡面的方法:
public interface IUserService {
void saveAccount();
}
然後是介面的實現類:
public class IUServicesImpl implements IUserService {
private IUserDao userDao = new IUserDaoImpl();
@Override
public void saveAccount() {
userDao.saveAccount ();
}
}
接著是操作資料庫層的Dao
public interface IUserDao {
void saveAccount();
}
接著就是介面的實現類
public class IUserDaoImpl implements IUserDao {
@Override
public void saveAccount() {
System.out.println("儲存使用者了......");
}
}
然後我們來測試程式碼:
public class AppTest{
@Test
public void testSpring(){
IUserService userService = new IUServicesImpl();
userService.saveAccount();
}
}
通過一系列的程式碼我們可以發現當需要物件的時候我們需要new
這樣造成的結果就是程式碼之間的耦合度很高,不利於程式碼維護
我們需要利用學習的反射知識讓反射幫助我們建立物件
這樣程式碼之間耦合稍微降低一些那麼如何利用反射建立物件,這時候需要我們建立一個BeanFactory工廠類,此類的作用就是在該類中建立我們需要的物件,不在需要我們new物件只要需要傳入我們類的名字就可以
第一步:
利用配置檔案把我們需要的都類的實現都放在配置檔案裡面bean.properties
accountService=com.beijing.service.Impl.IUServicesImpl
accountDao=com.beijing.dao.Impl.IUserDaoImpl
第二部我們需要在BeanFactory中讀取配置檔案:
/**
* BeanFactory用來建立物件
* 配置檔案
* 讀物配置檔案反射建立物件
*/
public class BeanFactory {
private static Properties prop;
static{
try{
prop = new Properties();
InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
prop.load(resourceAsStream);
}catch (Exception e){
e.printStackTrace();
System.out.println("載入配置檔案失敗");
}
}
//定義一個獲取new物件的方法
public static Object getBean(String benaName){
Object bean = null;
try{
String beanPath = prop.getProperty(benaName);
//System.out.println(beanPath);
bean = Class.forName(beanPath).newInstance();
}catch (Exception e){
e.printStackTrace();
}
return bean;
}
}
這樣我們需要在測試的時候需要傳入一個String beanName就可以通過反射獲取我們需要的物件
在我們需要new物件的地方就利用BeanFactory來建立我們需要的物件
public class IUServicesImpl implements IUserService {
//利用反射建立物件
private IUserDao userDao = (IUserDao) BeanFactory.getBean("accountDao");
@Override
public void saveAccount() {
userDao.saveAccount();
}
}
在測試類中:
public class AppTest{
@Test
public void testSpring(){
IUserService userService = (IUserService) BeanFactory.getBean("accountService");
userService.saveAccount();
}
}
到這裡我們發現程式碼之間的耦合度降低了,但是程式碼之間問題還是很多
這裡我們需要IUserService是單例的但是我們通過程式碼發現這裡方式獲取的是userService是多例也就是我們每次建立都會new一個新的物件
我們可以建立一個容器用來儲存我們的物件
這時候修改BeanFactory工廠類
public class BeanFactory {
private static Properties prop;
//定義一個map用來儲存我們要建立的物件我們稱之為容器
private static Map<String,Object> beans;
static{
try{
prop = new Properties();
InputStream resourceAsStream = BeanFactory.class.getClassLoader().getResourceAsStream("bean.properties");
prop.load(resourceAsStream);
//例項化容器
beans = new HashMap<>();
//獲取載入配置檔案裡面的值
Enumeration<Object> keys = prop.keys();
//遍歷列舉獲取裡面的每個key
while (keys.hasMoreElements()){
//獲取每個key
String key = keys.nextElement().toString();
//根據key獲取value
String beanPath = prop.getProperty(key);
//反射建立物件
Object value = Class.forName(beanPath).newInstance();
//放入容器
beans.put(key,value);
}
}catch (Exception e){
e.printStackTrace();
System.out.println("載入配置檔案失敗");
}
}
/**
* 獲取物件
* @param benaName
* @return
*/
public static Object getBean(String benaName){
return beans.get(benaName);
}
}
這時候在測試就會發現:
public class AppTest{
@Test
public void testSpring(){
for (int i = 0; i < 5; i++) {
IUserService userService = (IUserService) BeanFactory.getBean("accountService");
System.out.println(userService);
userService.saveAccount();
}
}
}
這裡的控制檯就會發現userService是單例
分析什麼是控制反轉(IOC)
private IUserDao userDao = new IUserDaoImpl();
private IUserDao userDao = (IUserDao) BeanFactory.getBean("accountDao");
這裡是IUserService類裡面需要建立的userDao物件
第一行程式碼知道我們建立的類的真實物件,也知道類建立是不是我們所需要的!
而第二行程式碼把建立物件的的權利交給BeanFactory,同時我們也不知道建立的類是否為類所用,只需要傳入字串就可以獲取物件
這樣的做法就是消減類與類之間的耦合性
IOC:就是把建立物件的權利交給Spring框架
Spring只能解決依賴關係,不能增刪改查!