1. 程式人生 > >初探Spring框架

初探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只能解決依賴關係,不能增刪改查!