spring_2_依賴注入

一.依賴注入

1.通過屬性標籤property注入

property標籤

屬性: name:屬性名 value:屬性值 ref:依賴的對象id

測試代碼:

public class Drink {

    private String name;

    private String sugar;

    private float price;

    public String getName() {
        return name;
    }

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

    public String getSugar() {
        return sugar;
    }

    public void setSugar(String sugar) {
        this.sugar = sugar;
    }

    public float getPrice() {
        return price;
    }

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

    public Drink() {
        System.out.println("創建一杯飲料");
    }
}
<bean id="drink_01" class="com.test.pojo.Drink" >
    <property name="name" value="西瓜汁" />
    <property name="price" value="18" />
    <property name="sugar" value="半糖" />
</bean>

2.通過構造函數注入

constructor-arg 標籤

屬性: name:構造函數的參數名

​ value:傳進去的值

​ ref:參數依賴的對象

​ index:參數類型和參數個數都相同,但順序不同的時候,可以用index來設置順序 從0開始

​ type: 參數個數相同,參數名也相同,但類型不同 ,可以用type來設置類型

測試代碼:

Drink類中添加構造函數:

package com.test.pojo;

public class Drink {

    private String name;

    private String sugar;

    private float price;

    public String getName() {
        return name;
    }

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

    public String getSugar() {
        return sugar;
    }

    public void setSugar(String sugar) {
        this.sugar = sugar;
    }

    public float getPrice() {
        return price;
    }

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

    public Drink() {
        System.out.println("創建一杯飲料");
    }

    public Drink(String name) {
        this.name = name;
    }

    public Drink(String name, String sugar) {
        this.name = name;
        this.sugar = sugar;
    }

    public Drink(String name, float sugar) {
        this.name = name;
        this.price = sugar;
    }

    public Drink(float sugar,String name) {
        this.name = name;
        this.price = sugar;
    }

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

配置文件中調用不同構造函數測試:

<bean id="drink_02" class="com.test.pojo.Drink">
    <constructor-arg name="name" value="蘋果汁" />
</bean>

<!--
構造函數的參數個數相同 參數類型也相同 但順序不同  需要用index來指定參數的順序
index 指的是參數的順序

-->
<!-- 如果構造函數的參數個數相同 參數類型不同 則需要指定參數類型
    基本類型 直接用基本類型
 -->

<bean id="drink_02" class="com.test.pojo.Drink" >
         <constructor-arg name="name" value="奶茶" />
 </bean>

 <bean id="drink_03" class="com.test.pojo.Drink" >
         <constructor-arg name="name" value="珍珠奶茶" index="0" />
         <constructor-arg name="sugar" value="13" type="float" index="1" />
 </bean>


3.p空間注入

1)引入p空間

​ xmlns:p="http://www.springframework.org/schema/p"

<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"
       xmlns:p="http://www.springframework.org/schema/p"       //加在xmlns屬性中
       xsi:schemaLocation="http://www.springframework.org/schema/beans

2)使用

​ p:屬性名=屬性值

<bean id="drink_01" class="com.test.pojo.Drink"  p:name="珍珠奶茶"
      p:price="28"  p:sugar="半糖"  />


4.複雜類型注入

​ 對象 ref

​ 數組

 <array>
   <value>/<ref>
 </array>

list

 <list>
  <value>/<ref>
 </list>

map

 <map>
       <entry key="" value=""/value-ref=""></entry>
 </map>

properties

<props>

  <prop key="">value</prop>

</props>

測試代碼:

1)定義一個類,屬性是各種複雜類型

public class AA {
      
    private int[] arr;

    private Drink[] drinkArr;

    private List<String> stringList;

    private List<Drink> drinkList;

    private Map<String,Drink> map;

    private Properties properties;
        
        。。。
       set和get方法
       --
       }       
  1. 注入
<bean id="drink_01" class="com.test.pojo.Drink" />
    <bean id="drink_02" class="com.test.pojo.Drink" />

    <bean id="aa" class="com.test.pojo.AA">
        <property name="arr">
            <array>
                <value>1</value>
                <value>2</value>
                <value>3</value>
            </array>
        </property>

        <property name="drinkArr">
            <array>
                <ref bean="drink_01" />
                <ref bean="drink_02" />
            </array>
        </property>

        <property name="stringList">
            <list>
                <value>tom</value>
                <value>jack</value>
                <value>tony</value>
            </list>
        </property>

        <property name="drinkList">
            <list>
                <ref bean="drink_01" />
                <ref bean="drink_02" />
            </list>
        </property>

        <property name="map">
            <map>
                <entry key="first" value-ref="drink_01" />
                <entry key="second" value-ref="drink_02"  />
            </map>
        </property>

        <property name="properties">
            <props>
                <prop key="driver" >com.mysql.jdbc.Driver</prop>
                <prop key="url" >jdbc:mysql://localhost:3306/taobao</prop>
            </props>
        </property>

    </bean>

5.spel 表達式語言 注入

