Spring IOC操作 之 基于xml的Bean管理

本文详细介绍了Spring框架中的Bean管理,包括基于XML的Bean创建、属性注入(如set注入和构造器注入)、特殊值注入、外部Bean注入、内部Bean和级联赋值。此外,还讲解了集合属性注入、工厂Bean、Bean作用域、生命周期以及自动装配。文章通过实例展示了如何配置和使用这些特性,帮助读者深入理解Spring的IoC和DI原理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

IOC操作(Bean管理)

控制反转(Inversion of Control,缩写为IoC),是面向对象编程中的一种设计原则,可以用来减低计算机代码之间的耦合度。其中最常见的方式叫做**依赖注入(Dependency Injection,简称DI**)

什么是Bean管理
基于XML
创建对象
注入属性
注入特殊值
外部Bean
内部Bean和级联赋值
xml注入集合属性
工厂Bean
Bean作用域
Bean生命周期
Xml自动装配

什么是Bean管理

Bean管理指的是下面两个操作:

Spring创建对象Spring注入属性(属性可以是对象里的字段,或者另一个对象)

主要有两种实现方式:xml和注解。

基于xml

创建对象

在Spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建

创建对象时,默认执行无参构造方法,不管类里面是否有有参构造方法(所以这一步小心报错)

使用

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8zVZKhN8-1625291693081)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210520202930538.png)]

bean中常用属性

id:并不是指对象的名字,而是指给对象创建一个标识,通过这个标识可以得到一个对象

class:要创建对象的全路径(包类路径)

name:比较早期的属性,作用跟id没差别,但是允许特殊符号

注入属性

DI:依赖注入(其实就是注入属性),是IOC的一种具体实现

以前的方式
set注入

基础注入方式是使用set方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-g3DMP1ti-1625291693082)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210520204110589.png)]

有参构造注入

也可以使用带参构造器注入属性

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mnEtZPyZ-1625291693083)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210520204219767.png)]

Spring方式
set注入

set注入涉及标签为property,里面有两个属性,name和value

name:表示的是类里面的字段名

value:表示字段的值

注意:①此时类里面涉及到的属性(字段)要有set方法

​ ②property对接的就是set方法

​ ③此时不需要构造函数带参

配置文件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0lAH2qtF-1625291693084)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210520205130096.png)]

具体类:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VTT498zO-1625291693085)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210521002240976.png)]

测试类测试方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0tV04bLz-1625291693086)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210520205805715.png)]

有参构造注入

有参构造涉及标签是constructor-arg,内有两个主要属性name,value

name:对应有参构造内的某个参数

value:要注入的属性值

注意:该标签中还有index属性,其值为0到i-1,分别表示对应第i个参数,其为name的代替(不过貌似没有什么人用,因为不够明显)

配置文件:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-aWbfouDg-1625291693087)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210521002708238.png)]

具体类:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ek9uBzDv-1625291693087)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210521003003066.png)]

测试类测试方法:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-h7AP0Cwy-1625291693088)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210521003135665.png)]

p名称空间注入(了解)

使用p名称空间注入,主要是简化基于xml配置方式的注入

xml文件上的xml**开头的,其实是一种约束

p:**其实就是代替property的作用,底层还是set

添加p名称空间:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-inDPfAhh-1625291693088)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210521004818054.png)]

具体配置代码(拿set注入的例子做改进版例子):

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RsfW2D70-1625291693089)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210521005108122.png)]

注入特殊值
null值

不写value, 在property里面加上null标签就可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sQHf7BHJ-1625291693091)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210522220105389.png)]

特殊符号

特殊符号注入主要有两种方法:

1、采用该符号的转移符号,比如:< 可以写成&lt

2、把带特殊符号的内容写到CDATA

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vMqPthVP-1625291693091)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210522220653682.png)]

外部Bean
场景复现

1、创建两个类service、dao

2、在service里面调用dao的方法

3、在Spring配置文件中进行配置

用到的属性:ref

接下来我们通过创建一些类和接口,以及对其进行测试来理解外部Bean的相关用法。

UserService类
package com.atguigu.spring5.service;
import com.atguigu.spring5.dao.UserDao;

public class UserService {

    //创建UserDoa类型属性,并生成set方法
    private UserDao userDao;
    public void setUserDao(UserDao userDao) {
        this.userDao = userDao;
    }

