本文正在参加「金石计划」

主张

在阅读本文之前,作者主张先阅读这篇文章以打牢Spring6根底,文章链接:/post/720818…

接下来咱们要学习一种新容器:IoC容器,即操控回转,咱们在spring里边经过IoC容器办理java目标的实例化和初始化,咱们将由IoC容器办理的java目标称为Spring Bean,这一点在和咱们学javase中运用new来创立目标没有任何差异。(仅仅为了区别,在spring里边叫IoC罢了)

接下来咱们要解说一下什么是依靠注入,常见的依靠注入包含如下两种办法

  • set注入
  • 结构注入

咱们在com.atguigu.spring6包下新建一个Person类,在User类中注入Person的特点,名为person

public class User {
    private String name ;
    private Person person ;
...
}

这里是初步完结注入的思维,后续咱们会在spring源码部分进行详细解说

为了对xml以及maven进行共同办理,咱们将spring-first工程里边的maven坐标共同迁移到父工程Spring6中去

六千字长文带你体验Spring6中11种IOC控制反转实现方式

最终不要忘记改写maven

紧接着咱们在Spring6中创立一个子工程,名为spring6-ioc-xml,承继父工程,JDK版别选择17,依旧是maven版别。

六千字长文带你体验Spring6中11种IOC控制反转实现方式

初步装备见下图,不再赘述(bean.xml未进行装备)

六千字长文带你体验Spring6中11种IOC控制反转实现方式

接着咱们将log4j2.xmlspring-first工程中复制到spring6-ioc-xml下,并放入相对应的方位(如果不知道在哪里的请回看spring-first的创立过程☹)

咱们在com.atguigu.spring6.iocxml包下新建一个class文件名为TestUser作为测验类进行测验。

然后咱们对bean.xml进行装备

<?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>">
<!--user目标创立-->
    <bean id="user" class="com.atguigu.spring6.iocxml.User"></bean>
</beans>

首要咱们经过id来获取beanTestUser类装备内容如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

运行成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

第二种办法:咱们能够依据类型获取bean

User user2 = context.getBean(User.class);
System.out.println("依据类型获取bean:" + user2);

输出的成果与第一种办法无异

第三种办法:依据id和类型获取bean

User user3 = context.getBean("user", User.class);
System.out.println("依据id和类型获取bean:" + user3);

输出的成果与第一、二种办法无异

当咱们依据类型获取bean的时分,要求咱们的IOC容器中指定类型的bean只能有一个

当咱们在bean.xml中写入如下装备

<!--user目标创立-->
    <bean id="user" class="com.atguigu.spring6.iocxml.User"></bean>
    <bean id="user1" class="com.atguigu.spring6.iocxml.User"></bean>

咱们在TestUser类中启动相关测验办法的时分,会发现报如下错误

Exception in thread "main" org.springframework.beans.factory.
NoUniqueBeanDefinitionException:
 No qualifying bean of type 'com.atguigu.spring6.iocxml.User' available:
 expected single matching bean but found 2: user,user1

这句话很明显的告诉咱们:没有为com.atguigu.spring6.iocxml.User匹配到一个合适的目标,Spring6希望咱们供给一个单实例的目标,但是咱们却供给了两个,一个叫user,一个叫user1,因而报错。

接下来咱们经过接口的办法去完结类获取的过程,首要咱们在com.atguigu.spring6.iocxml包下新建一个package名为bean,别离建立UserDao接口以及UserDaoImpl完结类,内容如下

package com.atguigu.spring6.iocxml.bean;
public interface UserDao {
    public void run();
}
package com.atguigu.spring6.iocxml.bean;
public class UserDaoImpl implements UserDao{
    @Override
    public void run() {
        System.out.println("run.......");
    }
}

接着咱们去装备一下bean.xml文件,咱们相同是经过idclass特点去获取咱们所要得到的完结类,以验证IOC回转操控的思维

<!--一个接口完结类获取过程-->
    <bean id="UserDaoImpl" class="com.atguigu.spring6.iocxml.bean.UserDaoImpl"></bean>

最终咱们在package包下新建一个测验类名为TestUserDao,写入下方代码

