欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Spring学习笔记4——Bean

程序员文章站 2022-06-04 23:36:43
...

六、Spring Bean的配置和属性

什么是Bean?

组成应用程序并且由IOC容器管理的对象称之为Bean,Bean由Spring容器初始化、加载和管理
Spring支持两种配置文件格式:XMLProperties格式,一般用XML注册和管理Bean间的依赖关系
XML配置文件的根元素是<beans>,里面包含多个子元素<bean>去定义不同的Bean,这些元素描述了Bean如何被装载进Spring容器

常用属性
  • id 唯一标识符
  • name 可有多个名称,用逗号/分号隔开
  • class 具体实现类,用全限定名
  • scope 设置作用域,其属性值有:默认值singleton(单例)、prototype(原型)、request、session和global Session
  • constructor-arg 子元素,可用其传入构造参数进行实例化,index从0开始
  • property 子元素,用于调用 Bean 实例中的 Set 方法完成属性赋值,从而完成依赖注入。该元素的 name 属性指定 Bean 实例中的相应属性名
  • ref 和 等元素的子元索,该元素中的 bean 属性用于指定对 Bean 工厂中某个 Bean 实例的引用
  • value 和 等元素的子元素,用于直接指定一个常量值
  • listsetmap 分别用于封装List、Set、和Map类型属性的依赖注入
  • entry 子元素,用于设置键值对,ref/value指定值

Bean的实例化

Bean的实例化有三种方法:

  1. 构造器实例化
  2. 静态工厂方式实例化
  3. 实例工厂方式实例化
Bean的作用域(五种)
  1. singleton:单例模式,是Bean默认作用域,该模式下的Bean只有一个实例。只要id和该Bean定义相同了,就会返回同一个实例,常用于无会话状态的Bean(如DAO层、Service层)
  2. prototype:原型模式,该模式下通过Spring获取Bean时,容器都会创建新的实例
  3. request:在一次HTTP请求中,容器会返回该Bean的同一个实例,不同的HTTP请求返回不同的实例,该作用域只在当前HTTP Request内有效
  4. session:在一次HTTP Session中,容器会返回该Bean的同一个实例,不同的HTTP请求返回不同的实例,该作用域只在当前HTTP Session内有效
  5. global Session:在一个全局的HTTP Sesion中,容器会返回该Bean的同一个实例,该作用域仅在使用portlet context时有效

Bean的装配

Bean的装配相当是依赖注入,Spring容器有三种装配方式,继续XML、基于Annotation和自动装配。

  1. 基于XML
    通常由两种实现方式,设值注入和构造注入。
  • 设值注入:要求Bean的对应类必须有默认的无参构造方法和必须为要注入的属性提供setter方法。因为Spring实例化Bean时,先调用默认的构造方法实例化Bean对象,然后通过反射机制调用setXxx()进行属性的注入。在Spring配置文件中的<bean><prototype>为每个属性注入值
    <bean id="stu" class="com.web.di.ba01.Student">-->
        <property name="name" value="tt"/>-->
        <property name="age" value="23"/>-->
        <property name="school" ref="myschool"/>-->
    </bean>-->
    <!--引用类型的设值注入-->
    <bean id="myschool" class="com.web.di.ba01.School">
            <property name="name" value="清北"/>
            <property name="address" value="西京"/>
    </bean>

  • 构造注入:在Spring配置文件中用<constructor-arg>定义构造方法的参数,可用value(或子元素)设置该参数的值
<!--使用name属性实现构造注入-->
    <bean id="stu" class="com.web.di.ba01.Student">
        <constructor-arg name="name" value="构造"/>
        <constructor-arg name="age" value="13"/>
        <constructor-arg name="school" ref="myschool"/>
    </bean>

    <!--使用index属性实现构造注入-->
    <bean id="stu1" class="com.web.di.ba01.Student">
        <constructor-arg index="0" value="0"/>
        <constructor-arg index="1" value="1"/>
        <constructor-arg index="2" ref="myschool"/>
    </bean>

    <!--构造注入创建文件对象-->
    <bean id="myfile" class="java.io.File">
        <constructor-arg name="parent" value="D:\xxx\yyy"/>
        <constructor-arg name="child" value="zzz.txt"/>
    </bean>
多配置文件

在开发中,可以有多个配置文件
优势:

  • 减小配置文件大小,提高效率
  • 避免多名开发人员调用时发生冲突

分配方式:

  • 按功能模块:1*model=1*配置文件
  • 按类的功能:如数据库相关、做事务、做service
    Spring学习笔记4——Bean
注意:1、classpath表示类路径(class文件所在的目录)2、主次配置文件要放在同一个目录下,不然无法读取3、使用通配符时注意命名,不要主配置文件读取自己,导致死循环

  1. 基于Annotation
    当Bean对象过多时,为了防止XML配置文件过于臃肿,我们还可以选择Annotation对Bean进行装配,常用的注解如下:
  • @Component 是一个泛化的概念,仅仅代表一个组件(Bean),可作用在任何层次,使用时将其标注在对应类上即可,有以下属性
  1. name:用于创建对象,相当于的name,唯一的,单例的;相当于<bean id="myStudent" class="com.xxx.xxx.Student"/>
  • @Repository 作用与数据访问层(DAO层),功能同上
  • @Service 作用于业务层(Service层),功能同上
  • @Controller 作用于控制层(如Struts2的Action),功能同上
  • Autowired 对Bean的属性变量、属性的set方法和构造方法函数进行标注,配合对应的注解处理器完成Bean的自动配置工作。默认按照Bean的类型进行装配
  • Resource 作用和Autowired一样。但是默认按照Bean实例名称进行装配的。其中有两个重要的属性:
    1、name Spring将name解析为Bean实例名称,如果指定name属性,则按实例名称进行装载
    2、type Spring将type解析为实例类型,如果指定type属性,则按Bean类型进行装载
    如果都不指定,则先按Bean实例名称装配,如匹配失败,再按Bean类型装配,如再匹配失败,则抛出NoSuchBeanDefintionException异常
  • QualifierAutowired配合使用,会将默认的按Bean类型装配改为按Bean实例名称装配,其实例名称有Qualifier的参数指定
