Spring在IOC容器中,使用配置文件创建对象,基本思路是什么样的?
目录
1. IOC的概念
1.1什么是IOC?
在百度百科中:IOC,Inversion Of Control,控制反转,属于面向对象编程的一种原则,用来降低计算机代码之间的耦合度,最常见的方式叫做依赖注入(DI);
目的(简单来说):就是通过IOC,把对象创建和对象之间的调用(就比如在一个类里面调用另一个类) 过程交给Spring来进行管理,降低耦合度(程序讲究高内聚,低耦合);
2. IOC的深层剖析
2.1 IOC用到的核心技术
- XML解析
- 设计模式中的工厂模式
- Java中的反射
2.2 IOC的底层实现原理(大致了解)
-
第一步:创建一个XML配置文件,配置需要创建的对象;(这个需要你手动)
<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"); } }
下图时对上面的返回方式进行简单的解释;
2.3 IOC接口
-
在Spring中IOC接口的实现有两种方式:
一种是BeanFactory接口,Spring内部的使用接口(一般不给普通开发者不用);加载配置文件的时候,不会直接创建对象;而是在getBean()的时候才会创建对象;
另一种是ApplicationContext接口,该接口是 BeanFactory的子接口,里面的功能更加的多,主要是给普通的开发者使用;而且只要在XML中进行了类的配置,那么加载配置文件时就会把配置文件中的对象进行创建; -
IOC底层是一个对象工厂(应该就是指,是一个工厂对象,专门用来生产对象的)
-
ApplicationContext中常见的两个类,如下图:
FileSystemXmlApplicationContext这个类使用时,中间的参数主要可以理解为一个绝对路径(比如从C盘开始写);
ClassPathXmlApplicationContext这个类创建对象时,中间的参数主要可以理解为相对的路径;
2.4 IOC的Bean管理
Bean的两个操作:
- Spring创建对象;
-
Spring注入属性依赖;
上面的两种操作同样的有两种方式来实现:一种是通过XML配置文件的方式来实现,第二种是通过注解的方式来实现;
3. 通过XML进行Bean管理
3.1 通过XML配置文件创建对象
首先要创建一个Spring的xml配置文件(Spring config),然后在其中使用<Bean>标签对类进行配置;
对Bean标签中的属性进行简单的记录:id属性:
自己设置的名字(就类似与自己给这个对象建立一个标识,用于区分不同的Bean标签)class属性:
创建的对象的类的全路径;name属性
:和id的使用方式类似,也是用于区分bean的;
基本使用如下:(通过这中方式创建的对象,默认调用的还是无参的构造方法)
3.2 通过XML方式注入属性
-
DI:
注入属性; - (在Spring中有两种注入属性的方式):一种是使用set方法注入,一种是通过构造方法注入;
通过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 中的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()); } }
输出:
总结:多个属性的注入也是按照这种格式,唯一的不同点可能就是多在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()); } }
运行结果:
前面介绍的都是指,所有放进去的属性开始设置就不是空值的情况,那么如果是空值(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类;
Mian类
TestBook.xml文件
4. P名称空间注入(还是以set注入为基础)
-
在配置文件里面添加P名称空间
-
进行属性注入即可,这时就不需要再次使用property属性了;
-
运行结果:
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); } }
测试结果:
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); } }
运行结果:
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
上一篇: 雅姆·蒂索是谁?法国古典主义画家雅姆·蒂索生平简介
下一篇: 只有新的最好看