Spring-IOC实现【01-XML配置方式】

简介: IOC概念 IoC控制反转(IoC,Inversion of Control), 是一个概念,是一种思想。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。把对象的创建、初始化、 销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。


IOC概念

   IoC控制反转(IoC,Inversion of Control),

   是一个概念,是一种思想。控制反转就是对对象控制权的转移,从程序代码本身反转到了外部容器。把对象的创建、初始化、

   销毁等工作交给spring容器来做。由spring容器控制对象的生命周期。

   DI依赖注入:Dependency Injection。

   依赖注入DI是指程序运行过程中,若需要调用另一个对象协助时,无须在代码中创建被调用者,而是依赖于外部容器,由外部容器创建后传递给程序。依赖注入是目前最优秀的解耦方式。依赖注入让Spring的Bean之间以配置文件的方式组织在一起,而不是以硬编码的方式耦合在一起的。

   IoC与DI的关系

   IoC是一个概念,是一种思想,其实现方式多种多样。当前比较流行的实现方式之一是DI。

IOC:控制反转, 将 new 的过程交给spring容器去处理

XML配置方式

一、普通构造注入

   创建Spring工程

   创建Spring的XML配置文件applicationContext.xml

image.png

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd">
 </beans>


   在Spring的配置文件中声明User Bean:

image.png

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:schemaLocation="http://www.springframework.org/schema/beans 
 http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!-- 在容器中注册UserBean -->
  <bean class="com.dpb.javabean.UserBean" id="userBean"></bean>
 </beans>

 所谓的声明,就是将自己的信息告诉Spring容器,例如id和class,Spring容器根据class,通过反射(默认使用的是无参构造方法)就可以创建一个名为user1的User对象。

   初始化容器

public static void main(String[] args) {
    //初始化Spring容器,当Spring容器初始化时,会自动加载配置文件,然后根据配置文件中的内容初始化Bean
    ApplicationContext ac = 
        new ClassPathXmlApplicationContext("application.xml");
   }

image.png

5. 初识化Spring容器之后,可以看到User已经被创建出来了。

注意:上面这种初始化方式,要求User必须有一个无参构造方法,如果没有无参构造方法,会抛出如下异常:

image.png

6.通过调用容器中的getBean方法可以获取Spring容器中的对象

public static void main(String[] args) {
    //初始化Spring容器,当Spring容器初始化时,会自动加载配置文件,然后根据配置文件中的内容初始化Bean
    ApplicationContext ac = 
        new ClassPathXmlApplicationContext("application.xml");
    // 去Spring容器中获取一个UserBean对象
    UserBean user = ac.getBean("userBean", UserBean.class);
    System.out.println(user);
  }

image.png

7. 也可以通过类型直接获取一个Bean的实例

image.png

public static void main(String[] args) {
    //初始化Spring容器,当Spring容器初始化时,会自动加载配置文件,然后根据配置文件中的内容初始化Bean
    ApplicationContext ac = 
        new ClassPathXmlApplicationContext("application.xml");
    // 去Spring容器中获取一个UserBean对象 通过类型直接获取
    UserBean user = ac.getBean( UserBean.class);
    System.out.println(user);
  }

这种方式有潜在的隐患:如果Spring容器中有多个User的实例,此时就会报错

image.png

id和name的区别

实际开发过程中我们可以忽略id和name的区别。可以混合使用。通过getBean()方法都可以获取,这个是个重载的方法。

id="user1,user2,user3"
表示bean有一个名字,这个名字就是user1,user2,user3 
name="user1,user2,user3"
表示bean有多个名字,多个名字分别是user1、user2以及user3 

在同一配置文件中ID不要出现重复的。

BeanFactory和ApplicationContext的区别

   /**
   * ApplicationContext 方式加载
   */
  @Test
  public void test1() {
    // 创建容器的同时 容器初始化,容器所有的bean创建完毕
    ApplicationContext ac = new ClassPathXmlApplicationContext("application.xml");
    // 去Spring容器中获取一个UserBean对象 通过类型直接获取
    UserBean user = ac.getBean(UserBean.class);
    System.out.println(user);
  }
  /**
   * BeanFactory 方式加载
   */
  @Test
  public void test2() {
    // 创建容器对象,BeanFactory当调用getBean获取响应对象是才创建对象
    BeanFactory bf = new XmlBeanFactory(new ClassPathResource("application.xml"));
    // 去Spring容器中获取一个UserBean对象 通过类型直接获取
    UserBean user = bf.getBean(UserBean.class);
    System.out.println(user);
  }

image.png

二、静态工厂注入

创建静态工厂类

/**
 * User 工厂类
 * @author dpb[波波烤鸭]
 *
 */
