【死磕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依赖来源到底在哪呢?这个疑问我们在下节会做出解释,欢迎大家继续来跟着我探究,依赖注入和查找的对象到底来自于哪里?

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值