微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

【死磕Spring】| Spring IoC依赖注入:Spring提供了哪些依赖注入模式和类型呢?

文章目录

Spring IoC依赖注入:Spring提供了哪些依赖注入模式和类型呢?

00、代码实现参考包的路径

1、context-dependency-injection.xml

2、DependencyInjectionDemo.java

3、其他同上节引用一致

01、根据Bean名称注入

  • 首先需要创建一个UserRepository,用于存储依赖注入的Bean对象

    • import com.markus.spring.ioc.dependency.domain.User;
      import org.springframework.beans.factory.beanfactory;
      import org.springframework.beans.factory.ObjectFactory;
      import org.springframework.context.ApplicationContext;
      import java.util.Collection;
      /**
       * @author 14222
       * @date 2021-02-02 22:10
       */
      public class UserRepository {
          private Collection<User> users;
      
          public Collection<User> getUsers() {
              return users;
          }
      
          public void setUsers(Collection<User> users) {
              this.users = users;
          }
      }
      
  • xml文件配置,将users集合类型注入到UserRepository当中去

    • <?xml version="1.0" encoding="UTF-8"?>
      <beans
              xmlns="http://www.springframework.org/schema/beans"
              xmlns:context="http://www.springframework.org/schema/context"
              xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
              xsi:schemaLocation="http://www.springframework.org/schema/beans
              https://www.springframework.org/schema/beans/spring-beans.xsd
              http://www.springframework.org/schema/context
              https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/util https://www.springframework.org/schema/util/spring-util.xsd">
          <import resource="context-dependency-lookup.xml"/>
          <bean id="userRepository" class="com.markus.spring.ioc.dependency.repository.UserRepository">
              <property name="users">
                  <util:list>
                      <ref bean="user"/>
                      <ref bean="super"/>
                  </util:list>
              </property>
          </bean>
      </beans>
      
  • 一个查看注入是否成功的Demo

    • import com.markus.spring.ioc.dependency.repository.UserRepository;
      import org.springframework.beans.factory.beanfactory;
      import org.springframework.beans.factory.ObjectFactory;
      import org.springframework.beans.factory.support.DefaultListablebeanfactory;
      import org.springframework.context.ApplicationContext;
      import org.springframework.context.support.ClasspathXmlApplicationContext;
      import org.springframework.core.env.Environment;
      /**
       * @author 14222
       * @date 2021-02-02 22:07
       */
      public class DependencyInjectionDemo {
          public static void main(String[] args) {
              //1.配置 xml 文件
              //2.启动 Spring 应用上下文
              beanfactory beanfactory = new ClasspathXmlApplicationContext("classpath:/meta-inf/context-dependency-injection.xml");
              UserRepository repository = beanfactory.getBean(UserRepository.class);
              System.out.println(repository.getUsers());
          }
      }
      
    • 这里有个小的知识点:users集合中User实例的顺序问题,这取决于xml文件里配置的先后顺序,比如我将xml文件里的顺序调换一下,结果会是下图所示

    • 所以,会有这样一个问题:注入容器的Bean是否可以调换顺序,答案是否定的,一旦在xml文件中的顺序确定,那么就会固定,不能调换!

02、根据Bean类型注入

01章节讲述的注入方式其实是属于硬编码方式,如果想要注入多个user对象,那么需要继续写代码注入相应的Bean。接下来,我们接触一个新的 Bean便签里的元信息:autowire。

该小结解释的是根据Bean类型注入,所以我们选择byType;

  • 代码演示:

    • 在01小结的基础上,只需要改变xml文件中的信息即可

    • <bean id="userRepository" class="com.markus.spring.ioc.dependency.repository.UserRepository"
            autowire="byType">
          <!--        <property name="users">-->
          <!--            <util:list>-->
          <!--                <ref bean="user"/>-->
          <!--                <ref bean="super"/>-->
          <!--            </util:list>-->
          <!--        </property>-->
      </bean>
      

03、注入非Bean对象(依赖)

上两个小节讲述了 通过硬编码或者自动注入的方式注入Bean对象,那接下来我们尝试注入一下beanfactory,更新我们的UserRepository

public class UserRepository {
    private Collection<User> users;

    private beanfactory beanfactory;

    public beanfactory getbeanfactory() {
        return beanfactory;
    }
    public void setbeanfactory(beanfactory beanfactory) {
        this.beanfactory = beanfactory;
    }
    public Collection<User> getUsers() {
        return users;
    }
    public void setUsers(Collection<User> users) {
        this.users = users;
    }
}
  • 代码演示:

    • public class DependencyInjectionDemo {
          public static void main(String[] args) {
              //1.配置 xml 文件
              //2.启动 Spring 应用上下文
              beanfactory beanfactory = new ClasspathXmlApplicationContext("classpath:/meta-inf/context-dependency-injection.xml");
              UserRepository repository = beanfactory.getBean(UserRepository.class);
      //        System.out.println(repository.getUsers());
              System.out.println(repository.getbeanfactory() == beanfactory);
          }
      }
      
    • 按照我们想的,控制台打印的应该是 True,但实际上是false。那到底是为什么呢?我们先更新下Demo代码,将UserRepository中注入的beanfactory类型打印出来

    • 先留着这个疑问,接下来,我们再尝试向UserRepository中注入一个ObjectFactory,也就是通过类型注入时采用延迟注入。

    • public class UserRepository {
          XXXX;
          private ObjectFactory<ApplicationContext> objectFactory;
      
          public ObjectFactory<ApplicationContext> getobjectFactory() {
              return objectFactory;
          }
          public void setobjectFactory(ObjectFactory<ApplicationContext> objectFactory) {
              this.objectFactory = objectFactory;
          }
          XXXX;
      }
      
    • 我们来看下这个注入的上下文Bean和beanfactory是否是同一个实例对象;

    • 答案是肯定的。也就是说 真正注入的beanfactory的实例对象其实就是引入的外部依赖,而如果我们采用依赖查找的方式去查找beanfactory时,是会出现异常的,我们来实验一遍。

    • 继续更新Demo代码

    • public class DependencyInjectionDemo {
          public static void main(String[] args) {
              //1.配置 xml 文件
              //2.启动 Spring 应用上下文
              beanfactory beanfactory = new ClasspathXmlApplicationContext("classpath:/meta-inf/context-dependency-injection.xml");
              System.out.println(beanfactory.getBean(beanfactory.class));
          }
      }
      
    • 所以,该实验验证我们上面的想法,真正注入到IoC容器的beanfactory实例其实是外部依赖,而非Bean对象。而我们上面留有的那个疑问:注入的beanfactory和我们使用的beanfactory并非是同一个

  • 看到这里,也许大家会有一个疑问?IoC容器中注入的对象除了Bean对象,还有外部依赖,那Spring IoC依赖来源到底在哪呢?这个疑问我们在下节会做出解释,欢迎大家继续来跟着我探究,依赖注入和查找的对象到底来自于哪里?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。