本文正在参加「金石计划」
主张
在阅读本文之前,作者主张先阅读这篇文章以打牢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
中去
最终不要忘记改写maven
紧接着咱们在Spring6
中创立一个子工程,名为spring6-ioc-xml
,承继父工程,JDK
版别选择17,依旧是maven
版别。
初步装备见下图,不再赘述(bean.xml
未进行装备)
接着咱们将log4j2.xml
从spring-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
来获取bean
,TestUser
类装备内容如下
运行成果如下
第二种办法:咱们能够依据类型获取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
文件,咱们相同是经过id
和class
特点去获取咱们所要得到的完结类,以验证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();
}
}
最终咱们打印输出的成果在操控台有所显现:
接下来咱们完结一个接口对应多个完结类的事务场景。咱们在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
中写入测验类,相关测验信息与之前无异,读者模仿前文自行写入测验类即可,测验成果如下
接下来咱们测验一下结构器注入
首要咱们去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
中写入测验类,原理与上文共同,读者自行编写测验类即可,测验成果如下
咱们在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="<"></property>
最终一种状况,有时分咱们想在xml
文件中注入纯文本,此刻咱们需求用到CDATA节
,详细运用办法见下
<property name="others">
<value><![CDATA[a < b]]></value>
</property>
要想为目标类型特点赋值,咱们首要得做一下准备工作。首要咱们要在com.atguigu.spring6.iocxml
包下新建一个package
名为ditest
,别离新建类名为Dept
和Emp
两个文件,别离写入如下内容
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);
}
}
接下来咱们别离在两个类中注入get
和set
办法,而且在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
办法,成果如下
接下来咱们运用内部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
办法,成果如下
接下来咱们要介绍第三种办法:级联赋值。首要咱们对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
办法,成果如下
接着咱们测验着去注入数组类型的相关特点,首要咱们新建一个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
办法,成果如下
下面咱们介绍一下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
办法,成果如下
现在咱们试着进行map
调集的注入,过程如下。首要咱们在com.atguigu.spring6.iocxml
下新建一个package
名为dimap
,在dimap
中新建两个文件,别离为Student
和Teacher
,别离创立如下特点
public class Student {
private Map<String,Teacher> teacherMap;
private String sid ;
private String sname ;
......
}
public class Teacher {
private String teacherId;
private String teacherName;
......
}
咱们别离对这两个类注入set
、get
、toString
办法,接下来咱们编写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
,读者自行完结即可。运行成果如下
接下来咱们测验着引用调集类型的bean
,首要咱们在dimap
中新建类为Lesson
,在类中咱们写入一个特点名为lessonName
,String
类型且私有化,而且结构出它的get
、set
、toString
办法。
接下来咱们新建一个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
标签进行引用调集类型的注入。首要咱们将id
为student
的property
特点补充完好,然后引进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
修正相关装备,改动地方见下图
运行成功截图见下
接下来咱们介绍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
数据库中的user
和password
都需求依据读者数据库的用户名和密码来决定,本文仅仅作者的数据库账户名和密码
数据库运用的是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,最终进行测验,成果如下
接下来咱们基于XML
办理Bean-FactoryBean
,首要咱们新建一个package
名为factorybean
,然后咱们别离创立两个目标,名为FactoryBean
和User
(创立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
,咱们在里边注入id
为user
的特点,并编写测验类进行测验。
在编写测验类的时分,读者需求留意运用强转,由于咱们的办法在FactoryBean
是经过User
创立的。
接下来咱们测验基于XML
办理Bean
完结主动安装。首要咱们在com.atguigu.spring6.iocxml
下新建一个package
名为auto
,在其包下新建三个package
别离名为controller
、dao
、service
。然后咱们在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
特点进行相关装备,其间在userController
和userService
中写入如下标签以完结依据类型完结主动安装
autowire="byType"
最终读者自行编写与userController
相关的测验类并进行测验。
以上办法是依据类型完结主动安装,在Spring6
中,咱们还能够依据称号完结主动安装,行将上述标签替换成
autowire="byName"
运行成果与上述是共同的,差异在于:当咱们运用byName
注入特点的时分,咱们id的姓名有必要与测验类中getBean
中的姓名共同,否则报错显现userDao
为null
,而类型注入能够疏忽这一点。