Spring-Bean的作用域&Bean的自动装配

bean的作用域

翻译版

英文版

重点掌握单例和原型就可以了

单例模式(Spring 默认机制)

  • 所有bean 共享一个实例化对象
xml 复制代码
<bean id="user2" class="com.cike4.pojo.User" c:name="user2" c:age="20" 
  scope="singleton"/>

测试方法

java 复制代码
    @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        // 这里申明了类型,就不需要强壮类型 User 类了
        User user = context.getBean("user2", User.class);
        User user2 = context.getBean("user2", User.class);
        System.out.println(user==user2);
    }

bean共享同一个实例化对象,所以返回true

原型模式

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

xml 复制代码
<bean id="user2" class="com.cike4.pojo.User" c:name="user2" c:age="20" scope="prototype"/>

测试方法

java 复制代码
    @Test
    public void test2(){
        ApplicationContext context = new ClassPathXmlApplicationContext("userbeans.xml");
        // 这里申明了类型,就不需要强壮类型 User 类了
        User user = context.getBean("user2", User.class);
        User user2 = context.getBean("user2", User.class);
        System.out.println(user.hashCode());
        System.out.println(user2.hashCode());
        System.out.println(user==user2);

    }

两个获取的对象不相等,hash也不一样,因为实例化不一样

其余的

request、session、application、这些只能在web开发中使用

官方解释:

plain 复制代码
https://docs.spring.io/spring-framework/docs/5.2.0.RELEASE/spring-framework-reference/core.html#beans-factory-scopes
https://docs.spring.io/spring-framework/reference/core/beans/factory-scopes.html

Bean的自动装配

  • 自动装配是 Spring满足bean以来的一种方式!
  • Spring会在上下文中国自动寻找,并自动给bean装配属性

在Spring中有三种装配的方式:

  1. 在XML中显示的配置
  2. 在Java中显示配置
  3. 隐式的自动装配bean 【重要的】

测试

环境搭建:一个人有两个宠物

byName自动装配

byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应beanid

xml 复制代码
<bean  id="cat" class="com.cike5.pojo.Cat"/>
<bean  id="dog" class="com.cike5.pojo.Dog"/>
<!--
byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应beanid
-->
<bean class="com.cike5.pojo.People" id="people" autowire="byName">
        <property name="name" value="cike_y"/>
</bean>

byType自动装配

  • byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
    • 弊端,类型全局为一才会自动装配
xml 复制代码
<bean  class="com.cike5.pojo.Cat"/>
<bean  class="com.cike5.pojo.Dog"/>
<!--
byType:会自动在容器上下文中查找,和自己对象属性类型相同的bean
    弊端,类型全局为一才会自动装配
-->
<bean class="com.cike5.pojo.People" id="people" autowire="byType">
        <property name="name" value="cike_y"/>
</bean>

小结:

  • byName的时候,需要保证所有bean的id唯一,并且bean需要和自动注入的属性set方法后面的字母一致!
  • byTtype的时候,需要保证所有的bean的calss唯一,并且这个bean需要和自动注入的属性的类型一致!

官方解释:

plain 复制代码
https://docs.spring.io/spring-framework/docs/5.2.0.RELEASE/spring-framework-reference/core.html#beans-autowired-annotation
https://docs.spring.io/spring-framework/reference/core/beans/annotation-config/autowired.html

使用注解实现自动装配

JDK1.5支持的注解,Spring2.5就支持注解了!

The introduction of annotation-based configuration raised the question of whether this approach is "better" than XML.

要使用注解须知:

  1. 导入约束。context约束
  2. 配置注解的支持
xml 复制代码
    <context:annotation-config/>

干净并且完整的xml配置:

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/>

</beans>

官方文档:

plain 复制代码
https://docs.spring.io/spring-framework/docs/5.2.0.RELEASE/spring-framework-reference/core.html#beans-annotation-config
https://docs.spring.io/spring-framework/reference/core/beans/annotation-config.html
https://docs.spring.io/spring-framework/reference/core/beans/annotation-config/autowired.html
@Autowired

