Spring(一)Spring的基本應用


控制的什么被反轉了?就是獲得依賴對象的方式被反轉了——Martin Fowler

1、Spring基本知識

 1.1 什么是Spring?

  • Spring是分層JavaSE/EE full-stack輕量級開源框架
  • IoC(Inverse of Control,控制反轉)和AOP(Aspect Oriented Programing,面向切面編程)為核心
  • 實際開發中,通常采用三層體系架構(web、service、dao)。spring對每一層都提供了技術支持,在表示層提供了與struts2框架的整合,在業務邏輯層可以管理事務、記錄日志等,在持久層可以整合Hibernate、JdbcTemplate等技術

 1.2 Spring框架的優點

  • 方便解耦,簡化開發  (高內聚低耦合)  Spring就是一個大工廠(容器),可以將所有對象創建和依賴關系維護,交給Spring管理spring工廠是用於生成bean
  • AOP編程的支持                   Spring提供面向切面編程,可以方便的實現對程序進行權限攔截、運行監控等功能
  • 聲明式事務的支持                只需要通過配置就可以完成對事務的管理,而無需手動編程
  • 方便程序的測試                                   Spring對Junit4支持,可以通過注解方便的測試Spring程序
  • 方便集成各種優秀框架                                  Spring不排斥各種優秀的開源框架,其內部提供了對各種優秀框架(如:Struts、Hibernate、MyBatis、Quartz等)的直接支持
  • 降低JavaEE API的使用難度                          Spring 對JavaEE開發中非常難用的一些API(JDBC、JavaMail、遠程調用等),都提供了封裝,使這些API應用難度大大降低

 1.3 Spring的體系結構 

  

        核心容器:beanscorecontextexpression

 1.4 Spring的下載及目錄結構

  下載地址:http://repo.spring.io/simple/libs-release-local/org/springframework/spring/3.2.0.RELEASE
  目錄結構:

    

  libs中有50多個jar文件,有4個Spring的基礎包,分別對應Spring核心容器的4個模塊

    

          spring-core-3.2.0.RELEASE.jar           包含Spring框架基本的核心工具類,Spring其他組件都要用到這個包里的類,是其他組件的基本核心
     spring-beans-3.2.0.RELEASE.jar        所有應用都要用到的,它包含訪問配置文件、創建和管理bean以及進行IoC或者DI操作相關的類
     spring-context-3.2.0.RELEASE.jar      在基礎IoC功能上的擴展服務
     spring-expression-3.2.0.RELEASE.jar   定義了Spring的表達式語言

2. 入門案例:IoC

 2.1 導入jar包   4核心+1依賴    

  

 2.2 目標類

  UserDao接口

public interface UserDao {
    public void addUser();
}

  UserDaoImpl實現類

public class UserDaoImpl implements UserDao {
    @Override
    public void addUser() {
        System.out.println("添加用戶");
    }
}

 2.3 配置文件

  spring幫我們創建對象,但也必須有相關類的信息,不然怎么能夠創建呢?

  配置文件名稱:建議:ApplicationContext.xml,取別的也可以,但是取建議的名稱的話,找到該配置文件更為簡單,

  配置文件位置:任意,一般都在classpath下(src)

  文件約束內容:添加約束,spring-framework-3.2.0.RELEASE 為spring的核心  docs為幫助文檔

  約束位置:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.html

 

<?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="com.tcxpz.spring_chapter01.ioc.UserDaoImpl"></bean> </beans>

 2.4 測試

public class TestIoC { @Test public void demo(){ /* * 以前的做法是 UserDao userDao = new UserDaoImpl() * 現在交給Spring來創建,程序從Spring容器中獲取 */ //1 定義配置文件的路徑(項目中一般放在src目錄下,此處為方便放在包下) String xmlPath = "com/tcxpz/spring_chapter01/ioc/applicationContext.xml"; //2 初始化Spring容器,加載配置文件 ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath); //3 通過容器獲取userDao實例 UserDao userDao = (UserDao) applicationContext.getBean("userDao"); //調用userDao的addUser()方法  userDao.addUser(); } }

  測試結果:

    

3 入門案例2:DI

  依賴注入(DI):spring創建對象A時,會將對象A所依賴的對象B也創建出來,並自動注入到對象A中。

  依賴:(has a) 有一個的意思,比如類A中有一個類B,那么就說A依賴B。          

  繼承,實現:(is a)

  當出現一個類依賴於另一個類時,之前的開發是這樣的

public class UserServiceImpl implements UserService {
    private UserDao userDao = new UserDaoImpl();
    @Override
    public void save() {
        userDao.addUser();
    }
}

