spring中的bean

简介:

环境准备

  • Eclipse上新建一个简单的maven工程,Artifact Id选择maven-archetype-quickstart;
  • 添加spring-context依赖;
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>3.2.16.RELEASE</version>
        </dependency>
  • resources目录下添加spring的配置文件spring.xml;
  • 开始编写bean及测试代码;

Bean的创建方式

默认构造方法创建bean

首先,写一个杂技师类;

  View Code

在spring配置文件中声明该杂技师Bean(未配置<constructor-arg>,将使用默认构造方法);

  <bean id="duke" class="cn.edu.hdu.sia.chapter2.Juggler">
  </bean>

在main方法中使用该杂技师bean;

    public static void main(String[] args) {
        ApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
        Performer performer = (Performer) ctx.getBean("duke");
        performer.perform();
    }

非默认构造方法创建bean

构造方法参数为基本数据类型的情况

接着上例的例子,可以在配置bean的时候,往构造方法传入参数,如下配置,将调用public Juggler(int beanBags)构造方法创建杂技师bean;

  <bean id="duke" class="cn.edu.hdu.sia.chapter2.Juggler">
    <constructor-arg value="15" />
  </bean>

构造方法参数为对象引用类型的情况

现在,我们将要给杂技师增加吟诗行为;

先定义一个诗歌背诵接口:

package cn.edu.hdu.sia.chapter2;

public interface Poem {
    public void recite();
}

再写一个吟诗实现类:

复制代码
package cn.edu.hdu.sia.chapter2;

public class JingYeSi implements Poem{

    public void recite() {
        System.out.println("床前明月光~");
    }

}
复制代码

然后编写吟诗杂耍类:

  View Code

在spring配置文件中声明该杂技师Bean,注意构造方法的第二个参数为对象引用,引用id为“jingyesi”的bean;

可以用index属性指定构造方法参数索引下标,type指定构造方法参数类型,name指定构造方法参数名,用于区分不同的参数;

复制代码
    <bean id="jingyesi" class="cn.edu.hdu.sia.chapter2.JingYeSi">
    </bean>
    
    <bean id="poeticDuke" class="cn.edu.hdu.sia.chapter2.PoeticJuggler">
        <constructor-arg value="15" />
        <constructor-arg ref="jingyesi" />
    </bean>
复制代码

最后参考前面写的main方法测试perform的执行情况,发现该杂技师Bean不仅能杂耍,还能吟诗;

 工厂方法创建bean

当构造方法为私有的时候,是不能够通过构造方法创建bean的,这时候一般通过工厂方法创建,如下为一个典型的单例类,其构造方法为私有属性:

复制代码
package cn.edu.hdu.sia.chapter2;

public class Stage {

    private Stage() {
    }

    private static class StageSingletonHolder {
        static Stage stage = new Stage();
    }

    public static Stage getInstance() {
        return StageSingletonHolder.stage;
    }
    
    public void printDescription(){
        System.out.println("this is a stage.");
    }
}
复制代码

要创建该bean,需要在spring配置文件中做如下配置:

可以用factory-bean属性设置指定的工厂bean,用<constructor-arg>标签往factory-method传入参数;

<bean id="theStage" class="cn.edu.hdu.sia.chapter2.Stage" factory-method="getInstance" />

bean的作用域

所有的bean在spring上下文范围内默认都是“单例”的,即只有一个实例,注意,这里的单例指的是spring上下文范围内的单例;要修改该配置项,只需要配置scope属性,scope默认是singleton,可配置的属性值如下列表:

作用域

定义

singleton

在每一个Spring容器中,一个Bean定义只有一个对象实例(默认)

prototype

运行Bean的定义可以被实例化任意次(每次调用都创建一个实例)

request

在一次HTTP请求中,每个Bean定义对应一个实例,该作用域仅在基于Web的Spring上下文(例如Spring MVC)中才有效

session

在一个HTTP Session中,每个Bean定义对应一个实例,该作用域仅在基于Web的Spring上下文(例如Spring MVC)中才有效