    public void add(){
        System.out.println("service add.....");
        userDao.update();
    }
}
UserDao接口
package com.atguigu.spring5.dao;

public interface UserDao {
    void update();
}
UserDaoImpl类(接口实现类)
package com.atguigu.spring5.dao;

public class UserDaoImpl implements UserDao {
    @Override
    public void update(){
        System.out.println("dao update......");
    }
}
TestBean类(测试类)
public class TestBean {
    @Test
    public void testAdd(){
        ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");

        UserService userService = context.getBean("userService", UserService.class);
        userService.add();
    }
}
配置文件
<!--    创建service和dao对象-->
    <bean id="userService" class="com.atguigu.spring5.service.UserService">
<!--    注入userDao对象-->
        <property name="userDao" ref="userDao"></property>
    </bean>
    <bean id="userDao" class="com.atguigu.spring5.dao.UserDaoImpl"></bean>

从配置文件可以看到,想要在一个注入类中使用另外一个类的方法,不仅另外一个类要注入,并且起始注入类的配置要做相应的改变。起始注入类的property的值不再是value,而是通过ref来注入,ref的值为另外一个需要注入的bean的id的值。

内部Bean和级联赋值
一对多关系

典型一对多关系:部门和员工

内部Bean

通常我们使用内部Bean会包含一对多的关系,比如员工需要一个属性表示其所属部门,这个时候我们需要在员工类里面实注入一个部门类,涉及类的注入需要用到bean标签。而在员工类的bean里面property的写法则需要改变。

员工类
public class Emp {
    private String ename;
    private String gender;
    private Dept dept;

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void add(){
        System.out.println(ename);
        System.out.println(gender);
        System.out.println(dept);
    }
}
部门类
public class Dept {

    private String dname;
    public void setDname(String dname) {
        this.dname = dname;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "dname='" + dname + '\'' +
                '}';
    }
}
配置文件
<bean id="emp" class="com.atguigu.spring5.Bean.Emp">
    <property name="ename" value="lucy"></property>
    <property name="gender" value=""></property>
    <property name="dept">
        <bean id="dept" class="com.atguigu.spring5.Bean.Dept">
            <property name="dname" value="安保部"></property>
        </bean>
    </property>
</bean>
测试文件
@Test
public void testbean2(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");

    Emp emp = context.getBean("emp", Emp.class);
    emp.add();
}
级联Bean
第一种写法

实质就是引用外部的bean给里面的属性赋值

配置文件:

<!--级联赋值-->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
    <!--设置两个普通属性-->
    <property name="ename" value="lucy"></property>
    <property name="gender" value=""></property>
    <!--级联赋值-->
    <property name="dept" ref="dept"></property>
</bean>
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
    <property name="dname" value="财务部"></property>
</bean>
第二种写法
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
    <!--设置两个普通属性-->
    <property name="ename" value="lucy"></property>
    <property name="gender" value=""></property>
    <!--级联赋值-->
    <property name="dept" ref="dept"></property>
    <property name="dept.dname" value="技术部"></property>
</bean>
<bean id="dept" class="com.atguigu.spring5.bean.Dept">
</bean>

此时emp类里面要有dept的get方法:

public Dept getDept() {
    return dept;
}
xml注入集合属性

xml注入集合属性主要有以下类型:

1.注入数组类型属性

2.注入List集合类型属性

3.注入Map集合类型属性

第一种情况
创建基本类
public class Stu {
    private String[] courses;

    private List<String> list;

    private Map<String, String> map;

    private Set<String> set;

    public void setSet(Set<String> set) {
        this.set = set;
    }

    public void setCourses(String[] courses) {
        this.courses = courses;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public void setMap(Map<String, String> map) {
        this.map = map;
    }
    
    public void test(){
        System.out.println(Arrays.toString(courses));
        System.out.println(list);
        System.out.println(map);
        System.out.println(set);
    }
}
配置文件

数组-array

list-liat

map-map

set-set

<bean id="stu" class="com.atguigu.spring5.Collectiontype.Stu">
    <property name="courses">
        <array>
            <value>java</value>
            <value>sql</value>
        </array>
    </property>
    <property name="list">
        <list>
            <value>张三</value>
            <value>小三</value>
        </list>
    </property>
    <property name="map">
        <map>
            <entry key="JAVA" value="java"></entry>
            <entry key="PYTHON" value="python"></entry>
        </map>
    </property>
    <property name="set">
        <set>
            <value>Mysql</value>
            <value>Redis</value>
        </set>
    </property>
</bean>
测试
@Test
public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    Stu stu = context.getBean("stu", Stu.class);
    stu.test();
}
第二种情况

