spring学习之---spring容器中的Bean

本文介绍了Spring框架的基础知识,包括Bean的定义与配置、作用域、依赖注入方式等内容。

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

开发者使用spring框架主要做两件事:1.开发Bean;2.配置Bean。
IoC的本质是:根据配置文件来创建Bean实例,并调用Bean实例的方法完成”依赖注入”。

1.Bean的基本定义和Bean别名

<beans.../>元素是spring配置文件的根元素,有如下属性:

  • default-lazy-init:指定<beans.../>元素下配置的所有Bean默认的延迟初始化行为。
  • default-merge:指定该<beans.../>元素下配置的所有Bean默认的merge行为。
  • default-autowire:指定该<beans.../>元素下配置的所有Bean默认的自动装配行为。
  • default-autowire-candidates:指定该<beans.../>元素下配置的所有Bean默认是否作为自动装配的候选Bean。
  • default-init-method:指定<beans.../>元素下配置的所有Bean默认的初始化方法。
  • default-destroy-method:指定<beans.../>元素下配置的所有Bean默认的回收方法。
    <beans.../>元素下所能指定的属性都可以在每个<bean.../>子元素中指定—将属性名去掉default即可。

定义Bean时,通常需要指定两个属性:

  • id:Bean的id属性在spring容器中应该是唯一的。
  • class:指定该Bean的具体实现类,这里不能是接口。
  • name:用于为Bean实例指定别名。

<alias.../>元素为已有的Bean指定别名。

  • name:该属性指定一个Bean实例的标识名,表明将为该Bean实例指定别名。
  • alias:指定一个别名。
2.容器中Bean的作用域
  • singleton:单例模式,在整个Spring IoC容器中,singleton作用域的Bean将生成一个实例。
  • prototype:每次通过容器的getBean()方法获取prototype作用域的Bean时,都将产生一个新的Bean实例。
  • request:对于一个HTTP请求,request作用域的Bean将只生成一个实例。
  • session:对于一次HTTP会话,session作用域的Bean将只生成一个实例。
  • global session:每个全局的HTTP Session对应一个Bean实例。

如果不指定Bean的作用域,spring默认使用singleton作用域。

spring配置文件通过scope属性指定Bean的作用域。

request和session作用域只在Web应用中才有效,并且必须在Web应用中增加额外配置才会生效。为了让request和session两个作用域生效,必须将HTTP请求对象绑定到为该请求提供服务的线程上,这使得具有request和session作用域的Bean实例能够在后面的调用链中被访问到。
在Web应用的web.xml文件中增加如下Listener配置,该Listener负责使request作用域生效。

    <listener>
        <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    </listener>
3.配置依赖

对于singleton作用域的Bean,如果没有强行取消其预初始化行为,系统会在创建spring容器时预初始化所有的singleton Bean,与此同时,该Bean所依赖的Bean也被一起实例化。
BeanFactory和ApplicationContext实例化容器中Bean的时机不同:前者等到程序需要Bean实例时才创建Bean;而后者在容器创建ApplicationContext实例时,会预初始化容器中的所有singleton Bean。
spring可以把任何Java类都部署在spring容器中—只要该Java类具有相应的构造器,可以为任何Java对象注入任何类型的属性—只要该Java对象为该属性提供了对应的setter方法即可。
创建实例的Java对象底层机制:

    Class targetClass = Class.forName("");
    Object bean = targerClass.newInstance();
    <property.../>元素的底层机制:
    String_setName1 = "set" + "Aa";
    Mehod setMethod1 = targetClass.getMethod(setName1,aVal.getClass());
    setMethod1.invoke(bean,aVal);
4.设置普通属性值

<value.../>元素用于指定基本类型及其包装、字符串类型的参数值,spring使用XML解析器来解析出这些数据,然后利用java.beans.PropertyEditor完成类型转换:从java.lang.String类型转换为所需的参数值类型。

5.配置合作者Bean

如果需要为Bean设置的属性值是容器中的另一个Bean实例,则应该使用<ref.../>元素。使用<ref.../>元素时可指定一个bean属性,该属性用于引用容器中其他Bean实例的id属性值。

6.使用自动装配注入合作者Bean