global-session

在一个全局HTTP Session中,每个Bean定义对应一个实例,该作用域仅在Portlet上下文中才有效

bean的初始化和销毁

bean的初始化指bean对象创建后执行的一些操作,如初始化等;

bean的销毁指bean从spring上下文移除时执行的一些操作,如清理,释放资源等;

可以对bean配置init-method和destroy-method属性,指定其初始化方法和销毁方法,如下配置:

    <bean id="theStage" class="cn.edu.hdu.sia.chapter2.Stage" factory-method="getInstance" 
          init-method="init" destroy-method="destroy"/>

其中init和destroy为该bean中自定义的方法,可在里面添加一些初始化和销毁操作;

另外,我们还可以通过实现InitializingBean和DisposableBean接口来完成bean的初始化和销毁操作,具体需要实现以下两个方法即可:

复制代码
    /**
     * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()
     * @throws Exception
     */
    public void afterPropertiesSet() throws Exception {
        // TODO Auto-generated method stub
    }

    /**
     * @see org.springframework.beans.factory.DisposableBean#destroy()
     * @throws Exception
     */
    public void destroy() throws Exception {
        // TODO Auto-generated method stub
    }
复制代码

实现这些接口的缺点是bean与spring api产生了耦合,因此还是推荐使用配置init-method和destroy-method属性实现初始化和销毁;

额外说下,在非web应用程序中,关闭spring上下文可以通过调用close方法或registerShutdownHook方法,区别如下:

close:立刻关闭spring上下文(容器);

registerShutdownHook:等到JVM关闭的时候再关闭spring上下文(容器);

如下代码段示例,bean的销毁方法不会马上执行,而是在JVM销毁后才执行:

复制代码
    public static void main(String[] args) {
        AbstractApplicationContext ctx = new ClassPathXmlApplicationContext("spring.xml");
        Stage stage = (Stage) ctx.getBean("theStage");
        stage.printDescription();
        ctx.registerShutdownHook();

        try {
            TimeUnit.MILLISECONDS.sleep(1000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println("start JVM desdroy.");
    }
复制代码

配置bean的属性

bean属性为基本数据类型情况(bean中需要有setter方法)

    <bean id="peter" class="cn.edu.hdu.sia.chapter2.User">
        <property name="name" value="Peter"></property>
        <property name="age" value="22"></property>
    </bean>

bean属性为对象引用的情况

属性bean通过外部注入

复制代码
    <bean id="jingyesi" class="cn.edu.hdu.sia.chapter2.JingYeSi"></bean>
    
    <bean id="peter" class="cn.edu.hdu.sia.chapter2.User">
        <property name="name" value="Peter"></property>
        <property name="age" value="22"></property>
        <property name="poem" ref="jingyesi"></property>
    </bean>
复制代码

属性bean通过内部注入,同样适用于构造方法的入参<constructor-arg>,注意:外部其它bean不能引用内部bean

复制代码
    <bean id="peter" class="cn.edu.hdu.sia.chapter2.User">
        <property name="name" value="Peter"></property>
        <property name="age" value="22"></property>
        <property name="poem">
            <bean class="cn.edu.hdu.sia.chapter2.JingYeSi"/>
        </property>
    </bean>
复制代码

另外,还可以使用spring的p命名空间来配置属性:

<bean id="peter" class="cn.edu.hdu.sia.chapter2.User" p:name="Peter" p:age="22" />

bean属性为集合的情况

可使用如下四种配置

 

集合元素

用途

对应实际数据类型

<list>

装配list类型的值,允许重复

数组或java.util.Collection

<set>

装配set类型的值,不允许重复

<map>

装配map类型的值,名称和值可以是任意类型

java.util.Map

<props>

装配properties类型的值,名称和值必须都是String

java.util.Properties

 

List、Set、Array

这里的list也可以用set替换,区别仅仅是允不允许重复

复制代码
    <bean id="jingyesi" class="cn.edu.hdu.sia.chapter2.JingYeSi"></bean>
    <bean id="xinglunan" class="cn.edu.hdu.sia.chapter2.XingLuNan"></bean>
    
    <bean id="peter" class="cn.edu.hdu.sia.chapter2.User">
        <property name="name" value="Peter"></property>
        <property name="age" value="22"></property>
        <property name="poemList">
            <list>
                <ref bean="jingyesi" />
                <ref bean="xinglunan" />
            </list>
        </property>
    </bean>
复制代码

map

复制代码
    <bean id="jingyesi" class="cn.edu.hdu.sia.chapter2.JingYeSi"></bean>
    <bean id="xinglunan" class="cn.edu.hdu.sia.chapter2.XingLuNan"></bean>
    
    <bean id="peter" class="cn.edu.hdu.sia.chapter2.User">
        <property name="name" value="Peter"></property>
        <property name="age" value="22"></property>
        <property name="poemMap">
            <map>
                <entry key="jingyesi" value-ref="jingyesi"/>
                <entry key="xinglunan" value-ref="xinglunan"/>
            </map>
        </property>
    </bean>
复制代码

Properties

复制代码
    <bean id="peter" class="cn.edu.hdu.sia.chapter2.User">
        <property name="name" value="Peter"></property>
        <property name="age" value="22"></property>
        <property name="properties">
            <props>
                <prop key="test1">111</prop>
                <prop key="test2">222</prop>
            </props>
        </property>
    </bean>
复制代码

bean属性值设为null情况

复制代码
    <bean id="peter" class="cn.edu.hdu.sia.chapter2.User">
        <property name="name" value="Peter"></property>
        <property name="age" value="22"></property>
        <property name="properties">
         <null/>
        </property>
    </bean>
复制代码
本文转自风一样的码农博客园博客,原文链接:http://www.cnblogs.com/chenpi/p/5474561.html,如需转载请自行联系原作者
相关文章
|
22天前
|
缓存 Java Spring
Spring 框架中 Bean 的生命周期
Spring 框架中 Bean 的生命周期
30 1
|
1月前
|
XML Java 开发者
Spring Boot中的bean注入方式和原理
Spring Boot中的bean注入方式和原理
49 0
|
1月前
|
XML 缓存 Java
Spring源码之 Bean 的循环依赖
循环依赖是 Spring 中经典问题之一,那么到底什么是循环依赖?简单说就是对象之间相互引用, 如下图所示: 代码层面上很好理解,在 bean 创建过程中 class A 和 class B 又经历了怎样的过程呢? 可以看出形成了一个闭环,如果想解决这个问题,那么在属性填充时要保证不二次创建 A对象 的步骤,也就是必须保证从容器中能够直接获取到 B。 一、复现循环依赖问题 Spring 中默认允许循环依赖的存在,但在 Spring Boot 2.6.x 版本开始默认禁用了循环依赖 1. 基于xml复现循环依赖 定义实体 Bean java复制代码public class A {
|
1月前
|
存储 NoSQL Java
Spring Boot统计一个Bean中方法的调用次数
Spring Boot统计一个Bean中方法的调用次数
33 1
|
2月前
|
Java 索引 Spring
spring创建bean的过程
spring创建bean的过程
|
3月前
|
缓存 Java Spring
Spring循环依赖原理和Bean创建过程
Spring循环依赖原理和Bean创建过程
69 0
|
6天前
|
Java 数据库连接 开发者
浅谈Spring的Bean生命周期
浅谈Spring的Bean生命周期
15 1
|
11天前
|
XML Java 数据格式
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
19 0
Bean工厂探秘:解析Spring底层工厂体系BeanFactory的神奇之道
|
21天前
|
XML Java 程序员
作为Java程序员还不知道Spring中Bean创建过程和作用?
作为Java程序员还不知道Spring中Bean创建过程和作用?
13 0
|
26天前
|
XML 缓存 Java
天天用 Spring,bean 实例化原理你懂吗
天天用 Spring,bean 实例化原理你懂吗
17 0

热门文章

最新文章