Spring的依赖注入

一、 Spring中的依赖注入

依赖注入:Dependency Injection
IOC的作用:

  降低程序间的依赖关系(耦合)
  依赖关系的管理
  以后都交给spring来维护
  在当前需要用到其他类的对象 由spring为我们提供 我们只需要在配置文件中说明
  依赖关系的维护:
  就称为依赖注入
   依赖注入
   能注入的数据有三类:
      基本类型和String
      其他bean类型(在配置文件中 或注解配置过得属性)
      复杂类型 集合类型

二、注入方式 三种

1.构造函数注入
构造函数注入 实际开发很少用
使用的标签 constructor-arg
标签出现的位置:bean标签的内部
标签中的属性
type:用于指定要注入的数据类型 该数据类型也是构造函数中某个或某些数据类型 无法独立实现功能
index:用于指定要注入的数据给构造函数中指定索引位置的参数赋值 索引的位置是从0开始 可以独立 实现功能
name:用于指定给构造函数中指定名称的参数赋值 常用的是name
=以上三个用于指定给构造函数中那个参数赋值========
value:用于提供基本类型和string类型的数据
ref:用于指定其他的bean类型数据 它指的就是在spring的ioc核心容器中出现过的bean对象

优势:在获取bean对象时,注入数据是必须的操作 否则对象无法创建成功
 缺点:改变了bean对象的实例化方式,使我们在创建对象时 如果用不到这些数据 也必须提供
   <bean id="accountService" class="com.rpf.service.impl.AccountServiceImpl">
      <constructor-arg name="name" value="test"></constructor-arg>
      <constructor-arg name="age" value="18"></constructor-arg>
      <constructor-arg name="birthday" ref="now"></constructor-arg>
    </bean>
  <!--配置一个日期对象-->
  <bean id="now" class="java.util.Date"></bean>

业务实现类

  //如果是经常变化的数据 并不适用于注入的方式
      private String name;
      private Integer age;
      private Date birthday;

      public AccountServiceImpl(String name,Integer age,Date birthday){
        this.name=name;
         this.age=age;
         this.birthday=birthday;
      }
    public AccountServiceImpl(){
        System.out.println("对象创建了");
    }

    public void  saveAccount(){
        System.out.println("service 中的save执行了"+name+","+age+","+birthday);
    }

测试控制层调用

    AccountService as = (AccountService)ac.getBean("accountService");
        as.saveAccount();

2.使用set方法提供
bean.xml

   <!--set方法注入             更常用的方式
     涉及的标签property
     出现的位置bean标签内部
   标签的属性
    name:用于指定注入时所需要的用的set方法名称             常用的是name
    value:用于提供基本类型和string类型的数据
    ref:用于指定其他的bean类型数据 它指的就是在spring的ioc核心容器中出现过的bean对象
    优势:创建对象时没有明确的限制 可以直接使用构造函数
    弊端:如果某个成员必须有值 则获取对象时有可能set方法没有执行
  -->
  <bean id="accountService2" class="com.rpf.service.impl.AccountServiceImpl2">
     <property name="name" value="test"></property>
     <property name="age" value="21"></property>
     <property name="birthday" ref="now"></property>
  </bean>

业务实现类

      private String name;
      private Integer age;
      private Date birthday;

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

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

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public void  saveAccount(){
        System.out.println("service 中的save执行了"+name+","+age+","+birthday);
    }

}

测试控制层调用

 AccountService as = (AccountService)ac.getBean("accountService2");
        as.saveAccount();

在这里插入图片描述

3.复杂类型注入
bean.xml

    <!--复杂类型的注入/集合类型的注入
             用于给List结构集合注入的标签:
              list array set(可以互换)
       用于给map集合注入的标签有:
           结构相同标签可以互换
             map props(可以互换)
   -->