package com.atguigu.spring6.iocxml.bean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUserDao {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//        依据类型获取接口对应bean
        UserDao userDao = context.getBean(UserDao.class);
        System.out.println(userDao);
        userDao.run();
    }
}

最终咱们打印输出的成果在操控台有所显现:

六千字长文带你体验Spring6中11种IOC控制反转实现方式
接下来咱们完结一个接口对应多个完结类的事务场景。咱们在bean下新建一个类叫PersonDaoImpl,并将它承继于UserDao接口。

package com.atguigu.spring6.iocxml.bean;
public class PersonDaoImpl implements UserDao{
    @Override
    public void run() {
        System.out.println("person run.....");
    }
}

然后咱们去bean.xml中进行装备接口所对应的bean标签

<!--一个接口完结多个类的过程-->
    <bean id="PersonDaoImpl" class="com.atguigu.spring6.iocxml.bean.PersonDaoImpl"></bean>

最终咱们再对TestUserDao进行测验,报错信息如下

Exception in thread "main" org.springframework.beans.factory.
NoUniqueBeanDefinitionException: 
No qualifying bean of type 'com.atguigu.spring6.iocxml.bean.UserDao' available: 
expected single matching bean but found 2: UserDaoImpl,PersonDaoImpl

很明显,报错原因是由于bean不仅有。

接下来咱们经过set办法注入。首要咱们在com.atguigu.spring6.iocxml下新建一个package名为di,新建一个类名为Book,内容如下

package com.atguigu.spring6.iocxml.di;
public class Book {
    private String bname ;
    private String author ;
    public String getBname() {
        return bname;
    }
    public void setBname(String bname) {
        this.bname = bname;
    }
    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }
    public static void main(String[] args) {
//        set办法注入
        Book book = new Book();
        book.setBname("java");
        book.setAuthor("尚硅谷");
    }
}

依据上方代码块咱们能够得知,咱们经过setter的途径去对Book目标注入相关特点,这是咱们最常见的set注入,接下来咱们另一种set注入办法。

首要先对Book类添加相关结构器

public Book() {
    }
public Book(String bname, String author) {
        this.bname = bname;
        this.author = author;
    }

经过New目标的办法进行注入

//        经过结构器注入
        Book book1 = new Book("c++","尚硅谷");

接下来介绍Spring6中特有的set注入办法。咱们在resources下新建一个xml名为bean-di,详细装备内容见下方代码块

<!--1.set办法注入-->
    <bean id="book" class="com.atguigu.spring6.iocxml.di.Book">
        <property name="bname" value="前端开发"></property>
        <property name="author" value="尚硅谷"></property>
    </bean>

在这个xml中,咱们引进一个新的标签名为property,其间name特点的值与你在Book中写入的变量有关,value的值即为上文set办法注入的特点具有平等效力。

然后咱们在Book类中写入toString()办法,用于打印输出相关信息。接着咱们在di中写入测验类,相关测验信息与之前无异,读者模仿前文自行写入测验类即可,测验成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

接下来咱们测验一下结构器注入

首要咱们去xml中进行装备

<!--2.结构器注入-->
    <bean id="bookCon" class="com.atguigu.spring6.iocxml.di.Book">
        <constructor-arg name="bname" value="java开发"></constructor-arg>
        <constructor-arg name="author" value="尚硅谷"></constructor-arg>
    </bean>

在上方代码块中,咱们引进了一个新标签名为constructor-arg,该bean标签有两个特点,与property共同。然后咱们在Book的含参结构器中写入如下输出语句

System.out.println("有参数结构执行了.....");

接着咱们在TestBook中写入测验类,原理与上文共同,读者自行编写测验类即可,测验成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

咱们在xml中结构bean标签中constructor-arg的时分,它还有一个特点叫作index,读者可自行探索并写出测验办法,测验成果与上图共同。

接下来咱们要对一个特别值:null进行处理。首要咱们在Book中新建变量others使其私有化,特点为String,为它生成set办法以及在Book内从头生成toString()。接着咱们在xml文件中手写property,内容见下

<property name="others"><null/></property>

这一方面很好的处理value值为null的状况。

有时分咱们会在xml文件中写入特别符号,比如<>,此刻咱们就需求特别转义符号来进行处理。

<property name="others" value="&lt;"></property>