public class UserFactory {
  /**
   * 必须是static方法
   * @return
   */
  public static UserBean getInstance(){
    return new UserBean();
  }
}

application.xml文件中注册

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!-- 静态工厂方式配置 配置静态工厂及方法 -->
  <bean class="com.dpb.factory.UserFactory" factory-method="getInstance" id="user2"/>
</beans>

获取相应的实例

image.png

应用场景

在一些第三方框架使用过程 中,可能不得不使用静态工厂注入或者实例工厂注入。

image.png

这里以OkHttp为例说明为何需要静态工厂注入

由于OkHttpClient需要通过Builder进行创建,因此无法直接使用构造方法注入。此时可以通过静态工厂注入。

三、动态工厂注入

创建动态工厂类

/**
 * User 工厂类
 * @author dpb[波波烤鸭]
 *
 */
public class UserFactory {
  /**
   * 动态工厂方式获取
   * 普通方法
   * @return
   */
  public  UserBean getInstance(){
    return new UserBean();
  }
}

application.xml注册

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!-- 注册动态工厂bean -->
  <bean class="com.dpb.factory.UserFactory" id="userFactory"/>
  <!-- 从工厂中获取UserBean对象 -->
  <bean id="user" factory-bean="userFactory" factory-method="getInstance"/>
</beans>

获取实例

image.png

四、属性注入

image.png

构造注入

创建有参构造方法,同时必须提供无参构造方法

image.png

application.xml中注入

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!-- 注册UserBean -->
  <bean class="com.dpb.javabean.UserBean" id="userBean">
    <!-- 通过构造注入设置 -->
    <constructor-arg name="id" value="1"/>
    <constructor-arg name="name" value="波波烤鸭"/>
    <constructor-arg name="age" value="18"/>
  </bean>
</beans>

还可以通过下标定位参数

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!-- 注册UserBean -->
  <bean class="com.dpb.javabean.UserBean" id="userBean">
    <!-- 通过构造注入设置 通过index 定位设置 -->
    <constructor-arg index="0" value="1"/>
    <constructor-arg index="1" value="波波烤鸭"/>
    <constructor-arg index="2" value="18"/>
  </bean>
</beans>

测试结果

image.png

设值注入

Java对象中提供对应的setter方法

image.png

/**
 * 
 * @author dpb[波波烤鸭]
 *
 */
public class UserBean {
  private int id;
  private String name;
  private int age;
  /**
   * 无参构造方法
   */
  public UserBean() {
    System.out.println("无参构造方法");
  }
  public int getId() {
    return id;
  }
  /**
   * 设值注入 必须提供对应的setter方法
   * @param id
   */
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  /**
   * 设值注入 必须提供对应的setter方法
   * @param name
   */
  public void setName(String name) {
    this.name = name;
  }
  public int getAge() {
    return age;
  }
  /**
   * 设值注入 必须提供对应的setter方法
   * @param age
   */
  public void setAge(int age) {
    this.age = age;
  }
  @Override
  public String toString() {
    return "UserBean [id=" + id + ", name=" + name + ", age=" + age + "]";
  }
  public void say(){
    System.out.println("hello ...");
  }
}

application.xml配置

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans 
  http://www.springframework.org/schema/beans/spring-beans.xsd">
  <!-- 注册UserBean -->
  <bean class="com.dpb.javabean.UserBean" id="userBean">
    <!--通过设值注入的方式注入  -->
    <property name="id" value="2"/>
    <property name="name" value="bobo烤鸭"/>
    <property name="age" value="32"/>
  </bean>
</beans>

测试

image.png

p名称空间注入

image.png

JavaBean对象

/**
 * p名称空间注入
 * @author dpb[波波烤鸭]
 *
 */
public class Person {
  private int id;
  private String name;
  private String address;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public String getAddress() {
    return address;
  }
  public void setAddress(String address) {
    this.address = address;
  }
  @Override
  public String toString() {
    return "Person [id=" + id + ", name=" + name + ", address=" + address + "]";
  }
}

application.xml配置

image.png

<!-- 注册 Person -->
<bean id="person" class="com.dpb.javabean.Person" p:id="3" p:name="邓澎波" p:address="深圳"/>

测试

image.png

image.png

对象注入

对象可以通过构造方法、set方法或者p名称空间注入,步骤如下:

Student类和Cat类

/**
 * 学生
 * @author dpb[波波烤鸭]
 *
 */
public class Student {
  private int id;
  private String name;
  // 拥有的 cat
  private Cat cat;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Cat getCat() {
    return cat;
  }
  public void setCat(Cat cat) {
    this.cat = cat;
  }
  @Override
  public String toString() {
    return "Student [id=" + id + ", name=" + name + ", cat=" + cat + "]";
  }
}
/**
 * 猫
 * @author dpb[波波烤鸭]
 *
 */
