IOC和DI

网上概念很多,感兴趣可以去搜一搜,在这里我就给个比喻:

IOC:以前我们买东西都要去商店买,用了IOC之后,我们只要在门口放个箱子, Spring就会给我相应商品,ಠᴗಠ

举个例子

  1. class A{}  
  2.     
  3. class B{  
  4.     private A a;  
  5.     public void setA(A a){  
  6.          this.a=a;  
  7.     }  
  8. }  

在传统的写法中,在创建A B对象,他们之间的关联需要我们手动设置,b.set(a),而在使用Spring之后,这一步就不需要了,由框架为我们设置相关内容

IOC的发展:

  1. 分离接口与实现
  2. 工厂设计模式
  3. 翻转控制

基于XML配置bean

<bean>中的class属性填入bean的全类名,通过反射方式在IOC容器中创建Bean,所以要求Bean中必须有无参的构造函数。

属性id用来表示容器中的id,id唯一

ApplicationContext代表IOC容器,实际这是一个接口。在SpringIOC容器读取Bean配置创建Bean实例之前,必须对它进行实例化,只有在容器实例化后,才可以从IOC容器里获取Bean实例并使用。

Spring为我们提供了两种类型的IOC容器实现:

  1. BeanFactory:IOC容器的基本实现
  2. ApplicationContext:提供了更多高级特性,是BeanFactory的子接口
  3. ClassPathXmlApplicationContext是ApplicationContext的实现类

BeanFactory是Spring的基础设施,面向Spring本身,ApplicationContext面向Spring框架开者,几乎所有应用场合都直接使用ApplicationContext而非底层BeanFactory,当然,无论使用何种方式,配置文件都相同。

ApplicationContext的主要实现类:

ClassPathXmlApplicationContext:从类路径下加载配置文件

FileSystemXmlApplicationContext:从文件系统中加载配置文件

ConfigurableApplicationContext扩展于ApplicationContext,新增两个主要方法:refresh()和close(),让ApplicationContext具有启动/刷新和关闭上下文的功能。

ApplicationContext在初始化上下文时就实例化所有单例的Bean。

WebApplication是专门为WEB应用而准备的,它允许从相对于WEB根目录的路径中完成初始化工作。

接下来说说getBean()这个方法,getBean()这个方法实际是存在在BeanFactory这个接口中,我们看看下面这张截图:

非常多个重载,我们在之前的例子中也可以这么写,利用类型返回IOC容器:

HelloWorld helloWorld = ctx.getBean(HelloWorld.class);

也是没问题的,这样有缺点吗?

加入我在配置文件中创建了两个<bean>并且都是HelloWorld的JavaBean,这样Spring就识别不出是哪一个<bean>了,因此不推荐这么写,推荐通过id名返回IOC容器,创建对象

HelloWorld helloWorld = (HelloWorld) ctx.getBean("helloWorld");

依赖注入

  1. 属性注入
  2. 构造器注入
  3. 工厂方法注入(很少使用,不推荐)

先说说最常用的属性注入,这个属性注入就是我们先前HelloWorld中使用的方法,通过setter方法注入Bean的属性值或依赖的对象,通过<property>标签,使用name指定Bean的属性名称,value属性指定属性值

<property name="name" value="World"></property>

接着说构造方法注入,通过构造方法注入Bean的属性值或依赖对象,它保证了Bean实例在实例化后就可以使用。

构造器注入需要用<constructor-arg>元素里声明属性,注意<constructor-arg>中没有name属性

我们新创建Car类作为测试:

  1. public class Car {  
  2.     private String brand;  
  3.     private String corp;  
  4.     private Integer price;  
  5.     private Integer maxSpeed;  
  6.     
  7.     public Car(String brand, String corp, Integer price) {  
  8.         this.brand = brand;  
  9.         this.corp = corp;  
  10.         this.price = price;  
  11.     }  
  12.     
  13.     @Override  
  14.     public String toString() {  
  15.         return "Car{" +  
  16.                 "brand='" + brand + '\'' +  
  17.                 ", corp='" + corp + '\'' +  
  18.                 ", price=" + price +  
  19.                 ", maxSpeed=" + maxSpeed +  
  20.                 '}';  
  21.     }  
  22. }  