最终一种状况,有时分咱们想在xml文件中注入纯文本,此刻咱们需求用到CDATA节,详细运用办法见下

<property name="others">
            <value><![CDATA[a < b]]></value>
        </property>

要想为目标类型特点赋值,咱们首要得做一下准备工作。首要咱们要在com.atguigu.spring6.iocxml包下新建一个package名为ditest,别离新建类名为DeptEmp两个文件,别离写入如下内容

package com.atguigu.spring6.iocxml.ditest;
public class Dept {
    private String dname;
    public void info(){
        System.out.println("部分称号:" + dname);
    }
}
package com.atguigu.spring6.iocxml.ditest;
public class Emp {
//    职工归于某个部分
    private Dept dept;
    private String ename;
    private Integer age;
    public void work(){
        System.out.println("emp is working....." + age);
    }
}

接下来咱们别离在两个类中注入getset办法,而且在Emp中将work办法改写为

public void work(){
        System.out.println("emp is working....." + age);
        dept.info();
    }

接着咱们新建一个xml名为bean-ditest,在xml中,咱们先对Dept进行一般的特点注入,id值均为类名小写,property值见下

<property name="dname" value="安保部"></property>

和上述操作相同,咱们相同为Emp注入相关特点

<property name="ename" value="lucy"></property>
<property name="age" value="18"></property>

接下来咱们要注入目标类型的特点,写法如下

<property name="dept" ref="dept"></property>

ref代表引进的意思,表明引进咱们的目标,这个目标与Dept进行特点注入的时分的id值具有平等效力。咱们在ditest下新建一个测验类名为TestEmp,读者对Emp自行编写测验办法而且调用work办法,成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

接下来咱们运用内部bean的办法进行注入,首要编写咱们的xml文件,内容如下

<!--第二种办法:内部bean做注入-->
    <bean id="dept2" class="com.atguigu.spring6.iocxml.ditest.Dept">
        <property name="dname" value="财务部"></property>
    </bean>
    <bean id="emp2" class="com.atguigu.spring6.iocxml.ditest.Emp">
        <!--一般特点注入-->
        <property name="ename" value="mary"></property>
        <property name="age" value="20"></property>
<!--运用内部bean的办法进行注入-->
        <property name="dept">
            <bean id="dept2" class="com.atguigu.spring6.iocxml.ditest.Dept">
                <property name="dname" value="财务部"></property>
            </bean>
        </property>
    </bean>

xml中咱们能够看到,咱们运用内部bean进行了注入,详细操作是在property中注入bean,这也是为什么叫内部bean的原因,换句话说,现在咱们是在emp2中注入内部bean,比较以前独自的两个模块,能更直观、方便的看到注入联系。最终读者对Emp自行编写测验办法而且调用work办法,成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

接下来咱们要介绍第三种办法:级联赋值。首要咱们对xml文件进行修正,内容见下

<!--第三种办法:级联赋值-->
    <bean id="dept3" class="com.atguigu.spring6.iocxml.ditest.Dept">
        <property name="dname" value="技能研发部"></property>
    </bean>
    <bean id="emp3" class="com.atguigu.spring6.iocxml.ditest.Emp">
        <property name="ename" value="tom"></property>
        <property name="age" value="30"></property>
        <property name="dept" ref="dept3"></property>
        <property name="dept.dname" value="测验部"></property>
    </bean>

咱们要点能够放在最终一行代码上,咱们经过类调特点的办法对dname的值进行修正,依据就近原则,操控台打印输出的成果也应该是跟测验部有关,然后读者对Emp自行编写测验办法而且调用work办法,成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

接着咱们测验着去注入数组类型的相关特点,首要咱们新建一个xml名为bean-diarray,相关装备见下

<!--注入数组类型的特点-->
    <bean id="dept" class="com.atguigu.spring6.iocxml.ditest.Dept">
        <property name="dname" value="技能部"></property>
    </bean>
    <bean id="emp" class="com.atguigu.spring6.iocxml.ditest.Emp">
<!--一般特点-->
        <property name="ename" value="lucy"></property>
        <property name="age" value="20"></property>
<!--注入目标类型的特点-->
        <property name="dept" ref="dept"></property>
