Spring學習(一)—入門

Spring是什麼?

Spring是一個開源框架,Spring是於2003 年興起的一個輕量級的Java 開發框架,由Rod Johnson創建。簡單來說,Spring是一個分層的JavaSE/EEfull-stack(一站式) 輕量級開源框架。
struts是web框架,Hibernate是O/RM框架

Spring是容器框架,用於配製bean並維護bean之間關係的框架。

Spring中有一個重要概念:Bean(是Java中的任何一種對象,javaBean、service、action、數據源、DAO等)

IoC,控制反轉,Inverse of Control,或者DI(Dependency Injection 依賴注入)

快速入門

開發一個spring項目,這裏使用3.2.17版的
創建一個簡單的maven項目SpringDemo,在pom.xml中寫入:

 <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.2.17.RELEASE</version>
    </dependency>

創建spring的一個核心文件 :applicationContext.xml(spring的配置文件,默認名字,也可以起別的名字)【hibernate有核心hibernate.cfg.xml,struts核心文件struts.xml】,該文件一般放在src目錄下
該版本的配置文件:

<?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-3.2.xsd" >

.....
<!--這裏寫bean-->


</beans>

下面編寫我們的測試代碼:
平常的java開發中,程序員在某個類中需要依賴其它類的方法,則通常是new一個依賴類再調用類實例的方法,這種開發存在的問題是new的類實例不好統 一管理,spring提出了依賴注入的思想,即依賴類不由程序員實例化,而是通過spring容器幫我們new指定實例並且將實例注入到需要該對象的類 中。依賴注入的另一種說法是“控制反轉”,通俗的理解是:平常我們new一個實例,這個實例的控制權是我們程序員,而控制反轉是指new實例工作不由我們 程序員來做而是交給spring容器來做。
我在這模擬項目中的業務層和Dao層
spring有多種依賴注入的形式,這裏使用了Set注入,即我們不再具體的類中手動new對象,把它交給spring操作
set注入
Biz層
UserBiz.java

package com.lgh.spring.biz;

public interface UserBiz {
    public void save();

}

實現
UserBizImpl.java

package com.lgh.spring.biz.impl;

import com.lgh.spring.biz.UserBiz;
import com.lgh.spring.dao.UserDao;

public class UserBizImpl implements UserBiz {

    private UserDao userDao;
    public UserBizImpl() {
        System.out.println("UserBizImpl 構造方法");
    }

    @Override
    public void save() {
        System.out.println("UserBizImpl ------------");
        userDao.save();

    }
    public void setUserDao(UserDao userDao) {
        System.out.println("setUserDao set");
        this.userDao = userDao;
    }

}

Dao層:
UserDao.java

package com.lgh.spring.dao;

public interface UserDao {

    void save();

}

UserDaoMysqlImpl.java

package com.lgh.spring.dao.impl;

import com.lgh.spring.dao.UserDao;

public class UserDaoMysqlImpl implements UserDao {

    public UserDaoMysqlImpl() {
        System.out.println("UserDaoMysqlImpl 構造方法");
    }

    @Override
    public void save() {
        System.out.println("UserDaoMysqlImpl save方法");

    }

}

準備已經做好了,我們之後要在spring的xml文件中進行配置
隨後編寫spring的xml文件,中的id屬性是class屬性的一個別名,class屬性指類的全名,因爲在UserBizImpl.java中有一個公共屬性userDao,所以要在標籤中創建一個標籤指定userDao。標籤中的name就是UserBizImpl類中的userDao屬性名,ref指下面,這樣其實是spring將UserBizImpl對象實例化並且調用UserBizImpl的setUserDao方法將userDao注入:

<bean id="userDao" class="com.lgh.spring.dao.impl.UserDaoMysqlImpl" lazy-init="true" >
</bean>
<bean id="userBiz" class="com.lgh.spring.biz.impl.UserBizImpl" lazy-init="true">
<property name="userDao" ref="userHib"></property>
</bean>

測試:
SpringTest01.java

package com.lgh.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lgh.spring.biz.UserBiz;

public class SpringTest01 {

   public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

    UserBiz userBiz = (UserBiz) ac.getBean("userBiz");
    userBiz.save();
   }

}

執行結果:

UserBizImpl 構造方法
UserDaoMysqlImpl 構造方法
setUserDao set
UserBizImpl ------------
UserDaoMysqlImpl save方法

通過執行結果我們看到spring在幫我們創建對象時,調用了實現類的構造方法
構造器注入
這種方式的注入是指帶有參數的構造函數注入,修改上面的例子,我創建了兩個成員變量userDao,但是並未設置對象的set方法,所以就不能支持第一種注入方式,這裏的注入方式是在UserBizImpl的構造函數中注入,也就是說在創建UserBizImpl對象時要將userDao參數值傳進來:
UserBizConstrImpl.java

package com.lgh.spring.biz.impl;

import com.lgh.spring.biz.UserBiz;
import com.lgh.spring.dao.UserDao;

public class UserBizConstrImpl implements UserBiz {

    private UserDao userDao;
    public UserBizConstrImpl(UserDao userDao) {
        this.userDao = userDao;
        System.out.println("構造方法注入方式"); 
    }

    @Override
    public void save() {

        userDao.save();

    }


}

在XML文件中同樣不用的形式,而是使用標籤,ref屬性同樣指向其它標籤的id屬性:

<bean id="userConBiz" class="com.lgh.spring.biz.impl.UserBizConstrImpl" lazy-init="true">
 <!--(2)創建構造器注入,如果主類有帶參的構造方法則需添加此配置-->  
        <constructor-arg ref="userDao"></constructor-arg>  
</bean>

測試:

package com.lgh.spring.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.lgh.spring.biz.UserBiz;

public class SpringTest04 {

   public static void main(String[] args) {
    ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");

    UserBiz userBiz = (UserBiz) ac.getBean("userConBiz");
    userBiz.save();
   }

}
UserDaoMysqlImpl 構造方法
構造方法注入方式
UserDaoMysqlImpl save方法

有時候,構造方法中傳遞的參數有多個我們用以下方法可以解決構造方法參數的不確定性
下面是設置index,就是參數位置:

<bean id="userConBiz" class="com.lgh.spring.biz.impl.UserBizConstrImpl" lazy-init="true">
 <!--(2)創建構造器注入,如果主類有帶參的構造方法則需添加此配置-->  
        <constructor-arg index="0" ref="userDao"></constructor-arg>  
        <constructor-arg index="1" ref="user"></constructor-arg>  
</bean>

另一種是設置參數類型:

    <constructor-arg type="java.lang.String" ref=""/>  

當參數爲非字符串類型時,在配置文件中需要制定類型,如果不指定類型一律按照字符串類型賦值。

當參數類型不一致時,框架是按照字符串的類型進行查找的,因此需要在配置文件中制定是參數的位置

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章