public class Cat {
  private int id;
  private String color;
  public int getId() {
    return id;
  }
  public void setId(int id) {
    this.id = id;
  }
  public String getColor() {
    return color;
  }
  public void setColor(String color) {
    this.color = color;
  }
  @Override
  public String toString() {
    return "Cat [id=" + id + ", color=" + color + "]";
  }
}

application.xml配置

  <!-- 配置 cat -->
  <bean id="catId" class="com.dpb.javabean.Cat">
    <property name="id" value="1"/>
    <property name="color" value="red"></property>
  </bean>
  <!-- 配置 student对象 -->
  <bean class="com.dpb.javabean.Student">
    <property name="id" value="10"/>
    <property name="name" value="波波烤鸭"/>
    <!-- 对象注入 -->
    <property name="cat" ref="catId"></property>
  </bean>

测试

image.png

数组和集合注入

数组和集合的注入方式是一致的,无论是基本数据类型还是一个引用,注入方式都是一样。 首先声明一个对象,对象中包含集合和数组

对象中添加对应的类型数据image.pngimage.png

application.xml注入

<!-- 配置 student对象 -->
  <bean class="com.dpb.javabean.Student">
    <property name="id" value="10"/>
    <property name="name" value="波波烤鸭"/>
    <!-- 对象注入 -->
    <property name="cat" ref="catId"></property>
    <!-- List集合注入 -->
    <property name="games">
      <list>
        <value>LOL</value>
        <value>DNF</value>
        <value>CS</value>
      </list>
    </property>
    <!-- 数组注入 -->
    <property name="books">
      <list>
        <bean class="com.dpb.javabean.Book">
          <property name="id" value="1001"/>
          <property name="bookName" value="西游记"/>
        </bean>
        <bean class="com.dpb.javabean.Book">
          <property name="id" value="1002"/>
          <property name="bookName" value="红楼梦"/>
        </bean>
      </list>
    </property>
  </bean>

测试

image.png

Map注入

声明Map属性,注意属性的key和value的数据类型需要提前定义好,然后在xml文件中直接使用(xml文件中配置时,key和属性的值必须要满足声明的要求,否则就会出错)。

对象中添加 Map属性

image.png

配置文件注入

<property name="score">
  <map>
    <entry key="数学" value="99"/>
    <entry key="英语" value="78"/>
    <entry key="化学" value="84"/>
  </map>
</property>

测试

image.png

props注入

properties注入与map注入类似

对象中添加properties属性

image.png

配置文件中注入

<property name="props">
  <props>
    <prop key="userName">admin</prop>
    <prop key="password">123</prop>
  </props>
</property>

测试

image.png


相关文章
|
25天前
|
XML Java 测试技术
Spring IOC—基于注解配置和管理Bean 万字详解(通俗易懂)
Spring 第三节 IOC——基于注解配置和管理Bean 万字详解!
117 26
|
2月前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
184 73
|
2月前
|
XML Java 数据格式
【SpringFramework】Spring IoC-基于XML的实现
本文主要讲解SpringFramework中IoC和DI相关概念,及基于XML的实现方式。
117 69
|
1月前
|
监控 Java 数据库连接
Spring c3p0配置详解
在Spring项目中配置C3P0数据源,可以显著提高数据库连接的效率和应用程序的性能。通过合理的配置和优化,可以充分发挥C3P0的优势,满足不同应用场景的需求。希望本文的详解和示例代码能为开发者提供清晰的指导,帮助实现高效的数据库连接管理。
72 10
|
2月前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
64 21
|
2月前
|
XML Java 数据格式
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
本文介绍了在使用Spring框架时,如何通过创建`applicationContext.xml`配置文件来管理对象。首先,在resources目录下新建XML配置文件,并通过IDEA自动生成部分配置。为完善配置,特别是添加AOP支持,可以通过IDEA的Live Templates功能自定义XML模板。具体步骤包括:连续按两次Shift搜索Live Templates,配置模板内容,输入特定前缀(如spring)并按Tab键即可快速生成完整的Spring配置文件。这样可以大大提高开发效率,减少重复工作。
使用idea中的Live Templates自定义自动生成Spring所需的XML配置文件格式
|
2月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
2月前
|
存储 Java 应用服务中间件
【Spring】IoC和DI,控制反转,Bean对象的获取方式
IoC,DI,控制反转容器,Bean的基本常识,类注解@Controller,获取Bean对象的常用三种方式
|
2月前
|
Java Spring
【Spring配置相关】启动类为Current File,如何更改
问题场景:当我们切换类的界面的时候,重新启动的按钮是灰色的,不能使用,并且只有一个Current File 项目,下面介绍两种方法来解决这个问题。
|
2月前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。