这里故意在构造器里少放一个字段,来到配置文件

  1. <bean id="car" class="com.figsprite.bean.Car">  
  2.     <constructor-arg value="奥迪"></constructor-arg>  
  3.     <constructor-arg value="上海"/>  
  4.     <constructor-arg value="3000000"/>  
  5. </bean>  

在Main中输入测试代码:

  1. Car car = (Car)ctx.getBean("car");  
  2. System.out.println(car.toString());  

看结果,很有意思的是我已经将HelloWorld.java相关的代码注释了,可是还是出现了我们上一讲所写的注释,这就应证了之前所说的:

ApplicationContext在初始化上下文时就实例化所有单例的Bean。

接下来再配置一个构造器:

  1. public Car(String brand, String corp, int price, int maxSpeed) {  
  2.     this.brand = brand;  
  3.     this.corp = corp;  
  4.     this.price = price;  
  5.     this.maxSpeed = maxSpeed;  
  6. }  

    来到配置文件:

  7. <bean id="car2" class="com.figsprite.bean.Car">  
  8.     <constructor-arg value="海南马自达"></constructor-arg>  
  9.     <constructor-arg value="上海"/>  
  10.     <constructor-arg value="3000000"/>  
  11.     <constructor-arg value="78"/>  
  12. </bean>  
  1. Car car2 = (Car)ctx.getBean("car2");  
  2. System.out.println(car2.toString());  

发现没什么问题,但如果构造器是品牌名、场地、最大速度,Spring能识别出来吗?

先将price改成double,否则不满足重载规则,写上新的配置文件

  1. <bean id="car2" class="com.figsprite.bean.Car">  
  2.     <constructor-arg value="海南马自达"></constructor-arg>  
  3.     <constructor-arg value="上海"/>  
  4.     <constructor-arg value="78"/>  
  5. </bean>  

发现并没有得到我们想要的,如何解决这个问题呢?

此时需要用到type属性,

  1. <bean id="car" class="com.figsprite.bean.Car">  
  2.     <constructor-arg value="奥迪" type="java.lang.String"></constructor-arg>  
  3.     <constructor-arg value="上海" type="java.lang.String"/>  
  4.     <constructor-arg value="3000000" type="double"/>  
  5. </bean>  
  6.     
  7. <bean id="car2" class="com.figsprite.bean.Car">  
  8. <constructor-arg value="海南马自达" type="java.lang.String"></constructor-arg>  
  9. <constructor-arg value="上海" type="java.lang.String"/>  
  10. <constructor-arg value="78" type="int"/>  
  11. </bean>  

嗯,是我们想要的了,使用构造器注入属性值可以指定参数的位置和参数类型,这里还有一个index的属性,用于不按构造器参数顺序写标签时使用。大家可以自行尝试一下