<bean id="accountService3" class="com.rpf.service.impl.AccountServiceImpl3">
    <property name="myStrs">
        <array>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </array>
    </property>
    <property name="myList">
        <list>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </list>
    </property>
    <property name="mySet">
        <set>
            <value>AAA</value>
            <value>BBB</value>
            <value>CCC</value>
        </set>
    </property>
    <property name="myMap">
        <props>
            <prop key="testD">AAA</prop>
            <prop key="testE">DDD</prop>
        </props>

    </property>
    <property name="myProps">
        <map>
            <entry key="testA" value="AAA"></entry>
            <entry key="testB">
                <value>BBB</value>
            </entry>
            <entry key="testC" value="CCC"></entry>
        </map>
    </property>
</bean>

业务实现类

private String[] myStrs;
private List<String> myList;
private Set<String> mySet;
private Map<String,String> myMap;
private Properties myProps;

public void setMyStrs(String[] myStrs) {
    this.myStrs = myStrs;
}

public void setMyList(List<String> myList) {
    this.myList = myList;
}

public void setMySet(Set<String> mySet) {
    this.mySet = mySet;
}

public void setMyMap(Map<String, String> myMap) {
    this.myMap = myMap;
}

public void setMyProps(Properties myProps) {
    this.myProps = myProps;
}

public void  saveAccount(){
    System.out.println(Arrays.toString(myStrs));
    System.out.println(myList);
    System.out.println(mySet);
    System.out.println(myMap);
    System.out.println(myProps);
}

测试

AccountService as = (AccountService)ac.getBean("accountService3");
     as.saveAccount();

在这里插入图片描述

三、扩展方式注入

扩展一个c命名空间注入个P命名空间注入

官方文档提到的注入方式
在这里插入图片描述

使用命名空间注入方式Spring的xml文件必须要导入约束

<beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:p="http://www.springframework.org/schema/p"
               xmlns:c="http://www.springframework.org/schema/c"
               xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

</beans>

我们创建一个实体类User用于测试

package com.rpf.pojo;

/**
 * @create: 2021/6/18
 * @author: Tony Stark
 */
public class User {
    private String name;
    private int age;

    public String getName() {
        return name;
    }

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

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

    public int getAge() {
        return age;
    }

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

测试P命名空间注入的方式

编写xml文件注入

<beans xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xmlns:p="http://www.springframework.org/schema/p"
               xmlns:c="http://www.springframework.org/schema/c"
               xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

<!--p命名空间注入可以直接注入属性的值-->
<bean id="user" class="com.rpf.pojo.User" p:name="飞飞" p:age="22"></bean>

</beans>

这里在类的全路径之后 打 p:就会提示我们实体类中的信息 选中赋值即可
在这里插入图片描述
测试

 @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");

        User user = context.getBean("user", User.class);

        System.out.println(user);

    }

结果如下
在这里插入图片描述
注入成功!!!!

测试C命名空间注入的方式

xml配置文件配置

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:c="http://www.springframework.org/schema/c"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
    http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--c命名空间注入通过构造器注入 construct-args  构造器参数-->
    <bean id="user2" class="com.rpf.pojo.User" c:age="18" c:name="飞飞"></bean>

</beans>

在类的全限定路径后打C:就会提示我们如下信息
在这里插入图片描述

由于我们的C命名空间注入方式是依靠构造函数注入 所以我们必须在实体类加入有参无参构造

package com.rpf.pojo;

/**
 * @create: 2021/6/18
 * @author: Tony Stark
 */
public class User {
    private String name;
    private int age;

    public User() {
    }

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

    public String getName() {
        return name;
    }

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

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

    public int getAge() {
        return age;
    }

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

测试注入是否成功

  @Test
    public void test3(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");

        User user = context.getBean("user2", User.class);

        System.out.println(user);

    }

结果如下:
在这里插入图片描述

注入成功!!!

最后附上测试命名空间命名方式的maven依赖和完整配置文件 与实体类

<dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>5.3.5</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
package com.rpf.pojo;

/**
 * @create: 2021/6/18
 * @author: Tony Stark
 */
public class User {
    private String name;
    private int age;

    public User() {
    }

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

    public String getName() {
        return name;
    }

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

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

    public int getAge() {
        return age;
    }

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值