上面的方式对于类型的参数是对象,就会显得捉襟见肘,所以我们需要一种新的方式

配置文件

这时候需要用到ref标签,里面的bean表示在外面声名的bean

<bean id="stu" class="com.atguigu.spring5.Collectiontype.Stu">
    <property name="courseList">
        <list>
            <ref bean="course1"/>
            <ref bean="course2"/>
        </list>
    </property>
</bean>

<bean id="course1" class="com.atguigu.spring5.Collectiontype.Course">
    <property name="cname" value="Spring5框架课程"/>
</bean>

<bean id="course2" class="com.atguigu.spring5.Collectiontype.Course">
    <property name="cname" value="Spring5框架课程"/>
</bean>
创建基本类
public class Stu {

    private List<Course> courseList;

    public void setCourseList(List<Course> courseList) {
        this.courseList = courseList;
    }

    public void test(){
        System.out.println(courseList);
    }
}
public class Course {
    private String cname;

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Course{" +
                "cname='" + cname + '\'' +
                '}';
    }
}
测试
@Test
public void test(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
    Stu stu = context.getBean("stu", Stu.class);
    stu.test();
}
第三种情况

对于一些公共用到的属性,我们可以把它们提取出来

之前提到过可以用p命名空间,现在使用一种新的命名空间(不要求掌握)

xmlns:util="http://www.springframework.org/schema/util"
配置文件
<?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 https://www.springframework.org/schema/util/spring-util.xsd">

    <!--    公共部分-->
    <util:list id="bookList">
        <value>one</value>
        <value>two</value>
        <value>three</value>
    </util:list>

    <!--    属性注入-->
    <bean id="book" class="com.atguigu.spring5.Collectiontype.Book">
        <property name="list" ref="bookList"/>
    </bean>
</beans>
基本类:
public class Book {
    private List<String> list;

    public void setList(List<String> list) {
        this.list = list;
    }

    public void test(){
        System.out.println(list);
    }
}
测试
@Test
public void test2(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    Book book = context.getBean("book", Book.class);
    book.test();
}
工厂Bean

在Spring的Bean管理中,有两种Bean,一种是普通的Bean,另外一种是工厂Bean(FactoryBean)

注意:

FactoryBean(工厂Bean)可以生成某一个类型Bean的实例,作用是可以让我们自定义Bean的创建过程

BeanFactory(Bean工厂)是Spirng容器中的一个基本类,在BeanFactory可以创建和管理Spring容器中的Bean

普通Bean的特点与实现

普通Bean:在配置文件中bean的class定义的类型就是该bean返回的类型

比如:在bean2.xml配置文件中我这样写:

<bean id="book" class="com.atguigu.spring5.Collectiontype.Book">
    <property name="list" ref="bookList"/>
</bean>

这个普通Bean返回的类型是Book,所以我用的时候要这么写:

@Test
public void test2(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    Book book = context.getBean("book", Book.class);
    book.test();
}

可以看到我们需要用一个Book引用去引用bean实例。

FactoryBean的特点与实现

FactoryBean:在配置文件中定义的Bean的类型可以和返回的类型可以不一致

具体步骤

1.创建类,让其作为工厂Bean,并实现 FactoryBean 接口

2.实现接口里的方法,在实现的方法中定义返回的Bean类型

案例

先定义MyBean类:

/**
 * 这里要实现的是泛型接口,所以不要漏了类型定义
 * 关于泛型的理解的博客:
 * https://blog.youkuaiyun.com/I_r_o_n_M_a_n/article/details/115128604
 */
public class MyBean implements FactoryBean<Course> {

    /**
     * 定义返回的bean
     * @return
     */
    @Override
    public Course getObject() {
        Course course = new Course();
        course.setCname("abd");
        return course;
    }

