【Spring框架】——5.Bean的作用域及自动装配

1. Bean 的作用域

Bean 的作用域有以下 6 种:

  • singleton (单例模式,Spring 默认)
  • prototype (原型模式)
  • request (web应用中可用)
  • session (web应用中可用)
  • application (web应用中可用)
  • websocket (web应用中可用)
1.1 单例模式

这是 Spring 的默认机制,全局唯一,只有一个对象创建出来存在。

每次从容器中 get 的时候,不会产生一个新的对象,而是得到前面已经创建的对象,适合用于并发量不高的场景。

下面的这个 bean 显示地声明是单例模式,当然也可以省略 scope 不写。

<bean id="course" class="com.yuhuofei.pojo.Course" c:name="数学" c:num="0002" scope="singleton"/>
1.2 原型模式

每次从容器中 get 的时候,都会产生一个新的对象。

<bean id="course01" class="com.yuhuofei.pojo.Course" c:name="英语" c:num="0003" scope="prototype"/>

2. Bean 的自动装配

Spring 会在上下文中自动寻找,并自动给 bean 装配属性。

Spring 中有 3 种装配的方式:

  • 在 xml 中显示地配置
  • 在 java 中显示地配置
  • 隐式地自动装配 bean

下面主要通过示例,演示隐式地自动装配。

2.1 基于 xml 形式的自动装配

这种形式的自动装配,还是脱离不了 beans.xml 这样的文件。

2.1.1 ByName 自动装配

1、新建一个 People.java 类

package com.yuhuofei.pojo;

/**
 * @Description
 * @ClassName People
 * @Author yuhuofei
 * @Date 2022/6/22 22:52
 * @Version 1.0
 */
public class People {
    private String name;

    private Dog dog;

    private Cat cat;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Dog getDog() {
        return dog;
    }

    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }

    public void setCat(Cat cat) {
        this.cat = cat;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }
}

2、新建一个 Dog.java 类

package com.yuhuofei.pojo;

/**
 * @Description
 * @ClassName Dog
 * @Author yuhuofei
 * @Date 2022/6/22 22:52
 * @Version 1.0
 */
public class Dog {

    public void printString() {
        System.out.println("狗狗很可爱");
    }

}

3、新建一个 Cat.java 类

package com.yuhuofei.pojo;

/**
 * @Description
 * @ClassName Cat
 * @Author yuhuofei
 * @Date 2022/6/22 22:54
 * @Version 1.0
 */
public class Cat {
    public void printString() {
        System.out.println("猫的速度很快");
    }
}

4、新建一个 people.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dog" class="com.yuhuofei.pojo.Dog"/>
    <bean id="cat" class="com.yuhuofei.pojo.Cat"/>

    <!--byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean的id,找到就装配-->
    <bean id="people" class="com.yuhuofei.pojo.People" autowire="byName">
        <property name="name" value="yuhuofei"/>
    </bean>

</beans>

5、新建一个测试类 TestPeople.java

import com.yuhuofei.pojo.People;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Description
 * @ClassName TestPeople
 * @Author yuhuofei
 * @Date 2022/6/22 22:59
 * @Version 1.0
 */
public class TestPeople {

    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("people.xml");

        People people = context.getBean("people", People.class);

        people.getDog().printString();

        people.getCat().printString();

        System.out.println(people.getName());
    }
}

运行测试类的结果,如下所示

在这里插入图片描述

2.1.2 ByType 自动装配

这里,保留 2.1.1 中多个类不变,只改变 people.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
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="com.yuhuofei.pojo.Dog"/>
    <bean class="com.yuhuofei.pojo.Cat"/>

    <!--byType:会自动在容器上下文中查找,和自己对象属性(如people.getDog())类型相同的bean,找到就装配-->
    <bean id="people" class="com.yuhuofei.pojo.People" autowire="byType">
        <property name="name" value="yuhuofei"/>
    </bean>

</beans>

然后运行原来的测试类,得到的结果,与前面一样

在这里插入图片描述

2.1.3 小结
  • byName 的时候,需要保证所有 bean 的 id 是唯一的,并且这个 bean 需要和自动注入的属性的 set 方法的值一致
  • byType 的时候,需要保证所有 bean 的 class 是唯一的,并且这个 bean 需要和自动注入的属性的类型一致
2.2 基于注解实现自动装配

使用注解前,在 xml 文件中需要做的事:

  • 导入约束:context约束
  • 配置注解的支持:context:annotation-config/

即如下所示

<?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:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">
    
    <context:annotation-config/>
    
</beans>
2.2.1 基于注解实现自动装配示例演示

