Spring学习笔记14---bean的使用

前言

Spring最基础的功能就是一个bean工厂,所以本文讲解的是Spring生成bean的种种方法及细节,Spring配置文件的名字是bean.xml,定义几个类:

一个Person类:

public class Person
{
    private String     personName; // 人的名字
    private int        personAge;    // 人的年龄    

    public Person(String personName, int personAge)
    {
        this.personName = personName;
        this.personAge = personAge;
    }

    public String getPersonName()
    {
        return personName;
    }

    public void setPersonName(String personName)
    {
        this.personName = personName;
    }

    public int getPersonAge()
    {
        return personAge;
    }

    public void setPersonAge(int personAge)
    {
        this.personAge = personAge;
    }

    public String toString()
    {
        return "personName = " + personName + ", personAge = " + personAge;
    }
}

一个Family类,里面持有Person的引用:

public class Family
{
    private Person person;
    private String familyName;

    public Family(Person person, String familyName)
    {
        this.person = person;
        this.familyName = familyName;
    }

    public String toString()
    {
        return person.toString() + ", familyName = " + familyName;
    }
}

一个单例类:

public class SingletonClass
{
    private SingletonClass instance = new SingletonClass();

    private SingletonClass(){}

    public SingletonClass getInstance()
    {
        return instance;
    }
}

一个空的类,为了测试初始化和销毁用的:

public class EmptyClass
{
    static
    {
        System.out.println("Enter EmptyClass.static block");
    }

    public EmptyClass()
    {
        System.out.println("Enter EmptyClass.construct()");
    }

    public void init()
    {
        System.out.println("Enter EmptyClass.init()");
    }

    public void destory()
    {
        System.out.println("Enter EmptyClass.destory()");
    }
}

一个集合类,为了演示集合注入:

public class CollectionClass
{
    private List<String> list;
    private Map<Family, Person> map;
    private int[] ints;

    public List<String> getList()
    {
        return list;
    }

    public void setList(List<String> list)
    {
        this.list = list;
    }

    public Map<Family, Person> getMap()
    {
        return map;
    }

    public void setMap(Map<Family, Person> map)
    {
        this.map = map;
    }

    public int[] getInts()
    {
        return ints;
    }

    public void setInts(int[] ints)
    {
        this.ints = ints;
    }
}

最简单的bean实例化

bean.xml中注入这个bean,以Person类为例:

<?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-4.2.xsd">

    <bean id="person" class="com.xrq.bean.Person" />

</beans>

main函数这么写:

public static void main(String[] args)
{
    ApplicationContext ctx =
            new ClassPathXmlApplicationContext("spring.xml");
    Person person1 = (Person)ctx.getBean("person");
    Person person2 = (Person)ctx.getBean("person");
    System.out.println(person1 == person2);
}

运行结果为true,也就是说Spring默认以单例的形式给开发者构造出指定的bean。另外有两点要注意:

1、同一个spring.xml中不可以定义两个id相同的bean

2、ClassPathXmlApplicationContext中有一个可变长度的构造函数,用于加载多个.xml中的bean,如果bean中有id相同,那么id相同的bean,后加载的会覆盖先加载的

bean的作用域及生命周期

代码不动,把bean.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-4.2.xsd">

    <bean id="person" class="com.xrq.bean.Person" scope="prototype"
        lazy-init="true"/>

</beans>

这里出现了两个属性,scope和lazy-init:

1、scope表示的是bean的作用域,有prototype、request、session、singleton四种,其中singleton是默认的,表示单例。prototype表示每次创建都会产生一个bean实例。request和session只在web项目中才会用,其作用域就和web中的request和session一样

2、lazy-init表示的是bean的生命周期,默认为false。当scope=singleton时,bean会在装在配置文件时实例化,如果希望bean在产生时才实例化,可以把lazy-init设置为true。当scope=prototype时,在产生bean时才会实例化它。补充一点,如果希望该配置文件中所有的bean都延迟初始化,则应该在beans根节点中使用lazy-init="true"

三种注入方式