<!--注入数组类型的特点-->
        <property name="loves">
            <array>
                <value>Java</value>
                <value>Vue</value>
                <value>MySQL</value>
            </array>
        </property>
    </bean>

咱们要点关注<array>相关标签的代码,由于咱们考虑到人的爱好不止一个,所以Spring6为咱们供给了一个内置的array标签,在标签内咱们能够写入多个值。接着咱们在Emp中对work办法进行改写,内容如下

public void work(){
        System.out.println("emp is working....." + age);
        dept.info();
        System.out.println(Arrays.toString(loves));
    }

最终读者对Emp自行编写测验办法而且调用work办法,成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

下面咱们介绍一下list调集的注入,首要咱们在Dept中写入一个调集,而且对info进行改写,内容如下

private List<Emp> empList;
public void info(){
        System.out.println("部分称号:" + dname);
        for (Emp emp:empList){
            System.out.println(emp.getEname());
        }
    }

接着咱们新建xml名为bean-dilist,内容如下

<bean id="empone" class="com.atguigu.spring6.iocxml.ditest.Emp">
        <property name="ename" value="lucy"></property>
        <property name="age" value="19"></property>
    </bean>
    <bean id="emptwo" class="com.atguigu.spring6.iocxml.ditest.Emp">
        <property name="ename" value="mary"></property>
        <property name="age" value="30"></property>
    </bean>
    <bean id="dept" class="com.atguigu.spring6.iocxml.ditest.Dept">
    <property name="dname" value="技能部"></property>
    <property name="empList">
        <list>
            <ref bean="empone"></ref>
            <ref bean="emptwo"></ref>
        </list>
    </property>
</bean>

咱们要点关注<list>,在list调集中,咱们引进相关ref,表明对特点的注入。最终读者对Dept自行编写测验办法而且调用info办法,成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式
现在咱们试着进行map调集的注入,过程如下。首要咱们在com.atguigu.spring6.iocxml下新建一个package名为dimap,在dimap中新建两个文件,别离为StudentTeacher,别离创立如下特点

public class Student {
    private Map<String,Teacher> teacherMap;
    private String sid ;
    private String sname ;
......
}
public class Teacher {
    private String teacherId;
    private String teacherName;
......
}

咱们别离对这两个类注入setgettoString办法,接下来咱们编写xml文件,名为bean-dimap,在xml文件中,咱们主要有以下三个过程

  • 创立两个目标
  • 注入一般类型的特点
  • 在学生的bean中注入map调集类型的特点

前两个读者自行了解并对xml进行相关操作,咱们要点解说第三个如何完结。咱们对teacherMap这个map进行如下操作

<property name="teacherMap">
            <map>
                <entry>
                    <key>
                        <value>10010</value>
                    </key>
                    <ref bean="teacher"></ref>
                </entry>
            </map>
        </property>

在上方代码块中,咱们经过引进entry标签对map进行操作,相同是经过value以及ref特点对map注入相关值,由于咱们的map是写入Teacher类中,所以咱们ref引进的值有必要是teacher

接着咱们在Student类中对run办法进行改写,内容如下

public void run(){
        System.out.println("学生的编号:"+sid+"学生的称号:"+sname);
        System.out.println(teacherMap);
    }

读者可自行在xml中写入两个map注入特点,并在dimap中新建测验类TestStu,读者自行完结即可。运行成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

接下来咱们测验着引用调集类型的bean,首要咱们在dimap中新建类为Lesson,在类中咱们写入一个特点名为lessonNameString类型且私有化,而且结构出它的getsettoString办法。

接下来咱们新建一个xml名为bean-diref,咱们要完结的过程如下

  • 创立三个目标
  • 注入一般类型特点
  • 运用util:类型 界说
  • 在学生bean里边引进util:类型界说bean,完结list map类型特点注入。然后咱们修正头文件,修正内容如下
<?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/util>
       <http://www.springframework.org/schema/beans/spring-util.xsd>
       <http://www.springframework.org/schema/beans>
       <http://www.springframework.org/schema/beans/spring-beans.xsd>">

接下来咱们就能够引进util标签进行引用调集类型的注入。首要咱们将idstudentproperty特点补充完好,然后引进util标签,内容见下