在类的属性上面进行注释

java 复制代码
public class People {
    @Autowired
    private Cat cat;
    @Autowired
    private Dog dog;
    private String name;

    public Cat getCat() {
        return cat;
    }

    public Dog getDog() {
        return dog;
    }
}
  • 不需要set方法了,因为是通过反射的原理实现的
  • 使用Autowired我们可以不用编写Set方法了,前提是你这个自动装配的属性在IoC(Spring)容器中存在且符合属性类型

测试方法

java 复制代码
    @Test
    public void test(){
        // 创建Spring容器对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        // 获取bean对象
        People people = context.getBean("people", People.class);
        people.getCat().shout();
        people.getDog().shout();
    }
科普
java 复制代码
@Nullable 字段标记了这个注解,说明这个字段可以为null

可以这样子写,让name值为空

java 复制代码
    private @Nullable String name;

查看Autowired的注解接口,可以看见默认值是true

java 复制代码
public @interface Autowired {

	/**
	 * Declares whether the annotated dependency is required.
	 * <p>Defaults to {@code true}.
	 */
	boolean required() default true;

}

也可以这样子写

java 复制代码
public class People {

    // 如果显示定义了Autowired 的 required属性为false,说明这个对象可以为null,否则不允许为空
    @Autowired (required = false)
    private Cat cat;
    @Autowired (required = false)
    private Dog dog;
@Qualifier

可以进行显示定义进行自动装配

java 复制代码
    @Qualifier("dog11")
    private Dog dog;

beans.xml 中的容器id为dog11,可以进行对应

java 复制代码
<?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="dog11" class="com.cike5.pojo.Dog"/>
    <bean id="cat" class="com.cike5.pojo.Cat"/>
    <bean id="people" class="com.cike5.pojo.People"/>

</beans>

@Autowired和@Qualifier的区别:

  • @Autowired是通过byType的方式实现的,而且这个对象必须存在
  • @Qualifier则是通过byName的方式实现的,显式定义这个容器id
@Resource

支持隐式自动装配、也支持显示定义,相当于@Autowored和@Quailifier的结合体

java 复制代码
public class People {

    // 隐式定义、自动装配
    @Resource
    private Cat cat;
java 复制代码
public class People {
    // 显示定义指定容器id、自动装配
    @Resource(name = "cat")
    private Cat cat;

小结:

@Resource和 @Autowired的区别:

  • 都是自动装配的,都可以放在属性字段上
  • @Autowired通过byType的方式实现,而且必须要求这个对象必须存在【常用】
  • @Resource 默认通过byName的方式实现,如果找不到,则会通过byType实现!如果两个都找不到的情况下,就会报错!最后也可以显示定义进行装配【常用】
  • 执行的顺序不同:@Autowired通过byType的方式实现,Resource 默认通过byName的方式实现
相关推荐
stella·2 小时前
mysql的时区问题
数据库·mysql·timezone·时区
斯普信云原生组2 小时前
Redis 阈值超限及影响分析
redis·spring·bootstrap
qq_12498707532 小时前
基于深度学习的蘑菇种类识别系统的设计与实现(源码+论文+部署+安装)
java·大数据·人工智能·深度学习·cnn·cnn算法
十八度的天空2 小时前
第01节 Python的基础语法
开发语言·python
谈笑也风生2 小时前
经典算法题型之排序算法(三)
java·算法·排序算法
yue0083 小时前
C# 字符串倒序
开发语言·c#
自己的九又四分之三站台3 小时前
导入数据到OG GraphQL以及创建graph
java·后端·graphql
强子感冒了3 小时前
Java学习笔记:String、StringBuilder与StringBuffer
java·开发语言·笔记·学习
低保和光头哪个先来3 小时前
场景6:对浏览器内核的理解
开发语言·前端·javascript·vue.js·前端框架