@Component、@Repository、@Service和@Controlle的区别:

@Repository用于持久层、放在dao的实现类上,表示创建dao对象(可访问数据库)
@Service用于业务层,放在service的实现类上,表示创建service对象(做业务处理,有事务等功能)
@Controlle用于控制器,放在控制器(处理器)的实现类上,创建controlle对象(能接收用户提交的数据,显示请求处理结果)
@Component当无法确定是哪个层或具体对象时,用@Component

@Repository、@Service和@Controlle是给项目的对象分层的
实现步骤
  1. 加依赖:略
  2. 创建类、类中加注解
@Component(value = "myStudent")
public class Student {
    //你要的代码
}
  1. 创建spring配置文件:声明组件扫描器的标签,指明注解在项目中的位置
    <context:component-scan base-package="com.spring.ba01"/>
    当扫描多个目标包时,有以下几种写法:
    1.<context:component-scan base-package="com.spring.ba01"/><context:component-scan base-package="com.spring.ba02"/>
    2.<context:component-scan base-package="com.spring.ba01;com.spring.ba02"/>冒号可以换成逗号
    3.base-package直接等于多个目标类的共同父包,但不建议写到com,包越多,越深都会导致扫描的速度下降

  2. 使用注解创建对象,创建容器ApplicationContext:略


简单类型赋值
@Value(value = "uzi")
private String name;
@Value(value = "23")
private Integer age;
注意:1、括号中的value是String类型的;2、放在属性定义上时无需set方法;3、这个也可以放在set方法之上

Spring学习笔记4——Bean

也可以通过${}来对属性赋值
  1. 首先在项目中创建一个properties配置文件,在里面设置属性的键值对,如:
myname=lisi  
myage=23
  1. 然后在xml中设置扫描其位置
<context:property=placeholder location="classpath:xxx.properties"/>

3.最后在对应的属性上通过注解来赋值

@Value("${myname}")
private String name;
@Value("${myage}")
private int age;
引用类型赋值

我们在Student中引用School

@Autowired
@Autowired
private School school;

@Autowired是spring框架提供的注解;使用自动注入原理;默认使用byType自动注入;位置和简单类型赋值一致

byName:

@Autowired
@Qualifier(value = "mySchool")
private School school;

byName不但要@Autowired,还要再加入一个@Qualifier(value=“bean的id”)

别忘了School也要创建对象哦

@Autowired的属性——required

  • @Autowired(required = true)是@Autowired的默认值,当引用类型赋值失败,程序报错并且终止执行,最好用这个,以便我们知道程序的问题
  • @Autowired(required = false)当引用类型赋值失败,程序正常执行,但是其引用类型是null
@Resource

@Resource:来自jdk,原理和@Autowired一致;默认byName;当byName注入赋值失败,则转换成byType
指定只使用byName的话: @Resource(name="bean的id")

//@Resource
@Resource(name="mySchool")
private School school;

3、自动装配
Spring容器自动装配相互写作的Bean间的关联关系,将一个Bean注入其他Bean的Property中。
使用时需要配置<bean>autowire属性,其属性有如下五个值:

  • byName 根据Property的name自动装配,如果其name和另一个Bean的Property的name相同,则自动装配这个Bean到Property
    <!--自动注入byName-->
    <bean id="stu3" class="com.web.di.ba01.Student" autowire="byName">
        <constructor-arg name="name" value="构造"/>
        <constructor-arg name="age" value="13"/>
    </bean>
    <bean id="school" class="com.web.di.ba01.School" >
        <property name="name" value="中科院"/>
        <property name="address" value="广州1"/>
    </bean>
应用类型的属性名和bean的id一致,且数据类型也是一致
  • byType 根据Property的type自动装配,如果type键注入另一个Bean的Property的type,则自动装配
<!--自动注入byType-->
    <bean id="stu4" class="com.web.di.ba01.Student" autowire="byType">
        <property name="name" value="aaa"/>
        <property name="age" value="22"/>
    </bean>
    <bean id="primaryschool" class="com.web.di.ba01.PrimarySchool">
        <property name="name" value="小学鸡"/>
        <property name="address" value="机场"/>
    </bean>
应用类型的数据类型和bean的class属性为同源(同源:引用类型的数据类型和bean的class值是一致的/是父子类关系/是接口和实现类关系)
primaryschool是school的子类哦~
需要注意的是,使用byType时,只能有一个符合条件的bean,不然会报异常,即声明了primaryschool就不要再声明school了

Spring学习笔记4——Bean
Spring学习笔记4——Bean

  • constructor 根据构造方法的参数的数据类型进行byType模式的自动装配
  • autodetect 如发现默认的构造方法,则用该模式,反之用byType模式
  • no 默认下,不使用自动装配,Bean依赖必须通过ref元素定义

条条:该学习笔记是记录了我的学习过程,学习自动力节点c语言中文网,有不对的地方欢迎指出