<util:list id="lessonList">
<ref bean="lessonone"></ref>
<ref bean="lessontwo"></ref>
    </util:list>
    <util:map id="teacherMap">
        <entry>
            <key>
                <value>10010</value>
            </key>
            <ref bean="teacherone"></ref>
        </entry>
        <entry>
            <key>
                <value>10086</value>
            </key>
            <ref bean="teachertwo"></ref>
        </entry>
    </util:map>

依照上述过程,读者可自行编写测验类,不出意外会报错(成心留的),咱们需求在xml修正相关装备,改动地方见下图

六千字长文带你体验Spring6中11种IOC控制反转实现方式

运行成功截图见下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

接下来咱们介绍p标签命名注入,首要咱们在beans头标签中写入

xmlns:p="<http://www.springframework.org/schema/p>"

然后咱们写入如下标签

<!--p命名空间注入-->
    <bean id="studentp" class="com.atguigu.spring6.iocxml.dimap.Student"
    p:sid="100" p:sname="mary" p:lessonList-ref="lessonList" p:teacherMap-ref="teacherMap">
    </bean>

咱们经过引进外部特点文件的办法对数据进行注入处理,首要咱们在pom.xml中引进相关依靠

<dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.30</version>
    </dependency>
    <!-- <https://mvnrepository.com/artifact/com.alibaba/druid> -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid</artifactId>
        <version>1.0.31</version>
    </dependency>

接着咱们在resources下新建一个properties名为jdbc,写入内容如下

jdbc.user=root
jdbc.password=20020930pch
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
jdbc.driver=com.mysql.cj.jdbc.Driver

数据库中的userpassword都需求依据读者数据库的用户名和密码来决定,本文仅仅作者的数据库账户名和密码

数据库运用的是8.0及以上的版别

咱们新建一个xml文件名为bean-jdbc,而且运用context命名空间引进,内容如下

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

接下来咱们在com.atguigu.spring6.iocxml中新建一个package名为jdbc,在里边新建一个测验类名为TestJdbc,内容如下

package com.atguigu.spring6.iocxml.jdbc;
import com.alibaba.druid.pool.DruidDataSource;
import org.junit.jupiter.api.Test;
public class TestJdbc {
    @Test
    public void demo1(){
        DruidDataSource dataSource = new DruidDataSource();
        dataSource.setUrl("jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC");
        dataSource.setUsername("root");
        dataSource.setPassword("20020930pch");
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
    }
}

然后咱们完结数据库相关信息的注入,运用$引用properties文件中的相关特点

<!--完结数据库信息注入-->
    <bean id="druidDataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="driverClassName" value="${jdbc.driver}"></property>
    </bean>

最终咱们写入一个测验类,办法如下

@Test
    public void demo2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean-jdbc.xml");
        DruidDataSource dataSource = context.getBean(DruidDataSource.class);
        System.out.println(dataSource.getUrl());
    }

接下来咱们测验bean的效果域。咱们先在com.atguigu.spring6.iocxml中新建一个package名为scope,在包下咱们新建Orders测验类,然后在resources中新建xml进行装备,装备内容如下

<?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>">
<!--经过scope特点装备单实例/多实例-->
<bean id="orders" class="com.atguigu.spring6.iocxml.scope.Orders" scope="singleton">
</bean>
</beans>

xml文件中咱们能够看到在bean标签内多了一个特点叫作scope,读者在这里能够把它了解为效果域标签,Spring6在默认状况下是单实例,如果想设置多实例,在scope里边修正即可。最终读者自行编写测验类进行测验,并调用sout办法输出orders

接下来咱们介绍一下bean的生命周期。首要咱们在com.atguigu.spring6.iocxml中新建一个package名为life,在life中新建一个User类,内容如下

package com.atguigu.spring6.iocxml.life;
public class User {
    private String name ;
//    无参数的结构
    public User(){
        System.out.println("1 bean目标创立,调用无参结构");
    }
//  初始化的办法
    public void initMethod(){
        System.out.println("4 bean目标初始化 调用指定的初始化的办法");
    }
//  毁掉的办法
    public void destoryMethod(){
        System.out.println("7 bean目标毁掉 调用指定的毁掉的办法");
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        System.out.println("2 给bean目标设置特点值");
        this.name = name;
    }
}

