zoukankan      html  css  js  c++  java
  • Spring中Bean的配置:基于XML文件的方式

    Bean的配置一共有两种方式:一种是基于XML文件的方式,另一种是基于注解的方式。
    本文主要介绍基于XML文件的方式

    <bean id="helloWorld" class="com.sevenhu.domain.HelloWorld">
         <property name="userName" value="Spring"></property>
    </bean>

    上面的配置代码中:
         id:Bean的名称,在IOC容器中必须是唯一的,若id,没有指定,那么Spring自动将类名作为Bean的名字,id可以指定多个名字,名字之间可用逗号,分 号,或空格分隔。
    Spring容器
          在Spring IOC容器读取Bean配置创建Bean实例之前,必须对它进行实例化,只有在容器实例化之后,才可以从IOC容器里获取Bean的实例并使用。
          Spring提供了两种类型的IOC容器实现
             -BeanFactory:Ioc容器的基本实现。
            -ApplicationContext:提供了更多的高级特性。是BeanFactory的子接口。
            -BeanFactory是Spring框架的基础设施,面向Spring本身;ApplicationContext面向使用Spring框架的开发者。
         ApplicationContext主要有两个实现类:
           -ClassPathXmlApplicationContext:从类路径下加载配置文件。
           -FileSystemXmlApplicationContext:从文件系统中加载配置文件。
            ApplicationContext在初始化上下文时就实例化所有单例的bean。
    属性注入:
          即通过setter方法注入bean的属性值或依赖的对象。属性注入使用<property>元素,使用name属性值指定bean的属性名称,value属性指定属性值。使用这种注入方式,那么bean中必须有一个默认的构造函数,即无参的构造函数。
       

    eg:
           <property name="userName" value="Spring"></property>

    构造方法注入:
         按索引匹配入参:

    <bean id="car" class="com.sevenhu.domain.Car">
           <constructor-arg value="长春一汽" index="0"></constructor-arg>
           <constructor-arg value="2000" index="1"></constructor-arg>
           <constructor-arg value="奥迪" index="2"></constructor-arg>
    </bean>

    按类型匹配入参:

    <bean id="car2" class="com.sevenhu.domain.Car">
            <constructor-arg value="长春一汽" type="java.lang.String"></constructor-arg>
            <constructor-arg value="2000" type="double"></constructor-arg>
            <constructor-arg value="奥迪" type="java.lang.String"></constructor-arg>
    </bean>

    注:字面值都可用字符串表示,可以通过<value>元素标签或value属性进行注入。基本数据类型及其封装类,String等类型都可以采用字面值注入的方 式。
      如果一个bean的某一个属性是一个对象,可使用如下配置:

    <bean id="people" class="com.sevenhu.domain.People">
           <property name="name" value="hujingwei"></property>
           <property name="car" ref="car2"></property>
    </bean>

    或者使用内部类:

          <bean id="people1" class="com.sevenhu.domain.People">
                  <property name="name" value="zhangsongzhu"></property>
                  <property name="car">
                         <!--内部bean,不能被外部的bean所引用,因此没有必要设置id-->
                         <bean class="com.sevenhu.domain.Car">
                                <property name="brand" value="Ford"></property>
                                <property name="creator" value="SomeOne"></property>
                                <property name="price" value="100000"></property>
                         </bean>
                  </property>
           </bean>
    

      可以使用专用的<null/>元素标签为Bean的字符串或其它对象的属性值注入null值,如下:

      <bean id="people2" class="com.sevenhu.domain.People">
                  <property name="name" value="hu"></property>
                  <!--若某一个bean的属性值需要设置为null-->
                  <property name="car"><null/></property>
      </bean>
    

      使用p命名空间:

         为了简化XML文件的配置,越来越多的XML文件使用属性而非子元素配置信息,因此Spring自从2.5之后就引入了一个p命名空间,可以通过<bean>元素属性的方式配置Bean的属性

    <!--使用p命名空间-->
           <bean id="people3" class="com.sevenhu.domain.People" p:name="seven" p:car-ref="car1">
           </bean>
    

      XML配置里的Bean自动装配

            Spring IOC容器可以自动装配bean,需要做的仅仅是在<bean>的autowire属性中指定自动装配的模式,具体的装配模式如下:

                   -byType(根据类型装配):若IOC容器中有多个与目标bean类型一致的bean,在这种情况下,Spring将无法判定哪个bean最适合该属性,所以不能进行自动装配。

                  -byName(根据名称自动装配):必须将目标bean的名称和属性名设置的完全相同。

            自动装配的缺点:在bean配置文件里设置autowire属性进行自动装配将会装配bean的所有属性,然而,若只希望装配个别属性,autowire不够灵活;autowire属性要么根据类型装配,要么根据名称装配,不能两者兼而有之。

    继承bean配置

          Spring允许继承bean的配置,被继承的bean称为父bean,继承这个bean的bean为子bean。子bean从父bean中继承配置,包括bean的属性配置,子bean也可以覆盖从父bean继承过来的配置,父bean可以作为配置模版,也可以作为bean实例,若指向把父bean作为模版,可以设置bean的abstract属性为true,这样Spring就不会实例化这个bean。并不是父bean中所有的属性都会被继承,比如:autowire,abstract等;也可以忽略父bean的class属性,让子bean指定自己的类,而共享相同的属性配置,但是此时abstract必须设为true。

          

    <bean id="user" class="com.*.*">
            <property name="userName" value="hu"/>
    </bean>
    <bean id="user1" parent="user">
            <property name="userName" value="hu"/>
    </bean>
    <bean id="user2" parent="user">
            <property name="userName" value="hu"/>
    </bean>
    

    依赖bean配置:

        Spring允许用户通过depends-on属性设定bean前置依赖的bean,前置依赖的bean会在bean实例化之前创建好,如果前置依赖多个bean,则可以通过逗号,空格的方式配置bean的名称。

    <bean id="user3" depends-on="user1">
    </bean>
    

      bean的作用域(通过<bean>标签的scope属性设置)

               -singleton  在Spring IOC容器中只存在一个bean实例,bean以单例的方式存在(默认的作用域)

              -prototype   每次调用getBean()时都会返回一个新的实例

               -request   每次HTTP请求都会返回一个新的bean,该作用域仅适用于WebApplicationContext环境中

               -session   在session中共享一个bean,该作用域仅适用于WebApplicationContext环境中

       使用外部属性文件:

        首先外部文件db.properties的内容如下:

    jdbc.user=root
    jdbc.password=1230
    jdbc.driverClass=com.mysql.jdbc.Driver
    jdbc.jdbcUrl=jdbc:mysql:///test
    jdbc.initPoolSize=5
    jdbc.maxPoolSize=10
    

      那么在配置文件中配置如下:

        <!-- 导入外部的资源文件 -->
        <context:property-placeholder location="classpath:db.properties"/>
        
        <!-- 配置数据源 -->
        <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
            <property name="user" value="${jdbc.user}"></property>
            <property name="password" value="${jdbc.password}"></property>
            <property name="driverClass" value="${jdbc.driverClass}"></property>
            <property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
            
            <property name="initialPoolSize" value="${jdbc.initPoolSize}"></property>
            <property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
        </bean>

    IOC容器中Bean的生命周期

         -通过构造器或工厂方法创建bean实例

         -为bean的属性设置值和对其它bean的引用

         -调用bean的初始化方法

         -bean可以使用了

         -当容器关闭的时候,调用bean的销毁方法。

    注:当bean的声明里设置init-method和destroy-method属性,为bean指定初始化和销毁方法(这两个方法一般都没有参数)

    创建bean的后置处理器

          bean后置处理器允许在调用初始化方法前后对bean进行额外的处理,bean后置处理器对IOC容器里所有bean实例逐一处理,而非单一实例。对bean的后置处理器而言,需要实现

    Interface BeanPostProcessor接口,在初始化方法被调用前后,Spring将把每个bean实例分别传递给BeanPostProcessor接口的以下两个方法:

    postProcessorAfterInitialization(Object bean,String beanName);
    postProcessorBeforeInitialization(Object bean,String beanName);
    

    添加后置处理器后Bean的生命周期

         -通过构造器或工厂方法创建bean实例

         -为bean的属性设置值和对其它bean的引用

         -将bean实例传递给后置处理器的postProcessorBeforeInitialization(Object bean,String beanName);方法

         -调用bean的初始化方法

         -将bean实例传递给后置处理器的postProcessorAfterInitialization(Object bean,String beanName);方法

         -bean可以使用了

         -当容器关闭的时候,调用bean的销毁方法。

    代码如下:

       

    package com.sevenhu.domain;
    
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.BeanPostProcessor;
    import org.springframework.context.ApplicationContext;
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * Created by hu on 2016/4/1.
     */
    public class MyBean implements BeanPostProcessor {
        //该方法在bean的初始化方法之前调用
        @Override
        public Object postProcessBeforeInitialization(Object o, String s) throws BeansException {
            //o就是bean实例对象,s就是bean实例的id
            System.out.println("before initialication ....");
            //返回bean的实例对象
            return o;
        }
        
        //该方法在bean的初始化方法之后调用
        @Override
        public Object postProcessAfterInitialization(Object o, String s) throws BeansException {
            System.out.println("after initialication ....");
            return o;
        }
        public static void main(String[] args){
            ApplicationContext applicationContext=new ClassPathXmlApplicationContext("beans.xml");
        }
    }
    

      配置代码如下:

           <!--配置bean后置处理器:不需要配置id属性,IOC容器会识别到它是一个bean后置处理器,并调用其方法-->
           <bean class="com.sevenhu.domain.MyBean"></bean>
    

    通过调用静态工厂方法创建bean

         调用静态工厂方法创建bean是将对象创建的过程封装到静态方法中,当客户端需要对象时,只需要简单地调用静态方法,而不关心创建对象的细节。

    直接上代码,工厂如下:

        

        <!-- 通过工厂方法的方式来配置 bean -->
        <!-- 1. 通过静态工厂方法: 一个类中有一个静态方法, 可以返回一个类的实例(了解) -->
        <!-- 在 class 中指定静态工厂方法的全类名, 在 factory-method 中指定静态工厂方法的方法名 -->
        <bean id="dateFormat" class="java.text.DateFormat" factory-method="getDateInstance">
            <!-- 可以通过 constructor-arg 子节点为静态工厂方法指定参数 -->
            <constructor-arg value="2"></constructor-arg>
        </bean>
        
        <!-- 2. 实例工厂方法: 先需要创建工厂对象, 再调用工厂的非静态方法返回实例(了解) -->
        <!-- ①. 创建工厂对应的 bean -->
        <bean id="simpleDateFormat" class="java.text.SimpleDateFormat">
            <constructor-arg value="yyyy-MM-dd hh:mm:ss"></constructor-arg>
        </bean>
        
        <!-- ②. 有实例工厂方法来创建 bean 实例 -->
        <!-- factory-bean 指向工厂 bean, factory-method 指定工厂方法(了解) -->
        <bean id="datetime" factory-bean="simpleDateFormat" factory-method="parse">
            <!-- 通过 constructor-arg 执行调用工厂方法需要传入的参数 -->
            <constructor-arg value="1990-12-12 12:12:12"></constructor-arg>
        </bean>
  • 相关阅读:
    Java的静态块与实例块(转)
    Programming Ability Test学习 1031. Hello World for U (20)
    Programming Ability Test学习 1011. World Cup Betting (20)
    Programming Ability Test学习 1027. Colors in Mars (20)
    Programming Ability Test学习 1064. Complete Binary Search Tree (30)
    Programming Ability Test学习 1008. Elevator (20)
    【maven详解-生命周期】Maven的生命周期和插件
    【maven详解-插件】maven插件学习之源码插件Source Xref
    $(document).ready(){}、$(fucntion(){})、(function(){})(jQuery)onload()的区别
    你还没真的努力过,就轻易输给了懒惰
  • 原文地址:https://www.cnblogs.com/hujingwei/p/5342036.html
Copyright © 2011-2022 走看看