Spring入门(2)-IOC容器中,如果使用配置文件创建对象,基本思路是什么样的?

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配置文件,配置需要创建的对象;(这个需要你手动)
    在这里插入图片描述
      <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接口

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

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

  3. ApplicationContext中常见的两个类,如下图:

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的;


基本使用如下:(通过这中方式创建的对象,默认调用的还是无参的构造方法)

3.2 通过XML方式注入属性

  1. DI:注入属性;
  2. (在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注入为基础)

  1. 在配置文件里面添加P名称空间

  2. 进行属性注入即可,这时就不需要再次使用property属性了;

  3. 运行结果:

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为主的标签;

©️2020 CSDN 皮肤主题: 黑客帝国 设计师:上身试试 返回首页