zoukankan      html  css  js  c++  java
  • 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

    首先,写一个杂技师类;

    package cn.edu.hdu.sia.chapter2;
    
    public class Juggler implements Performer {
        private int beanBags = 3;
    
        public Juggler() {
        }
    
        public Juggler(int beanBags) {
            this.beanBags = beanBags;
        }
    
        public void perform() throws PerformanceException {
            System.out.println("JUGGLING " + beanBags + " BEANBAGS");
        }
    }
    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("床前明月光~");
        }
    
    }

    然后编写吟诗杂耍类:

    package cn.edu.hdu.sia.chapter2;
    
    public class PoeticJuggler extends Juggler {
    
        private Poem poem;
    
        public PoeticJuggler(int beanBags, Poem poem) {
            super(beanBags);
            this.poem = poem;
        }
    
        /**
         * @see cn.edu.hdu.sia.chapter2.Juggler#perform()
         * @throws PerformanceException
         */
        @Override
        public void perform() throws PerformanceException {
            super.perform();
            poem.recite();
        }
    }
    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>

     demo代码下载

    http://files.cnblogs.com/files/chenpi/sia.7z

  • 相关阅读:
    Microsoft Enterprise Library 5.0 系列(二) Cryptography Application Block (初级)
    Microsoft Enterprise Library 5.0 系列(五) Data Access Application Block
    Microsoft Enterprise Library 5.0 系列(八) Unity Dependency Injection and Interception
    Microsoft Enterprise Library 5.0 系列(九) Policy Injection Application Block
    Microsoft Enterprise Library 5.0 系列(三) Validation Application Block (高级)
    软件研发打油诗祝大家节日快乐
    从挖井的故事中想到开发管理中最容易忽视的几个简单道理
    ITIL管理思想的执行工具发布
    管理类软件设计“渔”之演化
    20070926日下午工作流与ITILQQ群 事件管理 讨论聊天记录
  • 原文地址:https://www.cnblogs.com/chenpi/p/5474561.html
Copyright © 2011-2022 走看看