欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

程序员文章站 2022-03-11 18:59:34
目录1. IOC的概念1.1什么是IOC?2. IOC的深层剖析2.1 IOC用到的核心技术2.2 IOC的底层实现原理(大致了解)2.3 IOC接口2.4 IOC的Bean管理1. IOC的概念1.1什么是IOC?在百度百科中:IOC,Inversion Of Control,控制反转,属于面向对象编程的一种原则,用来降低计算机代码之间的耦合度,最常见的方式叫做依赖注入(DI);目的(简单来说):就是通过IOC,把对象创建和对象之间的调用(就比如在一个类里面调用另一个类) 过程交给Spring来进...



1. IOC的概念

1.1什么是IOC?

在百度百科中:IOC,Inversion Of Control,控制反转,属于面向对象编程的一种原则,用来降低计算机代码之间的耦合度,最常见的方式叫做依赖注入(DI);
目的(简单来说):就是通过IOC,把对象创建对象之间的调用(就比如在一个类里面调用另一个类) 过程交给Spring来进行管理,降低耦合度(程序讲究高内聚,低耦合);

2. IOC的深层剖析

2.1 IOC用到的核心技术

  1. XML解析
  2. 设计模式中的工厂模式
  3. Java中的反射

2.2 IOC的底层实现原理(大致了解)

  • 第一步:创建一个XML配置文件,配置需要创建的对象;(这个需要你手动)
    Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?
     <bean id="自己设置的名字" class="类的路径"/> 
  • 第二步:创建工厂类,在工厂类中返回类A的对象;(这个Spring给你完成了,你可以直接获得对象)
    public class factory { //就像是简单工厂模式返回一样; public static B getA() throws ClassNotFoundException, IllegalAccessException, InstantiationException { String classvalue = "获得XML文件中的class属性值"; //然后通过反射对那个类进行加载;classvalue就是从XML中获得的类的路径; Class clazz = Class.forName(classvalue); //创建需要的对象并返回,但是如果使用工厂模式的话,就可以直接返回这个类的接口就可以了,这样以后多态就方便了; //return (A) clazz.newInstance(); /*使用下面这种方式返回,那么以后但凡是实现了接口B的都可以使用,
             但是使用上面的,就只能返回A类;也就是只有调用A类才可以使用;
             */ return (B) clazz.newInstance(); } } interface B { } class A implements B { public void test() { System.out.println("13"); } } 
    下图时对上面的返回方式进行简单的解释;Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

2.3 IOC接口

  1. 在Spring中IOC接口的实现有两种方式:
    一种是BeanFactory接口,Spring内部的使用接口(一般不给普通开发者不用);加载配置文件的时候,不会直接创建对象;而是在getBean()的时候才会创建对象;
    另一种是ApplicationContext接口,该接口是 BeanFactory的子接口,里面的功能更加的多,主要是给普通的开发者使用;而且只要在XML中进行了类的配置,那么加载配置文件时就会把配置文件中的对象进行创建;

  2. IOC底层是一个对象工厂(应该就是指,是一个工厂对象,专门用来生产对象的)

  3. ApplicationContext中常见的两个类,如下图:
    Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

FileSystemXmlApplicationContext这个类使用时,中间的参数主要可以理解为一个绝对路径(比如从C盘开始写);
ClassPathXmlApplicationContext这个类创建对象时,中间的参数主要可以理解为相对的路径;

2.4 IOC的Bean管理

Bean的两个操作:

  1. Spring创建对象;
  2. Spring注入属性依赖;
    上面的两种操作同样的有两种方式来实现:一种是通过XML配置文件的方式来实现,第二种是通过注解的方式来实现;

3. 通过XML进行Bean管理

3.1 通过XML配置文件创建对象

首先要创建一个Spring的xml配置文件(Spring config),然后在其中使用<Bean>标签对类进行配置;
对Bean标签中的属性进行简单的记录:
id属性:自己设置的名字(就类似与自己给这个对象建立一个标识,用于区分不同的Bean标签)
class属性:创建的对象的类的全路径;
name属性:和id的使用方式类似,也是用于区分bean的;