    @Override
    public boolean isSingleton() {
        return FactoryBean.super.isSingleton();
    }

    @Override
    public Class<?> getObjectType() {
        return null;
    }
}

FactoryBean接口传入的类可以是随便一个类,这里我沿用上面定义的Course类,同时重写该接口的三个方法(主要还是getObject())。

接下来在src目录下创建bean3.xml,同时定义一个Bean:

<?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="myBean" class="com.atguigu.spring5.FactoryBean.MyBean">
    </bean>
</beans>

上面的class就是我们上面定义的MyBean。

接下来做测试:

@Test
public void test3(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean3.xml");
    Course course = context.getBean("myBean", Course.class);
    System.out.println(course);
}

可以看到,我上面返回的Bean类型不再是MyBean,而是Course,同时getBean的第二个参数也变成了Course.class

这里返回的Bean主要是要和我们重写的getObject()方法的返回类型对应上

测试:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-f0BTFRIh-1625291693091)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210701231304918.png)]

可以看到,测试成功。

Bean作用域

Bean的作用域可以理解成Bean是单实例还是多实例

默认情况下,Spring中的Bean是单实例

单实例

接下来我们通过一个例子来理解什么叫单实例,比如说下面的测试代码:

<bean id="book" class="com.atguigu.spring5.Collectiontype.Book">
	<property name="list" ref="bookList"/>
</bean>
@Test
public void test2(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    Book book1 = context.getBean("book", Book.class);
    Book book2 = context.getBean("book", Book.class);
    System.out.println(book1);
    System.out.println(book2);
}

我们对同一个xml配置文件内的同一个Bean,用两个引用来获取Bean实例,那么输出的结果是怎么样的呢?如果使用多实例,那么他们两个的地址应该是不相同的,但是实际结果确是这样:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8vSZmqA8-1625291693091)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210702102918687.png)]

可以看到他们的输出是一样的,这证明默认创建的,就是单实例。

多实例

在Spring的Bean标签里面有一个属性scope可以设置该标签是单实例还是多实例

scope有两个值:singleton(默认值),表示该Bean是单实例对象;prototype,表示该Bean是多实例对象。

这时我们为bean添加scope属性,赋值prototype

<bean id="myBean" class="com.atguigu.spring5.FactoryBean.MyBean" scope="prototype">
</bean>
@Test
public void test2(){
    ApplicationContext context = new ClassPathXmlApplicationContext("bean2.xml");
    Book book1 = context.getBean("book", Book.class);
    Book book2 = context.getBean("book", Book.class);
    System.out.println(book1);
    System.out.println(book2);
}

同样对该段代码进行测试,结果发现他们是不一样的对象:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vpFy03kv-1625291693092)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210702222153709.png)]

singletonprototype除了表示单实例与多实例的区别外,还有下面这个特点:

如果scope的值为singleton时,加载Spring配置文件时就会创建该对象(单实例),如果值为prototype时,在调用getBean才会创建该对象(多实例、懒加载)。

Bean生命周期

从对象创建到对象销毁的过程

生命周期简述
  1. 通过构造器创建bean实例(类的无参数构造)

  2. 为bean的属性设置值和对其他bena的引入(调用set方法)

  3. 调用bean的初始化的方法(想看到这步需要自行配置)

  4. 可以使用bean了(获取到对象了)

  5. 当容器关闭的时候,调用bean的销毁的方法(想看到这步需要自行配置)

重现过程

为了更高地看明白bean的生命周期,我们可以简单地整一个案例。

首先是实体类Orders:

public class Orders {

    private String oname;

    public void setOname(String oname) {
        this.oname = oname;
        System.out.println("这里执行了第二步,设置属性的值");
    }

    public Orders(){
        System.out.println("这里执行了第一步,调用无参构造创建Bean实例");
    }

    /**
     * Bean初始化方法
     */
    public void initMethod(){
        System.out.println("这里执行了第三步,调用bean的初始化方法");
    }

    /**
     * Bean注销的方法
     */
    public void destroyMethod(){
        System.out.println("这里执行了第五步,调用bean的销毁方法");
    }
}

上面的实体类中只有一个字段oname,还有Orders的无参构造方法、oname的set方法,以及用来手动显示Bean初始化和注销过程的init和destroy方法。

下面是配置文件:

<bean id="orders" class="com.atguigu.spring5.bean.Orders" init-method="initMethod" destroy-method="destroyMethod">
    <property name="oname" value="手机"/>
</bean>

上面的bean标签内多了两个属性,init-method属性表示初始化的时候调用的方法,destroy-method属性表示注销bean的时候调用的方法,他们的值分别对应Orders类里面的方法。

接下来是测试方法:

@Test
public void test4(){
    ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("bean4.xml");
    Orders orders = context.getBean("orders", Orders.class);
    System.out.println("这里执行了第四步,获取到Bean实例,并且可以使用");
    System.out.println(orders);

    //注销
    context.close();
}

上面除了调用getBean方法之外,还调用了close方法,该方法表示注销对应配置文件内的Bean实例,同时还应当注意的是:由于调用了close方法,context的引用类型不再是ApplicationContext,而是ClassPathXmlApplicationContext

如果还是想使用ApplicationContext引用的化,那么就请将注销的代码改成这样:((ClassPathXmlApplicationContext)context).close,也就是说加一个强转(但是现在已经不推荐这种写法了)。

接下来是测试:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EjBzOT9h-1625291693092)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210702231402710.png)]

可以看到测试结果符合我们的预期,第一步调用了无参构造方法,第二部设置属性的值,第三步调用我们手动设置的初始化方法,第四步获取bean实例,第五步调用被我们手动设置了的注销方法。

Bean的后置处理器

上面的生命周期其实是没有加上Bean后置处理器的,如果加上后置处理器,那么Bean的生命周期将分为七步,具体改变在第三步的前后。

  1. 通过构造器创建bean实例(类的无参数构造)

  2. 为bean的属性设置值和对其他bena的引入(调用set方法)

  3. 把Bean实例传递给Bean的后置处理器的方法(postProcessBeforeInitialization)

  4. 调用bean的初始化的方法(想看到这步需要自行配置)

  5. 把Bean实例传递给Bean的后置处理器的方法(postProcessAfterInitialization)

  6. 可以使用bean了(获取到对象了)

  7. 当容器关闭的时候,调用bean的销毁的方法(想看到这步需要自行配置)

演示添加后置处理器之后的效果

演示后置处理器,我们需要实现一个BeanPostProcessor接口,该接口内有postProcessBeforeInitialization方法和postProcessAfterInitialization方法,实现类MyBeanPost需要重写这两个方法。

实现类MyBeanPost

public class MyBeanPost implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之前执行的方法");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("在初始化之后执行的方法");
        return bean;
    }
}

配置文件中需要配置后置处理器,它其实也是一个Bean:

<bean id="myBeanPost" class="com.atguigu.spring5.bean.MyBeanPost"/>

当配置文件中有了上诉的bena之后,Spring就会认为该配置文件内的所有Bean都会加上后置处理器。

测试方法与之前的无差别。

下面是测试的结果:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1adP45rW-1625291693094)(C:\Users\15998\AppData\Roaming\Typora\typora-user-images\image-20210702232936215.png)]

可以看到已经调用了后置处理器的两个方法,这就是完整的Bean生命周期。

xml自动装配

我们可以根据指定装配规则(根据属性名或者属性类型进行装配),让Spring自动将匹配的属性值进行注入。

以往的手动装配

以往我们注入外部bean时,需要在bean标签内时使用property标签手动装配

<bean id="emp" class="com.atguigu.spring5.autowire.Emp">
    <property name="dept" ref="dept"/>
</bean>
<bean id="dept" class="com.atguigu.spring5.autowire.Dept"/>
自动装配

bean标签有一个属性autowire,该属性表示所属标签注入属性值时使用自动装配,其主要使用的有两个值:byName、byType。

  • byName:根据属性名称注入,注入的bean的id值应和需要装配属性的set方法的名称一样。

  • byType:根据属性类型注入。

比如:

Emp类中有:

private String dept;

public void setDept(String dept) {
    this.dept = dept;
}

那么我们就可以使用自动装配来注入Dept类:

<bean id="emp" class="com.atguigu.spring5.autowire.Emp" autowire="byName"/>
<bean id="dept" class="com.atguigu.spring5.autowire.Dept"/>

实际xml自动装配不常用,有时候反而让人感觉更加麻烦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值