比如如果只是引入對象中的某個屬性 可以 用#{}

<bean id="outSeller_05" class="com.test.pojo.OutSeller" p:type="餓了麼"
          p:drink-ref="drink_05" />
          
<bean id="outSeller_06" class="com.test.pojo.OutSeller">
      <property name="type" value="#{outSeller_05.type}" />
       <property name="drink" ref="drink_05" />
</bean>

二.SPEL

spel:spring 表達式語言 ,Spring Expression Language(縮寫爲SpEL)是一種強大的表達式語言。在Spring產品組合中,它是表達式計算的基礎。它支持在運行時查詢和操作對象圖,它可以與基於XML和基於註解的Spring配置還有bean定義一起使用。由於它能夠在運行時動態分配值,因此可以爲我們節省大量Java代碼

需要的jar包

<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>4.3.18.RELEASE</version>
</dependency>

1.定義測試案例

​ 自定義類: function類

package com.test.spel;

import com.test.pojo.Drink;

import java.util.ArrayList;
import java.util.List;

public class TestSpel {

  //成員方法 先創建對象 再調用對象中的方法
    // <bean id="testSpel" class="com.test.spel.TestSpel"/>
    //#{testSpel.getDrinkList()}
    public List<Drink> getDrinkList()
    {
        List<Drink> list=new ArrayList<Drink>();

        list.add(new Drink("奶茶"));

        list.add(new Drink("橙汁"));

        return list;

    }

 //靜態方法 可以直接用類名訪問 #     {T(com.test.spel.TestSpel).getDrinkList2()}
    public static List<Drink> getDrinkList2()
    {
        List<Drink> list=new ArrayList<Drink>();

        list.add(new Drink("奶茶2"));

        list.add(new Drink("橙汁2"));

        return list;

    }

}

2.在 spring的配置文件中的使用

​ 訪問成員屬性

#{對象.屬性名}

​ 訪問靜態方法

#{T(包名.類名).方法名([參數])}

​ 訪問成員方法

#{對象.方法名()}

  <bean id="testSpel" class="com.test.spel.TestSpel"/>

  <!-- 訪問成員方法 -->
  <bean id="aa" class="com.test.pojo.AA">

        <property name="num" value="#{3*4}" />

        <property name="drinkList" value="#{testSpel.getDrinkList()}" />

  </bean>

  <!-- 訪問靜態方法 -->
  <bean id="aa2" class="com.test.pojo.AA">

        <property name="drinkList" value="#{T(com.test.spel.TestSpel).getDrinkList2()}" />

  </bean>

三.註解方式

使用註解的方式完成IOC

1.配置註解掃描

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

    <!-- 開啓註解掃描
        掃描com.test包以及所有子包中的文件
    -->
    <context:component-scan
            base-package="com.test" />

</beans>

2.常用的註解

2.1用來創建對象的註解

@Component

​ 創建一個對象(組件)

@Service

​ 創建service層對象

@Controller

​ 創建控制層對象

//默認會創建一個DrinkService的對象 對象的名字爲drinkService (類名的首字母小寫)
@Service
//也可以設置自己制定的對象名
@Service("自己制定的對象名")
public class DrinkService implements IDrinkService {
}

2.2用來注入的註解

2.2.1注入對象的方式1

@Autowired

​ 根據類型自動注入

@Qualifier("對象名")

​ 如果滿足自動注入的對象有多個,可以通過@Qualifier()設置具體的對象名

//自動注入
@Autowired
//指定注入的對象(如果滿足注入對象有多個的時候)
@Qualifier("oracleDrinkDao")
private IDrinkDao drinkDao;

public IDrinkDao getDrinkDao() {
    return drinkDao;
}

//也可以在set方法上設置自動注入
public void setDrinkDao(IDrinkDao drinkDao) {
   this.drinkDao = drinkDao;
}

2.2.2注入對象的方式2

@Resource(name="對象名")

​ 根據對象名注入,作用相當於@Autowired+@Qualifier("對象名")

//自動注入方式2
@Resource(name="oracleDrinkDao")
private IDrinkDao drinkDao;

public IDrinkDao getDrinkDao() {
    return drinkDao;
}

public void setDrinkDao(IDrinkDao drinkDao) {
   this.drinkDao = drinkDao;
}

2.2.3注入普通值

​ **@Value("數值")**相當於 @Value(value="數值") ​

@Component
public class Drink {

    @Value("橙汁")
    private String name;

    @Value("半糖")
    private String sugar;

    @Value("18")
    private float price;

2.3其它註解

@Scope

​ 設置對象的作用域,默認是單例,可以設置爲多例模式@Scope(scopeName="prototype")

@Lazy

​ 設置是否懶加載,默認是非懶加載,設置 @Lazy代表懶加載,前提是單例模式

//可以設置對象作用域
//默認是單例
//可以設置爲多例
//@Scope(scopeName ="prototype" )
//設置是否是懶加載  默認是false 前提是單例
@Lazy
@Component
public class Drink {

    @Value("橙汁")
    private String name;
}

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