摘要:本文主要介绍Spring Bean的配置、实例化、作用域、声明周期以及装配方式等内容。通过本文的学习,希望能够帮助大家了解Spring Bean的生命周期,掌握Spring Bean的配置、实例化、作用域以及装配方式。

  1. Bean的配置
  2. Bean的实例化
  3. Bean的作用域
  4. Bean的生命周期
  5. Bean的装配方式
    在Spring的应用中,Spring IoC容器可以创建、装配和配置应用组件对象,这里的组件对象成为Bean。本文重点介绍如何将Bean装配注入Spring IoC容器中。

1.1 Bean的配置

Spring可以看做是一个大型的工厂,用于生产和管理Spring容器中的Bean,那么开发者就需要将Bean配置在Spring的配置文件中。Spring框架支持XML和Properties两种格式的配置文件,在实际开发中常用XML格式的配置文件。
中包含了多个元素,每个元素定义一个Bean,并描述Bean如何装配到Spring容器中.元素的常用属性及其子元素如下所示:

属性

描述

id

唯一标识

class

Bean的实现类(dao.TestDIDaoImpl)

scope

作用域

constructor-arg

bean的子元素

property

用于设置一个属性

list

property的子元素

map

property的子元素

set

property的子元素

entry

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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">

    <!--将指定类TestDIDaoImpl配置给Spring,让Spring创建其实例-->
    <bean id="myTestDIDao" class="com.kuang.dao.TestDIDaoImpl"/>
    <!--使用构造方法注入-->
    <bean id="testDIService" class="com.kuang.service.TestDIServiceImpl">
        <!--将myTestDIDao注入到TestDIServiceImpl类的属性testDIDao属性上-->
        <constructor-arg index="0" ref="myTestDIDao"/>
    </bean>

    <!--使用setter注入-->
    <bean id="testDIService1" class="com.kuang.service.TestDIServiceImpl1">
        <!--调用TestDIServiceImpl类的setter方法,将myTestDIDao注入到TestDIServiceImpl类的属性testDIDao-->
        <property name="testDIDao" ref="myTestDIDao"/>
    </bean>

1.2 Bean的实例化

Spring框架实例化Bean有3中方式:
(1)构造方法实例化(常用)
(2)静态工厂实例化
(3)实例工厂实例化

1.2.1 构造方法实例化

文件目录:

spring 的bean能忽略字段吗_bean

(1)创建BeanClass类

package com.kuang.instance;

public class BeanClass {
    public String message;
    public BeanClass(){
        message = "构造方法实例化Bean";
    }
    public BeanClass(String s){
        message = s;
    }

}

(2)创建配置文件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"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!--构造方法实例化-->
    <bean id="constructorInstance" class="com.kuang.instance.BeanClass"/>
</beans>

(3)测试类

import com.kuang.instance.BeanClass;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanClass constructorInstance = (BeanClass)context.getBean("constructorInstance");
        System.out.println(constructorInstance.message);
    }
}

(4)结果

spring 的bean能忽略字段吗_bean_02

1.3 Bean的作用域

作用域名称

描述

singleton

默认的作用域,只有一个Bean实例

prototype

容器每次创建新的Bean实例

request

再一次http请求中容器将返回一个Bean实例,不同的http请求返回不同的Bean实例。仅在web Spring应用程序上下文中使用

session

在一个http session中,然后同上

application

websocket

1.3.1 singleton 作用域

spring 的bean能忽略字段吗_spring_03

import com.kuang.instance.BeanClass;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        BeanClass constructorInstance1 = (BeanClass)context.getBean("constructorInstance");
        BeanClass constructorInstance2 = (BeanClass)context.getBean("constructorInstance");

        System.out.println(constructorInstance1==constructorInstance2);

//        System.out.println(constructorInstance1.message);
    }
}

spring 的bean能忽略字段吗_bean_04

1.3.2 prototype作用域

spring 的bean能忽略字段吗_spring_05


spring 的bean能忽略字段吗_java_06

1.4 Bean的生命周期

spring 的bean能忽略字段吗_bean_07

1.5 Bean的装配方式

Bean的装配可以理解为将Bean依赖注入到Spring容器中,Bean的装配方式即Bean依赖注入的方式。

1.5.1 基于XML配置的装配(由于xml配置繁琐,不常用)

1.5.2 基于注解的装配(重点)

  1. @Component
    该注解是一个泛化的概念,仅仅表示一个组件对象(Bean)可以作用在任何层次上。
    (1)创建Bean的实现类
package com.kuang.annotation;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class AnnotationUser {
    @Value("ywm")
    private String uname;


    public String getUname() {
        return uname;
    }

    public void setUname(String uname) {
        this.uname = uname;
    }
}

(2)配置注解
创建一个annotationContext.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
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/context
       https://www.springframework.org/schema/context/spring-context.xsd">

    <context:component-scan base-package="com.kuang.annotation"/>
</beans>

(3)测试类

import com.kuang.annotation.AnnotationUser;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class Test2 {
    public static void main(String[] args) {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("annotationContext.xml");
        AnnotationUser annotationUser = (AnnotationUser)context.getBean("annotationUser");
        System.out.println(annotationUser.getUname());
    }
}

结果:

spring 的bean能忽略字段吗_java_08

  1. @Repository(DAO层)
  2. @Service(业务层)
  3. @Controller(控制层)
  4. @Autowired(类成员变量、方法及构造方法进行标注,并完成自动装配的工作,消除setter和getter方法)
  5. @Resource(属性:name和type,name表示Bean实例名称,type属性指定Bean类型)
  6. @Qualifier(配合Autowired使用)