基本使用如下:(通过这中方式创建的对象,默认调用的还是无参的构造方法)
Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

3.2 通过XML方式注入属性

  1. DI:注入属性;
  2. (在Spring中有两种注入属性的方式):一种是使用set方法注入,一种是通过构造方法注入;

通过set注入:

  • 创建一个类,然后在类中写好基本属性和set方法;
    Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?
  • 创建一个配置文件用来配置需要的属性;
<?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"> <!--
    bean 中的id和class属性都已经介绍了,现在介绍以下property中使用到的属性;
    name 是你自己设置的属性名;
    value 是你注入的属性值,类似于默认属性值;
    --> <bean id="book" class="com.company.BookTest"> <property name="bname" value="数理化"/> </bean> </beans> 

测试类:

public class cTest { @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("/cn/dxs/XML/TestBook.xml"); //第一个参数是之前在XML文件里面配置的id,后面是规定类型; BookTest book = context.getBean("book", BookTest.class); //通过上面的对象直接调用set方法,并进行赋值; book.setBname("dd"); System.out.println(book.toString()); } } 

输出:
Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

总结:多个属性的注入也是按照这种格式,唯一的不同点可能就是多在bean标签中多写几个property


通过构造方法的方式进行属性的注入

  • 创建一个类,这个类里面有带参的构造方法;
public class BookTest { private String Bname; public BookTest(String bname) { Bname = bname; } @Override public String toString() { return "BookTest{" + "Bname='" + Bname + '\'' + '}'; } } 
  • 在Spring的配置文件中进行配置
<?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"> <!--
    constructor-arg 这个标签是用来标明构造方法中的参数的;
    name 构造方法中的参数名
    value 是你注入的属性值,类似于默认属性值;
    --> <bean id="book" class="com.company.BookTest"> <constructor-arg name="bname" value="天才在左,疯子在右"/> </bean> </beans> 

测试类:

public class cTest { @Test public void test() { ApplicationContext context = new ClassPathXmlApplicationContext("/cn/dxs/XML/TestBook.xml"); //第一个参数是之前在XML文件里面配置的id,后面是规定类型; BookTest book = context.getBean("book", BookTest.class); System.out.println(book.toString()); } } 

运行结果:
Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?


前面介绍的都是指,所有放进去的属性开始设置就不是空值的情况,那么如果是空值(null),该怎么设置?
其它的步骤都是一样的,唯一的不同点就是空值的属性中,在配置文件配置的时候是这样的;

<!--这就表示这个属性是空值了;--> <property name="bname"> <null/> </property> 

还有一个就是说如果属性是一个类的引用,该怎么编写property标签;(一般就是只外部类在另一个类中调用)

 <property name="bname" ref="填写另一个类的id" /> <!--解释如下:--> <!--class user{}类;class Myclass{private user use}类--> <!--有一个类叫user,它在配置文件中的配置;--> <bean id="user" class="a.b.d"></bean> <!--这是在一个类Myclass中将user作为它的属性;--> <bean id="myclass" class="a.b.c"> <!--里面的name是属性设置时的名字;里面的ref是那个类的Bean中的id值--> <property name="use" ref="user"> </property> </bean> <!--代替这里的整个xml配置文件,还有一种方式
		 <bean id="myclass" class="a.b.c">
		<property name="use" >
		<bean id="user" class="a.b.d">
		<property name="user" value="jjj"/>
		</bean>
		</property>
		</bean> 
		--> 

接下来考虑一下,如果放进去的值带有特殊符号的时候该怎么设置,如果只是单纯什么都不做,肯定会报错的;
第一个想到的肯定是进行转移符号;(可以直接百度,一般都有,当然记得最好)
第二个就是使用<![CDATA[放入带特殊符号的值]]>就可以了;

 <property name="bname"> <value> <![CDATA[小王子]]> <!-- 目前没想写特殊符号,单纯记录吧--> </value> </property> 

外部级联复制;

这是BookTest类;
Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?
Mian类

Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

TestBook.xml文件
Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?


4. P名称空间注入(还是以set注入为基础)

