zoukankan      html  css  js  c++  java
  • Spring2:bean的使用

    转自原文 Spring2: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>

     

     

  • 相关阅读:
    入门菜鸟
    FZU 1202
    XMU 1246
    Codeforces 294E Shaass the Great 树形dp
    Codeforces 773D Perishable Roads 最短路 (看题解)
    Codeforces 814E An unavoidable detour for home dp
    Codeforces 567E President and Roads 最短路 + tarjan求桥
    Codeforces 567F Mausoleum dp
    Codeforces 908G New Year and Original Order 数位dp
    Codeforces 813D Two Melodies dp
  • 原文地址:https://www.cnblogs.com/arxive/p/9881184.html
Copyright © 2011-2022 走看看