  學習了Spring之后,開發就是這樣的了

public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void save() {
        userDao.addUser();
    }
}

 3.1 導入jar包(同2.1)

 3.2 目標類

  UserDao接口與UserDaoImp實現類(同2.2)

  UserService接口與UserServiceImpl實現類

public interface UserService {
    public void save();
}
public class UserServiceImpl implements UserService {
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }
    @Override
    public void save() {
        userDao.addUser();
    }
}

 3.3 配置文件

<?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">
      <!-- 創建UserDao對象 -->
    <bean id="userDao" class="com.tcxpz.spring_chapter01.di.UserDaoImpl"></bean>
    <!-- 創建Service對象 -->
    <bean id="userService" class="com.tcxpz.spring_chapter01.di.UserServiceImpl">
    <!--  
    <property> 用於進行屬性注入
            name: bean的屬性名,通過setter方法獲得
                setBookDao ##> BookDao  ##> bookDao
            ref :依賴的另一個bean的id值的引用
    -->
        <property name="userDao" ref="userDao"></property>
    </bean>
</beans>

 

3.4 測試

public class TestDI {
    @Test
    public void demo(){
        String xmlPath = "com/tcxpz/spring_chapter01/di/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        UserService userService = (UserService) applicationContext.getBean("userService");
        userService.save();
    }
}

 測試結果

4 Spring中的bean

4.1 Bean的配置

可以把Spring看做一個大型的工廠,而Spring容器中的bean就是該工廠的產品

Spring容器支持兩種格式的文件,分別為Properties文件格式和XML文件格式,在實際開發中,最常用的是XML文件格式的配置方式

每一個<bean>子元素定義了一個bean,並且描述了該bean如何被裝配到Spring容器中。<bean>中包含很多屬性:id,name,class,scope,constructor-arg,property,ref,value,list,set,map,entry

4.2 Bean的實例化

並不是每個bean都是普通類,有些是通過工廠來獲取的,而工廠就有靜態工廠和實例工廠,所以spring創建實例對象有三種情況,

  默認無參構造:直接<bean id="" class="">,必須提供無參的構造方法

  靜態工廠:由於是靜態工廠,所以通過工廠類直接調用創建實例的靜態方法就可以了,不需要創建工廠的實例對象。

        <bean id="" class="工廠全限定類名" factory-method="靜態方法">

  實例工廠:需要先創建出工廠實例對象,然后再由工廠實例對象的方法創建對象,所以會有兩個Bean

          <bean id="myFactoryId" class="工廠全限定類名"></bean>

          <bean id="" factory-bean="myFactoryId"  factory-method=""></bean>

4.3 Bean的作用域

  作用域的種類:singleton  prototype  request  session  global

    

    主要掌握前兩個即可

單例模式(singleton):使用singleton定義的Bean在Spring容器中只有一個實例,也就是說,無論有多少個Bean引用它,始終指向同一個對象(默認作用域) 

public class TestDI {
    @Test
    public void demo(){
        String xmlPath = "com/tcxpz/spring_chapter01/di/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        UserService userService1 = (UserService) applicationContext.getBean("userService");
        UserService userService2 = (UserService) applicationContext.getBean("userService");
        System.out.println(userService1==userService2);
    }
}

原型模式(prototype):每次通過Spring容器獲取的prototype定義的Bean時,容器都將創建一個新的實例。

4.4 Bean的生命周期

  Spring容器可以管理singleton作用域下Bean的生命周期,再次作用於下,Spring能夠精確地知道該何時創建,何時初始化完成,以及何時被銷毀。

  而對於prototype作用域的Bean,Spring只負責創建,當容器創建了Bean實例后,Bean的實例就交給客戶端代碼來管,Spring容器就不再跟蹤其生命周期。

4.5 Bean的裝配方式

  Bean的裝配可以理解為依賴關系注入,Bean的裝配方式也就是Bean依賴注入的方式。主要有三種:基於XML      基於注解      自動裝配

  4.5.1 基於XML的裝配

    主要有兩種方式:setter注入和構造注入   setter注入時,Bean類必須提供一個默認的構造方法,而且必須為注入的屬性提供setter方法
    (1)導包   4核心+1依賴

    (2)創建User類

public class User {
    private String username;
    private Integer password;
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public Integer getPassword() {
        return password;
    }
    public void setPassword(Integer password) {
        this.password = password;
    }
    //默認構造
    public User(){
    }
    //構造方法注入
    public User(String username,Integer password){
        super();
        this.username=username;
        this.password=password;
    }
    @Override
    public String toString() {
        return "User [username=" + username + ", password=" + password + "]";
    }    
}

    (3)測試