spring的自动装配可通过<beans.../>元素的default-autowire属性指定,该属性对配置文件中的所有Bean起作用;也可通过<bean.../>元素的autowire属性指定,该属性只对该Bean起作用。

  • no:不使用自动装配。显示配置合作者能够得到更清晰的依赖关系。
  • byName:根据setter方法名进行自动装配。spring容器查找容器中的全部Bean,找到id与setter方法名去掉set前缀,并小写首字母后同名的Bean来完成注入。如果没有找到匹配的Bean实例,则Spring不会进行任何注入。
  • byType:根据setter方法的形参类型来自动装配。spring容器查找容器中的全部Bean,如果正好有一个Bean类型与setter方法的形参类型匹配,就自动注入这个Bean;如果找到对个这样的Bean,就抛出一个异常;如果没找到,则什么都没有发生。
  • constructor:与byType类似,区别是用于自动匹配构造器的参数。
  • autodetect:spring容器根据Bean内部结构,自行决定使用construtor或byType策略。
7.注入嵌套Bean

如果某个Bean所依赖的Bean不想被spring容器直接访问,则可以使用嵌套Bean。由于容器不能获取嵌套Bean,因此它不需要指定id属性。

    <bean id="" class="">
        <property name="">
            <bean class=""/>
        </property>
    </bean>

spring框架的本质就是通过XML配置文件来驱动Java代码。

8.注入集合值
    <bean id="" class="">
        <property name="">
            <list>
                <value>小学</value>
                <value>初中</value>
                <value>高中</value>
            </list>
        </property>
    </bean>

    <bean id="" class="">
        <property name="">
            <map>
                <entry key="原始社会" value="yuanshi"/>
                <entry key="农业社会" value-ref=""/>
            </map>
        </property>
    </bean>

    <bean id="" class="">
        <property name="">
            <props>
                <prop key="血压">正常</prop>
                <prop key="身高">180</prop>
            </props>
        </property>
    </bean>

    <bean id="" class="">
        <property name="">
            <set>
                <value>普通字符串</value>
                <bean class=""/>
                <list>
                    <value>20</value>
                    <set>
                        <value type="int">30</value>
                    </set>
                </list>
            </set>
        </property>
    </bean>

spring IoC容器将支持集合的合并,子Bean中的集合属性值可以从其父Bean的集合属性继承和覆盖而来。子Bean的集合属性的最终值是父Bean、子Bean合并后的最终结果,而且子Bean集合中的元素可以覆盖父Bean集合中对应的元素。

    <bean id="parent" abstract="true" class="">
        <property name="admin1">
            <props>
                <prop key="admin">admin</prop>
                <prop key="user">root</prop>
            </props>
        </property>
    </bean>
    <bean id="child" parent="parent">
        <property name="admin1">
        <!--指定了merge="true"将会把parent Bean的集合属性合并到 child Bean中-->
            <props merge="true">
                <prop key="pass">0408</prop>
                <prop key="user">root</prop>
            </props>
        </property>
    </bean>
9.组合属性

spring支持组合属性的方式。例如:使用配置文件为形如foo.bar.name的属性设置参数值。为Bean的组合属性设置参数值时,除最后一个属性之外,其他属性值都不允许为null。

    public class ExampleBean{
        private Person person = new Person();

        public Person getPerson(){
            return this.person;
        }
    }
    Person类里有一个String类型的name成员变量

    <bean id="exampleBean" class="">
        <property name="person.name" value="猴子"/>
    </bean>

对于这种注入组合属性值的形式,每个<property.../>元素依然是让spring执行一次setter方法,但它不再是直接调用该Bean的setter方法,而是需要先调用getterfangfa,然后再去调用setter方法。

    exampleBean.getPerson().setName("猴子");
10.spring的Bean和JavaBean

spring容器对Bean没有特殊要求,甚至不要求该Bean像标准的JavaBean—必须为每个属性提供对用的setter和getter方法。spring中的Bean是Java实例、Java组件;而传统Java应用中的JavaBean通常作为DTO(数据传输对象),用来封装值对象,在各层之间传递数据。

建议spring容器中的Bean应满足如下几个原则:

  • 尽量为每个Bean实现类提供无参数的构造器。
  • 接受构造注入的Bean,则应提供对应的、带参数的构造函数。
  • 接受设值注入的Bean,则应提供对应的setter方法,并不要求提供对应的getter方法。

传统的JavaBean和spring中的Bean存在如下区别:

  • 用处不同:传统的JavaBean更多的是作为值对象传递参数;spring的Bean用处几乎无所不包,任何应用组件都被称为Bean。
  • 写法不同:传统的JavaBean作为值对象,要求每个属性都提供setter和getter方法;但spring的Bean只需为接受设值注入的属性提供setter方法即可。
  • 生命周期不同:传统的JavaBean作为值对象传递,不接受任何容器管理其生命周期;spring中的Bean由spring管理其生命周期行为。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值