所谓注入即注入bean中的属性,Spring为用户提供了三种注入方式,settter注入、构造方法注入、注解注入,不过对于Spring的讲解,不讲注解,所以看一下前两种注入方式:

1、setter注入,bean.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-4.2.xsd">

    <bean id="person" class="com.xrq.bean.Person">
        <property name="personName" value="Alice"/>
        <property name="personAge" value="10" />
    </bean>
</beans>

2、构造方法注入,bean.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-4.2.xsd">

    <bean id="family" class="com.xrq.bean.Family">
        <constructor-arg name="person" ref="person" />
        <constructor-arg name="familyName" value="friendly" />
    </bean>

    <bean id="person" class="com.xrq.bean.Person">
        <property name="personName" value="Alice"/>
        <property name="personAge" value="10" />
    </bean>
</beans>

这里故意把family的定义写在person的定义上面,说明即使前面的beanA持有beanB的引用,把beanA定义在beanB前面也不影响

集合注入

spring对于集合属性的支持非常好,以CollectionClass为例,看下如何配置bean.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-4.2.xsd">

    <bean id="collectionClass" class="com.xrq.bean.CollectionClass">
        <property name="list">
            <list>
                <value>111</value>
                <value>222</value>
            </list>
        </property>
        <property name="map">
            <map>
                <entry key="111">
                    <bean class="com.xrq.bean.Person">
                        <property name="personName" value="Mike"/>
                        <property name="personAge" value="11" />
                    </bean>
                </entry>
            </map>
        </property>
        <property name="ints">
            <array>
                <value>333</value>
                <value>444</value>
            </array>
        </property>
    </bean>
</beans>

工厂方式生成类

Spring虽然可以指定bean以单例的方式生成出来,但是每次都要用getBean方法获取类的实例非常麻烦,有办法像单例模式一样使用XXX.getInstance()就好了,不过还真有,以SingletonClass作为例子:

<?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-4.2.xsd">

    <bean id="singletonClass" class="com.xrq.bean.SingletonClass"
        factory-method="getInstance">
    </bean>

</beans>

这样,我们就可以使用单例的方式去调用这个类了,如果类里面有一些私有属性,还可以注入的方式在生成这个bean的时候就注入进去,非常方便

init-method和destory-method

有时候我们希望,在某个bean加载的时候做一些事情,销毁的时候做一些事情(是不是想到了Servlet),所以我们可以自定义初始化和销毁的方法EmptyClass这个类,bean.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-4.2.xsd">

    <bean id="emptyClass" class="com.xrq.bean.EmptyClass"
        init-method="init" destroy-method="destory"/>
</beans>

注意两点:

1、实例化类的时候,几个方法的加载顺序为静态资源->构造方法->初始化方法

2、触发destory()方法的调用可以使用"((ClassPathXmlApplicationContext)ctx).close();",注意scope="prototype"是不会触发destory()的,没有为什么,设计就是这样

父子类继承关系

有时候我们有要求,一个类是某一个类/抽象类的子类,可以这么做:

public abstract class AbstractClass
{

}
public class ImplClass extends AbstractClass
{

}

此时bean.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-4.2.xsd">

    <bean id="abstractClass" class="com.xrq.bean.abstractClass" abstract="true"/>
    <bean id="implClass" class="com.xrq.bean.ImplClass" parent="abstractClass" />
</beans>

注意这种写法对接口也有效。

原文地址:https://www.cnblogs.com/huangyangquan/p/8600779.html

时间: 2025-01-17 16:28:50

Spring学习笔记14---bean的使用的相关文章

Spring学习笔记——02 Bean的命名及实例化

一.Bean的命名 前一篇讲到IoC是一个管理Bean的容器,Bean多数情况下都是通过XML文件进行配置的,其中Bean的命名有以下几种方式,现在梳理一下. 1. 不指定id,只配置类名 <bean class="com.erving.HelloImpl"></bean> 若要调用该Bean,需要用以下语句: HelloApi helloApi = context.getBean(HelloApi.class); 2. 指定id,且id必须在IoC容器中唯一

Spring学习笔记之bean配置