public class TestUser {
    @Test
    public void demo(){
        String xmlPath="com/tcxpz/spring_chapter01/domain/applicationContext.xml";
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext(xmlPath);
        User user1 = (User) applicationContext.getBean("user1");
        User user2 = (User) applicationContext.getBean("user2");
        System.out.println(user1);
        System.out.println(user2);
    }
}

  不管是普通屬性還是引用數據,都可以通過構造方法進行注入。通過setter方法進行注入引用數據。

  

  通過setter方法對普通屬性和引用屬性進行注入,那么要是創建的對象中有集合呢?那該如何進入注入?

         集合的注入List、Map、Set、數組、Properties等。

  list

    

  set

    

  map

    

  數組:

    

  properties

    

    注意:集合之間可以相互嵌套,比如list中可能裝有對象(bean)等等

      

  4.5.2 基於Annotation的裝配    

    注解格式:@xxx       開發中通常采用注解取代xml配置文件

    使用注解:必須對使用注解的地方進行掃描,不然注解沒用。而掃描需要做兩件事

      1、添加名稱空間

         在我們找配置文件中約束的位置那:spring-framework-3.2.0.RELEASE\docs\spring-framework-reference\html\xsd-config.html 找到context的名稱空間。

         

        

      2. 掃描指定的目錄

        

    注解:

      1、@Component  替代  <bean id="" class=""> 可以配置任意bean,在所在類上面添加該注解即可,

         @Component("userId") userId相當於bean中的id屬性值

      2、這三個就跟使用@Component是一樣的,但是為了更好的體現三層架構,就有了這三個注解

         @Controller  修飾web層中的類。

         @Service  修飾service層的類

         @Repository  修飾dao層的類

            兩種方式,一種不聲明名稱,一種聲明名稱

            @Controller("xxx")  @Controller  

            如果聲明了名稱,那么在別的地方引用的話,就可以使用@Autowired或@Autowired與@Qualifier的組合 或直接使用@Resource按照名稱注入

            如果沒有聲明名稱,那么在別的地方引用的話,只能使用@Autowired 來進行注入

      3、屬性注入

         普通屬性

            @Value    @Value("")  給普通屬性注入屬性值

          引用屬性

              @Autowired  按默認類型進行注入

              @Qualifier("") 按照名稱注入  

            如果使用了@Qualifier這個注解,那么就需要兩個一起使用才能生效。如果只使用@Autowired,那么寫不寫@Qualifier都可以

          引用屬性

            @Resource  直接按照名稱注入,與上面兩個注解一起使用是等效的  

            @Resource(name="xxx")

      4、使用

        

      5、其他注解

        @Scope("prototype")  作用域注解(spring幫我們創建的bean實例的作用域,在下面會講解到)

        @PostConstruct  修飾初始化    

        @PreDestory  修飾銷毀      

                最后兩個用的不多,掌握前面的即可。

  4.5.3 P命令空間[了解]

  對setter方法注入”進行簡化,替換<property name="屬性名">,而是在<bean p:屬性名="普通值"  p:屬性名-ref="引用值">

  p命名空間使用前提,必須添加命名空間

     

    <bean id="personId" class="com.itheima.f_xml.c_p.Person" 
        p:pname="jack" p:age="22" 
        p:homeAddr-ref="homeAddrId" p:companyAddr-ref="companyAddrId">
    </bean>
    
    <bean id="homeAddrId" class="com.itheima.f_xml.c_p.Address"
        p:addr="北京" p:tel="010">
    </bean>
    <bean id="companyAddrId" class="com.itheima.f_xml.c_p.Address"
        p:addr="合肥" p:tel="0551">
    </bean>

 

  4.5.4 SpEL[了解]

  <property>進行統一編程,所有的內容都使用value

  <property name="" value="#{表達式}">

    #{123}#{'jack'} : 數字、字符串

    #{beanId} :另一個bean引用

    #{beanId.propName} :操作數據

    #{beanId.toString()} :執行方法

    #{T().字段|方法} :靜態方法或字段

5 myeclipse schema xml提示

 步驟一:確定xsd文件位置:spring-framework-3.2.0.RELEASE\schema\beans

步驟二:復制路徑

步驟三:搜索“xml catalog”

步驟四:添加約束提示

 

 

 

 

 

 

  

 

 

 

        


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM