• 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

  • 相关阅读:
    【C#】Color颜色对照表
    eslint的实践
    关于babel和webpack结合使用的实践
    前端学习博客
    css学习4--网格布局
    css学习3--flexbox布局
    CSS学习2-布局介绍
    css学习1
    前端性能优化
    line-height介绍
  • 原文地址:https://www.cnblogs.com/chenpi/p/5474561.html
Copyright © 2020-2023  润新知