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;
}

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