  1. 在配置文件里面添加P名称空间
    Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

  2. 进行属性注入即可,这时就不需要再次使用property属性了;
    Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

  3. 运行结果:
    Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?

5. IOC注入集合属性

5.1注入数组,List,Map,Set类型的属性

一:创建一个类CollectionTest作为需要创建对象的类;

public class CollectionTest { //定义一个数组属性 private String[] arr; //定义一个list集合属性; private List<String> list; //定义一个Map集合属性; private Map<String,String> map; //定义一个Set集合属性; private Set<String> set; //创建所需要的setter方法,getter 先不创建; public void setArr(String[] arr) { this.arr = arr; } public void setList(List<String> list) { this.list = list; } public void setMap(Map<String, String> map) { this.map = map; } public void setSet(Set<String> set) { this.set = set; } @Override public String toString() { return "CollectionTest{" + "arr=" + Arrays.toString(arr) + ", list=" + list + ", map=" + map + ", set=" + set + '}'; } } 

二:在配置文件中进行设置;

<?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"> <!--先使用bean标签创建类的对象--> <bean id="collectiontest" class="cn.dxs.Collection.CollectionTest"> <!--下面是对数组属性进行配置--> <property name="arr"> <array> <value>语文</value> <value>数学</value> </array> </property> <!--下面是对List属性进行配置--> <property name="list"> <list> <value>物理</value> <value>化学</value> </list> </property> <!--下面是对Map属性进行配置--> <property name="map"> <map> <entry key="English" value="英语"/> </map> </property> <!--下面是对Set属性进行配置--> <property name="set"> <set> <value>历史</value> </set> </property> </bean> </beans> 

三.测试类Test

 public class Testdemo1 { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml"); CollectionTest collectiontest = context.getBean("collectiontest", CollectionTest.class); System.out.println(collectiontest); } } 

测试结果:
Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?


5.2 当需要往List中插入对象时,该如何做?

第一步:我们先创建一个类Book和类Library

//Book类 public class Book { //在这个类里面创建一个简单属性; String Bname; public void setBname(String bname) { Bname = bname; } @Override public String toString() { return "Book{" + "Bname='" + Bname + '\'' + '}'; } } 

Library类:

public class Libarary { public List<Book> list; //创建一个Set方法; public void setList(List<Book> list) { this.list = list; } @Override public String toString() { return "Libarary{" + "list=" + list + '}'; } } 

第二步:创建一个配置文件

<?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"> <!--众所周知,bean标签其实就是在创建一个对象,这里先创建一个book1的对象--> <bean id="book1" class="cn.dxs.OnCollection.Book"> <property name="bname" value="巴黎圣母院"/> </bean> <!--再次创建应该对象book2--> <bean id="book2" class="cn.dxs.OnCollection.Book"> <property name="bname" value="八仙过海"/> </bean> <!--创建一个Library类的对象--> <bean id="library" class="cn.dxs.OnCollection.Libarary"> <property name="list"> <list> <ref bean="book1"/> <!--<ref bean="book2"/>--> <!--再次创建应该对象book2--> <bean id="book2" class="cn.dxs.OnCollection.Book"> <property name="bname" value="八仙过海"/> </bean> </list> </property> </bean> </beans> 

测试类:

public class TestLibrary { @Test public void test(){ ApplicationContext context = new ClassPathXmlApplicationContext("cn/dxs/xml/Bookconfig.xml"); Libarary library = context.getBean("library", Libarary.class); System.out.println(library); } } 

运行结果:
Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?


5.3 引入名称空间,将List注入简化使用

配置文件这样写:

<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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 http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd"> <util:list id="book"> <value>八仙过海</value> <value>巴黎圣母院</value> </util:list> <!--创建一个Library类的对象--> <bean id="library" class="cn.dxs.OnCollection.Libarary"> <property name="list" ref="book"/> </bean> </beans> 

在这之中最重要的就是插入xmlns:util="http://www.springframework.org/schema/util
和最后的 http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd
这样才能使用util为主的标签;

本文地址:https://blog.csdn.net/dxsdcyy/article/details/107791579