Spring的Bean配置的更多相关文章

  1. 【转】Spring学习---Bean配置的三种方式(XML、注解、Java类)介绍与对比

    [原文]https://www.toutiao.com/i6594205115605844493/ Spring学习Bean配置的三种方式(XML.注解.Java类)介绍与对比 本文将详细介绍Spri ...

  2. spring中bean配置和bean注入

    1 bean与spring容器的关系 Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载.实例化Bean ...

  3. spring中bean配置和注入场景分析

    bean与spring容器的关系 Bean配置信息定义了Bean的实现及依赖关系,Spring容器根据各种形式的Bean配置信息在容器内部建立Bean定义注册表,然后根据注册表加载.实例化Bean,并 ...

  4. Spring 梳理-bean配置与装配

    1       bean配置与装配 1.1      bean在XML文件中进行显示配置并装配 1.2      bean在JavaConfig中显示配置并装配 1.2.1  优点:类型是安全的,编译 ...

  5. 关于spring中bean配置的几件小事

    一.IOC和DI 1.IOC(Inversion of Control) 其思想是反转资源获取的方向.传统的资源查找方式要求组件向容器发起请求查找资源,作为回应,容器适时的返回资源:而应用了IOC之后 ...

  6. 使用@Configuration注解来代替Spring的bean配置

    下面是一个典型的Spring配置文件(application-config.xml): <beans> <bean id="orderService" class ...

  7. Spring中bean的配置

    先从IOC说起,这个概念其实是从我们平常new一个对象的对立面来说的,我们平常使用对象的时候,一般都是直接使用关键字类new一个对象,那这样有什么坏处呢?其实很显然的,使用new那么就表示当前模块已经 ...

  8. Spring之Bean的配置方式

    在博客中为了演示容器Bean实例化时暴露出的几个接口,将UserBean配置在XML中,其实常见的Bean的配置有3种.1.基于xml配置Bean 2.使用注解定义Bean 3.基于java类提供Be ...

  9. spring中bean的配置详解--定义parent

    在工作中碰到了好多的配置文件,具体来说是spring 中bean配置的parent的配置,搞的我一头雾水,仔细看一下spring中有关bean的配置,剖析一下,具体什么含义! 一.Spring IoC ...

随机推荐

  1. CF 331 E. Biologist

    CF 331 E. Biologist 题目描述 题目大意:有\(n\)个点,初始时每个点为黑色或者白色,你可以花费\(v_i\)的代价将一个点反色.然后你有许多计划,每个计划要求一个点集中的所有点为 ...

  2. python六十八课——网络编程之UDP协议

    1.1 概述 UDP是无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接.简单来说,当一台计算机向另外一台计算机发送数据时,发送端不会确认接收端是否存在,就会发出数据,同样接收端在收到 ...

  3. UVA11059-Maximum Product(动态规划)

    Problem UVA11059-Maximum Product Accept:4769  Submit:38713 Time Limit: 3000 mSec  Problem Descriptio ...

  4. 转://Oracle 高可用技术与云基础架构

    众所周知Oracle云基础架构已经在越来越多的行业里应用.大家了解云基础架构是如何演进的嘛?可能有人会说Oracle高可用技术是组成云架构的基础,那它们的关系是怎么样的?大家又了解Oracle高可用技 ...

  5. Scala主构造器参数是否升级为成员与是否有get/set

    1:主构造器前面添加val/var 关键字则升级为类成员,否则只是构造器中的一个参数而已. 2:private 修饰get/set方法权限,private var/val 成员变量,则有get/set ...

  6. P1217 [USACO1.5]回文质数 Prime Palindromes(技巧+暴力枚举+线性筛)

    技巧:就是偶数位的回文数字一定不是质数---------证明:奇数位之和sum1==偶数位之和sum2的数字可以被11整除.(11除外,这是一个坑点) 最高位,最低位必须是 1, 3, 7, 9 暴力 ...

  7. Docker下载mysql镜像

    1.使用命令查看mysql NAME DESCRIPTION STARS OFFICIAL AUTOMATED mysql MySQL [OK] mariadb MariaDB [OK] mysql/ ...

  8. docker 5 docker-阿里云加速配置

    阿里云加速配置 鉴于国内网络问题,后续拉取docker镜像十分缓慢,我们可以配置加速器来解决. 1.阿里云地址  https://dev.aliyun.com/ 如果你想注册,可以注册个账号. 不想注 ...

  9. docker 1 为什么要使用docker

    一款产品从开发到上线,从操作系统,到运行环境,再到应用配置.做为开发+运维之间的协作,我们需要关心很多东西,这也就是很多互联网公司都不得不面对的问题,特别是各种版本的迭代后,不同版本环境的兼容,对运维 ...

  10. Luogu4983 忘情

    Luogu4983 忘情 定义序列 \(x_1,\ x_2,\ \cdots,\ x_n\) 的值为 \(\frac{((\displaystyle\sum_{k=1}^nx_k\times \bar ...