1.命名bean 每个bean都有一个或者多个的的标识符.这些标识符必须在加载他们的容器里边唯一.一个bean经常有且只有一个标识符,但是如果需要超过一个的名字,可以考虑额外的别名. 基于xml的配置源文件,你可以使用id或者name属性去指定bean的标识符,这里有个问题,如果是名字和ID的不一致,内部又是如何处理的? 如果你不想再另外再给他们定义一个别名,你可以指定name属性,利用逗号(,),分号(;)或者空格.spring3.1以前id属性是xsd:ID类型的,这个是唯一的,3.1以后,

Spring学习笔记3 - Bean的生命周期

当一个bean被实例化时,它可能需要执行一些初始化使它转换成可用状态. 当bean不再需要,并且从容器中移除是,可能需要做一些清除工作. 为了定义安装和拆卸一个bean,我们只要声明带有init-method和/或destroy-method参数 init-method属性指定一个方法,在实例化bean时,立即调用该方法. destroy-method指定一个方法,只有从容器中移除bean之后,才能调用该方法. 示例: beans.xml <?xml version="1.0"

Spring学习笔记2 - Bean

Bean是一个被实例化.组装,并通过Spring IoC容器所管理的对象. Bean定义的属性 属性 描述 class 这个属性是强制性的,并且制定用来创建bean的bean类 name 这个属性指定唯一的bean标识符.在基于XML的配置元数据中,可以使用ID和/或name属性来制定bean标识符 scope 指定由特定的bean定义创建的对象的作用域 constructor-arg 用来注入依赖关系 properties 用来注入依赖关系 autowiring mode 用来注入依赖关系 l

Spring学习笔记--注入Bean属性

这里通过一个MoonlightPoet类来演示了注入Bean属性property的效果. package com.moonlit.myspring; import java.util.List; import java.util.Map; import java.util.Map.Entry; import org.springframework.context.ApplicationContext; import org.springframework.context.support.Clas

Spring学习笔记5 - Bean定义继承

bean定义可以包含很多的配置信息,包括构造函数的参数,属性值,容器的具体信息. 例如初始化方法,静态工厂方法名等等. 子bean的定义继承父定义的配置数据.子定义可以根据需要重写一些值,或添加其他值(与Java类的继承概念一致). 当使用基于XML的配置元数据时,通过使用父属性,指定父bean作为该属性的值来表明子bean的定义. 示例: 1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmln

Spring学习笔记之Bean的实例化

一.bean的实例化方法有3种, 1.构造器实例化 2.静态工厂方法实例化 3.实例工厂方法实例化 二.用构造器来实例化 <bean id="ShunDao" class="test.FTPDAO"  > id或者name用于指定bean的名称,class用于指定bean的类型 三.静态工厂方法实例化 <bean id="ShunDao" class="test.FTPDAO" factory-method=

Spring学习笔记之Bean的一些属性设置

1.beans 里边配置default-init-method="shunge",有这个方法的会执行,没有也不会报错 2.beans 里边配置default-destroy-method="shun88",这个只适用于单例模式,而且只在容器销毁的时候被调用 3.lazy-init="true" 可以在容器初始化的时候不加载,随用随加载,不使用不加载 4.depends-on="wait" 和ant里边的依赖都一样,多个用逗号分

mybatis学习笔记(14)-spring和mybatis整合

mybatis学习笔记(14)-spring和mybatis整合 mybatis学习笔记14-spring和mybatis整合 整合思路 整合环境 sqlSessionFactory 原始dao开发和spring整合后 mapper代理开发 遇到的问题 本文主要将如何将spring和mybatis整合,只是作简单的示例,没有使用Maven构建.并展示mybatis与spring整合后如何进行原始dao开发和mapper代理开发. 整合思路 需要spring通过单例方式管理SqlSessionFa

不错的Spring学习笔记(转)

Spring学习笔记(1)----简单的实例 ---------------------------------   首先需要准备Spring包,可从官方网站上下载.   下载解压后,必须的两个包是spring.jar和commons-logging.jar.此外为了便于测试加入了JUnit包.   在Myeclipse中创建Java项目.   编写一个接口类,为了简单,只加入了一个方法.   Java代码   1.package com.szy.spring.interfacebean;