1、修改 People.java 类,将 setDog() 、setCat 两个方法去掉,并在 dog、cat 两个成员变量上加上注解 @Autowired

package com.yuhuofei.pojo;

import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Description
 * @ClassName People
 * @Author yuhuofei
 * @Date 2022/6/22 22:52
 * @Version 1.0
 */
public class People {

    @Autowired
    private Dog dog;
    @Autowired
    private Cat cat;

    private String name;

    public Dog getDog() {
        return dog;
    }

    public Cat getCat() {
        return cat;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }
}

2、修改 Cat.java 类

package com.yuhuofei.pojo;

/**
 * @Description
 * @ClassName Cat
 * @Author yuhuofei
 * @Date 2022/6/22 22:54
 * @Version 1.0
 */
public class Cat {
    public void printString() {
        System.out.println("猫的速度很快==使用Autowired注解");
    }
}

3、修改 Dog.java 类

package com.yuhuofei.pojo;

/**
 * @Description
 * @ClassName Dog
 * @Author yuhuofei
 * @Date 2022/6/22 22:52
 * @Version 1.0
 */
public class Dog {

    public void printString() {
        System.out.println("狗狗很可爱==使用Autowired注解");
    }

}

4、新建一个 applicationContext.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"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        https://www.springframework.org/schema/context/spring-context.xsd">

    <context:annotation-config/>

    <bean id="dog" class="com.yuhuofei.pojo.Dog"/>
    <bean id="cat" class="com.yuhuofei.pojo.Cat"/>
    <bean id="people" class="com.yuhuofei.pojo.People"/>

</beans>

5、修改 TestPeople.java 类

import com.yuhuofei.pojo.People;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Description
 * @ClassName TestPeople
 * @Author yuhuofei
 * @Date 2022/6/22 22:59
 * @Version 1.0
 */
public class TestPeople {

    public static void main(String[] args) {

        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");

        People people = context.getBean("people", People.class);

        people.setName("yuhuofei");

        people.getDog().printString();

        people.getCat().printString();

        System.out.println(people.getName());
    }
}

6、运行测试类,得到的结果,如下

在这里插入图片描述

2.2.2 小结

@Autowired 注解

  • 用在类的成员变量上
  • 用在 set 方法上

对于用在 set 方法上,例如前面的 People.java 类,可以改成下面这样,直接将注解加在 set 方法上。

package com.yuhuofei.pojo;

import org.springframework.beans.factory.annotation.Autowired;

/**
 * @Description
 * @ClassName People
 * @Author yuhuofei
 * @Date 2022/6/22 22:52
 * @Version 1.0
 */
public class People {
    
    private Dog dog;
    private Cat cat;
    private String name;

    public Dog getDog() {
        return dog;
    }
    
    @Autowired
    public void setDog(Dog dog) {
        this.dog = dog;
    }

    public Cat getCat() {
        return cat;
    }
    
    @Autowired
    public void setCat(Cat cat) {
        this.cat = cat;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "People{" +
                "name='" + name + '\'' +
                ", dog=" + dog +
                ", cat=" + cat +
                '}';
    }
}

使用 Autowired 的前提是,自动装配的属性在 IOC 容器中存在,且符合名字 byName。

@Qualifier 注解

当同一个类创建了多个 bean 对象,无法再单独使用 @Autowired 注解完成自动装配时,可以配合 @Qualifier 注解的使用,指定一个唯一的 bean 对象注入。

如下,创建了一个 cat 、一个 cat11 对象,由于都是从 Cat 类创建,无法再通过@Autowired 注解完成自动装配

<bean id="cat" class="com.yuhuofei.pojo.Cat"/>
<bean id="cat11" class="com.yuhuofei.pojo.Cat"/>

这时,在 People.java 类中,可以像下面这么写,来指定 cat11 对象

@Autowired
@Qualifier(value = "cat11")
private Cat cat;

@Resource 注解

@Resource
private Dog dog;

@Resource(name = "cat11")
private Cat cat;

这个注解是 java 自带的,不是 Spring 的,它比 Autowired 注解要强大些,不过效率可能差一点点。

@Resource 和 @Autowired 的区别

  • 都是用来自动装配的,都可以用在类的成员变量(属性)上
  • @Autowired 是通过 byType 的方式实现,而且必须要求这个对象存在,否则报错
  • @Resource 默认通过 byName 方式实现,如果找不到名字,则通过 byType 实现,如果都找不到,则报错
  • 执行顺序不同,@Autowired 是通过 byType 的方式实现,@Resource 默认通过 byName 方式实现
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值