接着咱们去xml文件中进行装备,新建一个xml名为bean-life,在文件中咱们写入如下内容

<?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="user" class="com.atguigu.spring6.iocxml.life.User"
          scope="singleton" init-method="initMethod" destroy-method="destoryMethod">
        <property name="name" value="lucy"></property></bean>
</beans>

最终咱们在life下新建一个测验类名为TestUser,用来测验bean的生命周期,内容见下图

package com.atguigu.spring6.iocxml.life;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("bean-life.xml");
        User user = context.getBean("user", User.class);
        System.out.println("6 bean目标创立完结了,能够运用了");
        System.out.println(user);
//        context.close();    // 毁掉
    }
}

测验结束之后咱们写入如下办法进行测验,意图是为了调用context.close();

package com.atguigu.spring6.iocxml.life;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestUser {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean-life.xml");
        User user = context.getBean("user", User.class);
        System.out.println("6 bean目标创立完结了,能够运用了");
        System.out.println(user);
        context.close();    // 毁掉
    }
}

如此下来,bean的基本生命周期就算走了一遍,读者可自行阅读代码加深印象。

细心的读者能够发现,生命周期的成果显现并不完好,接下来咱们把完好的生命周期展现一遍。首要咱们在life下新建一个类名为MyBeanPost,咱们在这个类中接入BeanPostProcessor接口,在接口中咱们能看到两个办法,咱们将这两个办法在MyBeanPost中进行重写,声明为public,而且别离加上bean生命周期中的3和5,最终进行测验,成果如下

六千字长文带你体验Spring6中11种IOC控制反转实现方式

接下来咱们基于XML办理Bean-FactoryBean,首要咱们新建一个package名为factorybean,然后咱们别离创立两个目标,名为FactoryBeanUser(创立User是由于有泛型),咱们在FactoryBean中写入如下内容

package com.atguigu.spring6.iocxml.factorybean;
import org.springframework.beans.factory.FactoryBean;
public class MyFactoryBean implements FactoryBean<User> {
    @Override
    public User getObject() throws Exception {
        return new User();
    }
    @Override
    public Class<?> getObjectType() {
        return User.class;
    }
}

接着咱们新建一个XML名为bean-factorybean,咱们在里边注入iduser的特点,并编写测验类进行测验。

在编写测验类的时分,读者需求留意运用强转,由于咱们的办法在FactoryBean是经过User创立的。

接下来咱们测验基于XML办理Bean完结主动安装。首要咱们在com.atguigu.spring6.iocxml下新建一个package名为auto,在其包下新建三个package别离名为controllerdaoservice。然后咱们在dao层下新建一个interface名为UserDao,装备内容如下

package com.atguigu.spring6.iocxml.auto.dao;
public interface UserDao {
    public void addUserDao();
}

接着咱们创立一个完结类名为UserDaoImpl而且承继UserDao,完结办法的重写,内容如下

@Override
    public void addUserDao() {
        System.out.println("userDao办法执行了...");
    }

以此类推,请读者自行在service层下写入相关信息。接着在UserController中写入如下信息

package com.atguigu.spring6.iocxml.auto.controller;
import com.atguigu.spring6.iocxml.auto.service.UserService;
import com.atguigu.spring6.iocxml.auto.service.UserServiceImpl;
public class UserController {
    private UserService userService;
    public void setUserService(UserService userService) {
        this.userService = userService;
    }
    public void addUser(){
        System.out.println("controller办法执行了...");
//        调用service里边的办法
        userService.addUserService();
    }
}

完结上述过程之后,咱们在resources中写入XML名为bean-auto,读者自行对三个id特点进行相关装备,其间在userControlleruserService中写入如下标签以完结依据类型完结主动安装

autowire="byType"

最终读者自行编写与userController相关的测验类并进行测验。

以上办法是依据类型完结主动安装,在Spring6中,咱们还能够依据称号完结主动安装,行将上述标签替换成

autowire="byName"

运行成果与上述是共同的,差异在于:当咱们运用byName注入特点的时分,咱们id的姓名有必要与测验类中getBean中的姓名共同,否则报错显现userDaonull,而类型注入能够疏忽这一点。