Spring隨筆(IOC/DI 及注入方式)

爲什麼要使用Spring,優點是什麼?

1.高內聚低耦合,簡化開發
spring是一個大工廠(容器),可以將對象的創建和依賴關係的維護全部交給spring管理。
2.支持Aop編程
方便對程序的權限攔截和運行性能進行監控
3.聲明式事務支持
通過過配置就可以完成對事務的管理,無需手動編程
4.支持Junit
5.方便集成各種優秀的框架

核心技術

IOC:控制反轉

什麼是控制反轉?Ioc不是一種技術而是一種設計思想,傳統的開發中我們在對象的內部通過new直接創建對象,是程序主動創建依賴對象。IOC意味着我們將對象的控制權交給專門容器去管理。這樣就降低了程序的耦合性。控制是什麼?主要就是控制了外部資源獲取。反轉:傳統的方式是我們在自己在對象中主動控制直接獲取依賴對象,就是正轉。而反轉則是由容器來幫助我們創建對象和注入依賴對象。對象只是被動的接受依賴對象。也就是說依賴對象的獲取被反轉了。

簡單的說就是A類要使用B接口中的方法 我們傳統的做法就是在A類中直接new一個B接口的實現類對象。但是顯然這樣做類和接口的依賴太強了。IOC是將A類B接口和他的實現類交給IOC容器,通過IOC容器的配置來實現他們之間的關聯。

DI:依賴注入

DI是什麼?IOC和DI是同一概念的不同描述。

DI的三種方式

測試類

package com.spring.demo;

public class BookServiceImpl implements BookService {


    @Override
    public void insert() {
        System.out.println("調用dao");


    }

}
package com.spring.demo;

public class BookDaoImpl implements BookDao {

    @Override
    public void insert() {
        System.out.println("插入數據");

    }

}
  • 構造器注入
package com.spring.demo;

public class BookServiceImpl implements BookService {
//傳統方式  BookDao b=new BookDaoImpl();
    private BookDao bookdao;
//構造函數
    public BookServiceImpl(BookDao bookdao) {

        this.bookdao = bookdao;
    }

    @Override
    public void insert() {
        System.out.println("調用dao");
        bookdao.insert();

    }

}
<?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="Dao" class="com.spring.demo.BookDaoImpl"></bean>
    <bean id="Service" class="com.spring.demo.BookServiceImpl">
    <!-- 構造默認從零開始 -->
        <constructor-arg index="0" ref="Dao">
        </constructor-arg>
    </bean>
</beans>
  • set方法注入(屬性注入)
public class BookServiceImpl implements BookService {
    // 之前的方式 BookDao dao=new BookDaoImpl(); 耦合性強
    private BookDao bookDao;
// set方法
    public void setBookDao(BookDao bookDao) {
        this.bookDao = bookDao;
    }

    @Override
    public void insert() {
        System.out.println("調用dao");
        this.bookDao.insert();
    }

}

BooKDao省略

<?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 definitions here -->
    <!-- Ioc 控制反轉 ,創建service實例 -->
    <bean id="BookService" class="BookServiceImpl">
        <!-- service依賴於Dao 注入 name bean的屬性名 ref 注入的bean的id -->
        <property name="bookDao" ref="BookDao"></property>
    </bean>
    <!-- Ioc 創建BookDao實例 -->
    <bean id="BookDao" class="BookDaoImpl"></bean>
    </beans>

注意的是:假如我們要注入一個簡單javaBean對象,他沒有無參的構造方法是無法使用屬性注入的

package com.spring.demo;

public class User {
    private String name;
    private Integer age;

    public User(String name, Integer age) {
        super();
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "User [name=" + name + ", age=" + age + "]";
    }

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

如果此時我們不指定構造的參數 會報一個錯誤:
這裏寫圖片描述

<?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
         ">
     <!-- type參數返回值類型  index 參數位置 -->    
    <bean id="user" class="com.spring.demo.User">
        <constructor-arg type="java.lang.String" index="0"
            value="花花"></constructor-arg>
        <constructor-arg type="java.lang.Integer" index="1"
            value="10"></constructor-arg>
    </bean>


    <bean id="Dao" class="com.spring.demo.BookDaoImpl"></bean>
    <bean id="Service" class="com.spring.demo.BookServiceImpl">
        <property name="user" ref="user"></property>
        <!-- 構造默認從零開始 -->
        <constructor-arg  ref="Dao">

        </constructor-arg>
    </bean>
</beans>

所以我們在開發中要保留默認構造,使用屬性注入使用< proprety>標籤 使用構造注入使用的是< constructor-arg>標籤

  • 接口注入(基本不用)

    反射獲取實例化對象

  • 註解注入
    使用註解注入首先要引入標籤和命名空間。
    @Component取代了標籤
    @Component取代了
    web開發提供了三個衍生註解
    @Repository dao層
    @Service service 層
    @Contorller web層
    普通值 @Value()
    引用值 :
    按照類型注入
    @Autowired
    按照名稱注入
    1 .@Autowired
    @Qualifier(“名稱”)
    2.@Resource(“名稱”)

    生命週期:
    初始化:@PostConstruct
    銷燬: @PreDestory
    作用域:@Scope(“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" xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context.xsd"> <!-- bean definitions here -->
    <!-- 掃描組件 -->
    <context:component-scan base-package="com.spring.annotation"></context:component-scan>
</beans>
package com.spring.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;

@Controller("BookActionid")
public class BookAction {
    //按類型注入
    @Autowired
    private BookService bookService; 

    public void insert() {
        System.out.println("這是web");
        bookService.insert();

    }

}
package com.spring.annotation;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;

@Service
public class BookServiceImpl implements BookService {

    private BookDao bookdao;
    //按名稱注入
    @Autowired
    @Qualifier("BookDaoImpl")
    public void setBookdao(BookDao bookdao) {
        this.bookdao = bookdao;
    }

    @Override
    public void insert() {
        System.out.println("調用dao");
        bookdao.insert();

    }

}
package com.spring.annotation;

import org.springframework.stereotype.Repository;

@Repository("BookDaoImpl")
public class BookDaoImpl implements BookDao {

    @Override
    public void insert() {
        System.out.println("插入數據");


    }

}
  • 靜態工廠注入
    常用於整合其他框架 ,靜態工廠所有方法必須是static的
package com.spring.staticFactory;

public class BookServiceImpl implements BookService {
    @Override
    public void insert() {
        System.out.println("靜態工廠實例化");
    }
}
package com.spring.staticFactory;

public class MyBeanFactory {

    public static BookService getServiceInstance() {
        return new BookServiceImpl();

    }

}
<!-- facory-method 靜態方法名稱 -->
    <bean id="BookService" class="com.spring.staticFactory.MyBeanFactory"
        factory-method="getServiceInstance"></bean
  • 實例工廠注入
    實例工廠所有的方法都是非靜態的
package com.spring.InstanFactory;

public class MyBeanFactory {
    public BookService getServiceInstance() {
        return new BookServiceImpl();

    }

}
<!-- 創建工廠實例 factory-bean 確定工廠實例 factory-method 確定普通方法 -->
    <bean id="MyBeanFactory" class="com.spring.InstanFactory.MyBeanFactory"></bean>
    <bean id="BookService" factory-bean="MyBeanFactory"
        factory-method="getServiceInstance"></bean>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章