1. 程式人生 > >Spring入門 --- IOC

Spring入門 --- IOC

配置環境

我們在開發中,會寫很多的類,而有些類之間不可避免的產生依賴關係,這種依賴關係稱之為耦合。有些依賴關係是必須的,有些依賴關係可以通過優化程式碼來解除的。請看下面的示例程式碼:

1 建立maven工程;

2 匯入必要的依賴

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
</dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>
junit</artifactId> </dependency> </dependencies>

2.1 引入log4j的配置檔案

### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### direct messages to file mylog.log ###
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=c:/mylog.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

### set log levels - for more verbose logging change 'info' to 'debug' ###

log4j.rootLogger=debug, stdout

3 建立UserDao介面

public interface UserDao {
   void save();
}

4 建立UserDao介面的實現類UserDaoImpl

public class UserDaoImpl implements UserDao {

   @Override
   public void save() {
      System.out.println("持久層:使用者儲存...");
   }

}

5 建立 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">

    <bean id="userDao" class="cn.cosco.impl.UserDaoImpl"></bean>

</beans>

6 建立測試類

 	@Test
    public void test1(){
        //建立Spring工廠(建立IOC容器)
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");//1
        UserDao userDao  = (UserDao) ac.getBean("userDao");//2
        userDao.save();
    }

測試結果:

控制檯輸出如下結果:

持久層:使用者儲存...

測試發現:我們可以從spring容器中獲取物件,但是,這個物件是如何創建出來的呢?

這其實是利用了 Spring IOC 方法。

Spring IOC

1 什麼是 Spring IOC

IOC,它是Inverse of Control的縮寫,中文含義是控制反轉,表示將物件的建立權力反轉給Spring框架!!

IOC解決的問題:使用IOC可以解決的程式耦合性高的問題!!

2 Spring中的工廠

在spring中提供了兩個工廠介面:

1、ApplicationContext

2、BeanFactory

2.1 ApplicationContext介面

使用該介面可以獲取到具體的Bean物件

該介面下有兩個具體的實現類

ClassPathXmlApplicationContext – 載入類路徑下的Spring配置檔案
FileSystemXmlApplicationContext – 載入本地磁碟下的Spring配置檔案

下面演示FileSystemXmlApplicationContext的用法:把src下的applicationContext.xml拷貝到你電腦的某個目錄,例如:c:/spring,可以通過FileSystemXmlApplicationContext載入本地磁碟下的spring配置檔案

public class TestIOC {
    @Test
    public void test1(){
        //建立Spring工廠(建立IOC容器)
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
        UserDao userDao  = (UserDao) ac.getBean("userDao");
        userDao.save();
    }

    @Test
    public void test2(){
        //建立Spring工廠(建立IOC容器)
        ApplicationContext ac = new FileSystemXmlApplicationContext("C:/spring/applicationContext.xml");
        UserDao userDao  = (UserDao) ac.getBean("userDao");
        userDao.save();
    }

}

2.2 BeanFactory工廠 ---- 已過時

BeanFactory是Spring框架早期的建立Bean物件的工廠介面。在TestIOC中建立test3測試方法:

/**
 * 早期版本的spring工廠:BeanFactory
 */
@Test
public void test3() {
    //此方法已經過時
    BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
    UserDao userDao = (UserDao) factory.getBean("userDao");
    userDao.save();

} 

2.3 BeanFactory和ApplicationContext的區別 :

BeanFactory                – BeanFactory採取延遲載入,第一次getBean時才會初始化Bean

ApplicationContext        – 在載入applicationContext.xml時候就會建立具體的Bean物件的例項

修改UserDaoImpl,增加一個無參構造方法,執行test1和test3兩個單元測試方法,驗證ApplicationContext和BeanFactory這兩個工廠到底什麼時候建立bean物件??

public class UserDaoImpl implements UserDao {

   public UserDaoImpl() {
      System.out.println("呼叫了無參構造方法...");
   }


   @Override
   public void save() {
      System.out.println("持久層:使用者儲存...");
   }

}

修改test1單元測試方法:

/**
 * 建立ioc容器時就已經把物件建立好了
 */
@Test
public void test1(){
    //建立Spring工廠(建立IOC容器)
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    System.out.println("===============");
    UserDao userDao  = (UserDao) ac.getBean("userDao");
    userDao.save();
}

執行結果:

呼叫了無參構造方法...
===============

執行test1方法,發現:ApplicationContext是在建立ioc容器時就已經把物件建立好了

修改test3單元測試方法:

/**
 * 早期版本的spring工廠:BeanFactory
 * 建立ioc容器時並沒有建立物件,而是在第一次getBean時再建立物件
 */
@Test
public void test3() {
    BeanFactory factory = new XmlBeanFactory(new ClassPathResource("applicationContext.xml"));
    System.out.println("===============");
    UserDao userDao = (UserDao) factory.getBean("userDao");
    userDao.save();

}

執行結果:

===============
呼叫了無參構造方法...

執行test3方法,發現:BeanFactory是建立ioc容器時並沒有建立物件,而是在第一次getBean時再建立物件

2.4 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">

    <bean id="userDao" class="cn.cosco.impl.UserDaoImpl"></bean>

</beans>

2.4.1 id屬性

id屬性是bean的唯一標識

2.4.2 class屬 性

javaBean 的全路徑名

其實,除了 id 屬性和 class 屬性外,還可以配置如下屬性:

2.4.3 scope屬性

scope屬性代表Bean的作用範圍

singleton: 單例(預設值)

prototype: 多例,在Spring框架整合Struts2框架的時候,Action 類也需要交給 Spring 做管理,配置把 Action 類配置成多例!!

request: 應用在 web 工程中,將建立的物件存入到 request 域中。

session: 應用在 web 工程中,將建立的物件存入到 session 域中。

globalsession: 應用在 porlet 環境下使用。將建立的物件存入到全域性的 session 中。

後三種比較少見。

在TestIOC中建立單元測試方法test4:

@Test
public void test4() {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    UserDao userDao1 = (UserDao) ac.getBean("userDao");
    UserDao userDao2 = (UserDao) ac.getBean("userDao");
    System.out.println(userDao1==userDao2);

}

執行結果:

呼叫了無參構造方法...
true

測試發現:當scope為 singleton 時,無論例項化幾次 javaBean 物件,都只會建立一次。

修改 applicationContext.xml,把 UserDaoImpl 的作用域改為 prototype:

<?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">
    <bean id="userDao" class="cn.cosco.dao.impl.UserDaoImpl" scope="prototype"></bean>
</beans>

執行結果:

呼叫了無參構造方法...
呼叫了無參構造方法...
false

測試發現:當scope為prototype時,每次獲取bean,都會重新例項化

2.4.4 init-method屬性

當bean被載入到容器的時候呼叫init-method屬性指定的方法

修改 UserDaoImpl ,在其中提供 init 方法

public class UserDaoImpl implements UserDao {

   public UserDaoImpl() {
      System.out.println("呼叫了無參構造方法...");
   }

   public void init(){
      System.out.println("呼叫了init方法...");
   }

   @Override
   public void save() {
      System.out.println("持久層:使用者儲存...");
   }

}

修改 applicationContext.xml,為 UserDaoImpl 指定初始化方法

<?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">
    <bean id="userDao" class="cn.cosco.dao.impl.UserDaoImpl" init-method="init"></bean>
</beans>

執行 test1 單元測試方法,測試結果:

呼叫了無參構造方法...
呼叫了init方法...
===============
持久層:使用者儲存...

2.4.5 destroy-method屬性

當bean從容器中刪除的時候呼叫destroy-method屬性指定的方法

想檢視destroy-method的效果,有如下條件:

scope= singleton 有效 

web容器中會自動呼叫,但是 main 函式或測試用例需要手動呼叫(需要使用 ClassPathXmlApplicationContext 的close() 方法) 

在applicationContext.xml中為UserDaoImpl指定銷燬方法

<?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">
    <bean id="userDao" class="cn.cosco.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
</beans>

修改UserDaoImpl,在其中提供destroy方法

public class UserDaoImpl implements UserDao {

   public UserDaoImpl() {
      System.out.println("呼叫了無參構造方法...");
   }

   public void init(){
      System.out.println("呼叫了init方法...");
   }


   @Override
   public void save() {
      System.out.println("持久層:使用者儲存...");
   }

   public void destroy(){
      System.out.println("呼叫了銷燬方法...");
   }


}

修改test1單元測試方法,顯示關閉ioc容器。測試結果如下:

呼叫了無參構造方法...
呼叫了init方法...
===============
持久層:使用者儲存...
呼叫了銷燬方法...

3 Spring 生成bean的三種方式

3.1 無參構造方法

預設呼叫無參構造方法例項化bean。在此之前,都是呼叫無參構造來例項化的。

3.2 靜態工廠例項化方式

通過呼叫工廠類的靜態方法來生成bean

編寫DeptDao介面:

public Interface DeptDaoImpl {
    public void save();
}

編寫DeptDaoImpl實現類:

public class DeptDaoImpl implements DeptDao{
    @Override
    public void save() {
        System.out.println("持久層:部門儲存...");
    }
}

編寫工廠類,在其中建立靜態工廠方法

public class Factory {
    /**
     * 靜態工廠方法
     */
    public static DeptDao create(){
        System.out.println("呼叫了靜態工廠方法");
        return new DeptDaoImpl();
    }

}

編寫applicationContext.xml配置檔案,採用靜態工廠方式配置DeptDaoImpl類

<?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">
    <bean id="userDao" class="cn.cosco.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
    <bean id="deptDao" class="cn.cosco.factory.Factory" factory-method="create"></bean>
</beans>

在配置DeptDaoImpl這個bean時,class屬性寫的不是DeptDaoImpl的全路徑名,而是工廠類的全路徑名;

factory-method:指定工廠類中靜態方法的名字

在TestIOC類中編寫測試方法test5:

@Test
public void test5(){
    //建立Spring工廠(建立IOC容器)
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
    DeptDao deptDao = (DeptDao) ac.getBean("deptDao");
    deptDao.save();

}

測試結果如下:

呼叫了靜態工廠方法
持久層:部門儲存...

3.3 例項工廠例項化方式

修改Factory工廠類,建立例項工廠方法:

public class Factory {
    /**
     * 靜態工廠方法
     */
//    public static DeptDao create(){
//        System.out.println("呼叫了靜態工廠方法");
//        return new DeptDaoImpl();
//    }

    /**
     * 例項工廠方法
     * @return
     */
    public  DeptDao create(){
        System.out.println("呼叫了例項工廠方法");
        return new DeptDaoImpl();
    }


}

編寫applicationContext.xml,採用例項工廠方式重寫配置DeptDaoImpl

<?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">
    <bean id="userDao" class="cn.cosco.dao.impl.UserDaoImpl" init-method="init" destroy-method="destroy"></bean>
    <!-- 例項工廠方法來例項化 -->
    <bean id="factory" class="cn.cosco.factory.Factory"></bean>
    <bean id="deptDao" factory-bean="factory" factory-method="create"></bean>
</beans>

factory-bean:指定工廠bean的id;

Factory-method:指定工廠bean的例項工廠方法的名字

執行test5測試方法,測試結果如下:

呼叫了例項工廠方法
持久層:部門儲存...

4 注入依賴

4.1 什麼是注入依賴

IOC和DI的概念:
​ * IOC – Inverse of Control,控制反轉,將物件的建立權反轉給Spring!!
​ * DI – Dependency Injection,依賴注入,在Spring框架負責建立Bean物件時,動態的將依賴物件注入到Bean元件中!!

如果UserServiceImpl的實現類中有一個屬性,那麼使用Spring框架的IOC功能時,可以通過依賴注入把該屬性的值傳入進來!!

4.2 構造方法注入

什麼是構造方法注入?構造方法注入就是利用bean的構造方法完成對bean中屬性的賦值。

建立Car實體類,提供有參構造方法

public class Car implements Serializable{
    private String name;
    private Double price;

    public Car(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}

建立applicationContext2.xml,在applicationContext2.xml配置Car這個bean

<?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">
    <!-- 構造方法注入 -->
   <bean id="car" class="cn.cosco.domain.Car">
       <constructor-arg name="name" value="蘭博基尼"></constructor-arg>
       <constructor-arg name="price" value="3000000.0"></constructor-arg>
   </bean>
</beans>

建立單元測試類TestDI,在其中建立單元測試方法test1測試,注意此處建立IOC容器時,應該載入applicationContext2.xml

public class TestDI {
    
    @Test
    public void test1(){
        //建立Spring工廠(建立IOC容器)
        ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext2.xml");
        Car car = (Car) ac.getBean("car");
        System.out.println(car);
    }

}

執行結果:

Car{name='蘭博基尼', price='3000000.0'}

4.3 set方法注入

什麼是set方法注入?set方法注入就是利用bean中屬性的set方法對屬性賦值。

建立People實體類,提供屬性的set方法,不需要提供有參構造方法。

public class 
            
           

相關推薦

Spring入門 --- IOC

配置環境 我們在開發中,會寫很多的類,而有些類之間不可避免的產生依賴關係,這種依賴關係稱之為耦合。有些依賴關係是必須的,有些依賴關係可以通過優化程式碼來解除的。請看下面的示例程式碼: 1 建立maven工程; 2 匯入必要的依賴 <dependencies>

Spring入門 --- IOC

配置環境 我們在開發中,會寫很多的類,而有些類之間不可避免的產生依賴關係,這種依賴關係稱之為耦合。有些依賴關係是必須的,有些依賴關係可以通過優化程式碼來解除的。請看下面的示例程式碼: 1 建立maven工程; 2 匯入必要的依賴 <dependen

SpringIOC/DI(反轉控制/依賴註入)_入門Demo

pro 開發 string類 業務邏輯 測試類 控制 control odin 以及 軟件152 劉安民 在平時的java應用開發中,我們要實現某一個功能或者說是完成某個業務邏輯時至少需要兩個或以上的對象來協作完成,在沒有使用Spring的時候,每個對象在需要使用他的合作對

《Java從入門到放棄》入門篇:springIOC的註入姿勢

java ioc spring IOC到底是個什麽東東呢?控制反轉(Inversion of Control,英文縮寫為IoC),其實就是這個東東。你隨便百度一下就會得到比較書面的解釋:通過引入實現了IoC模式的IoC容器,即可由IoC容器來管理對象的生命周期、依賴關系等,從而使得應用程序的配置和

Spring入門(三)之IoC

使用 bsp martin 需要 容器 nbsp 依賴註入 tin 這就是 一、IoC定義   IoC,即控制反轉。開發者在使用類的實例之前,需要先創建對象的實例。但是IoC將創建實例的任務交給IoC容器,這樣開發應用代碼時只需要直接使用類的實例,這就是IoC。在討論控制反

【Java框架型項目從入門到裝逼】第一節 - Spring框架 IOC的喪心病狂解說

ng- turn ins int 代碼 入門到 extends comm min 大家好,好久不見,今天我們來一起學習一下關於Spring框架的IOC技術。 控制反轉——Spring通過一種稱作控制反轉(IoC)的技術促進了松耦合。當應用了IoC,一個對象依賴的其它對象

Spring入門(一)— IOC、DI

使用 splay 1.0 了解 ngs eth text 實例 sts 一、Spring介紹   Spring 是一個開源框架,是為了解決企業應用程序開發復雜性而創建的。框架的主要優勢之一就是其分層架構,分層架構允許您選擇使用哪一個組件,同時為 J2EE 應用程序開發提供集

Spring入門(二)— IOC註解、Spring測試AOP入門

兩種 cts his 工作 source print 編程 實現機制 工廠 一、Spring整合Servlet背後的細節 1. 為什麽要在web.xml中配置listener <listener> <listener-class>org.s

Spring入門篇——第2章 Spring IOC容器

第2章 Spring IOC容器 介紹Spring IOC容器的基本概念和應用 2-1 IOC及Bean容器               在IO

spring入門ioc

  spring簡介: Spring是一個開源框架,它由Rod Johnson建立。它是為了解決企業應用開發的複雜性而建立的。 Spring使用基本的JavaBean來完成以前只可能由EJB完成的事情。Spring的用途不僅限於伺服器端的開發。從簡單性、可測試性和鬆耦合的角度而

Spring入門之一-------實現一個簡單的IoC

一、場景模擬 public interface Human { public void goHome(); } Human:人類,下班了該回家啦 public interface Car { void start();

Spring入門Ioc簡介

相互學習,歡迎指正,共同進步。 一、Spring概念: Spring 是一個輕量級的Java開源框架,是為了解決企業應用開發的複雜性而建立的。 Spring 是容器框架,建立bean(相當於一個物件),維護bean之間的關係。實現了程式的解耦合和麵向切面(AOP)的容器

Spring入門&IOC

1、Spring入門 1.1 下載spring的開發包 官網:http://spring.io/ 1.2 解壓縮spring的壓縮包 docs :Spring的開發規範和API libs :Spring的開發的jar和原始碼 schema :Spri

Spring課程 Spring入門篇 2-1 IOC和bean容器

本節講了5部分內容: 1  介面及面向介面程式設計 2  什麼是IOC 3  Spring的bean配置 4  Bean的初始化 5  Spring的常用注入方式   自己理解: 1  高層模組和底層模組都依賴於他們共同的介面,而不是高層模組依賴於底層模組進行開發 2  IOC&n

Spring入門案例(Ioc 控制反轉)

1、首先匯入spring必須要的4個核心包(beans、core、context、expression)+1個依賴(commons-logging...jar)              2、目標類

SSH框架學習之Spring ----1、Spring入門IOC

一、 spring概述 開源的輕量級框架(不依賴很多其他東西–輕量級) 兩部分核心 aop 面向切面程式設計:擴充套件功能不是修改原始碼來實現 ioc 控制反轉:把物件的建立交給spring,通過配置代替之前的new物件操作。

Spring入門筆記之ioc容器

                                                                              Spring框架入門筆記(一)                                            

Spring入門——Spring IOC容器

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-ins

(一)SpringIOC入門簡單例子

1. IOC 和 DI 是什麼 2.匯入Spring 的jar 包 3.實現IOC簡單例子的步驟 (一)IOC 和 DI是什麼 IOC即控制反轉,意思是物件的建立不通過 手動 new,而是把物件的建立權交給Spring來完成。 DI 即依賴注入,意思是 Spring主動建

JavaEE框架——Spring入門基礎(控制反轉Ioc和切面技術Aop)

一.簡介: Spring在英語中含義是春天,對於JavaEE開發者來說,Spring框架出現確實帶來了一股全新的春天的氣息。早在2002年,Rod Johson在其編著的《Expert one to one J2EE design anddevelopment》書中,對J