zoukankan      html  css  js  c++  java
  • Sping中Bean配置的深入探讨

    一、p命名空间的使用
    Spring 从 2.5 版本开始引入了一个新的 p 命名空间,可以通过 <bean> 元素属性的方式配置 Bean 的属性。使用 p 命名空间后,基于 XML 的配置方式将进一步简化。

    简化前:


    <bean id="user" class="com.kang.TestUser">
    		<!-- 为属性赋值 -->
    		<property name="userName" value="kang"></property>
    </bean>


    简化后:
    <bean id="user" class="com.kang.TestUser" p:userName="kang"></bean>


    二、继承和依赖Bean的配置
    1、Spring允许继承bean的配置,可以通过<bean>的parent属性来完成继承。子Bean从父Bean中继承配置, 包括Bean的属性配置。子Bean也可以覆盖从父Bean继承过来的配置。
    父Bean可以作为配置模板, 也可以作为Bean实例. 若只想把父Bean作为模板, 可以设置<bean>的abstract属性为true, 这样 Spring将不会实例化这个Bean。
    示例:

    <bean id="user" class="com.kang.TestUser" p:userName="kang"></bean>
    <!-- 继承自user -->
    <bean id="user1" parent="user" ></bean>
    <!-- 继承自user,且覆盖了user的原属性值 -->
    <bean id="user2" parent="user" p:userName="Jack"></bean>
    



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

    <!-- 继承自user,且覆盖了user的原属性值。并且依赖于user1这个bean -->
    <bean id="user3" parent="user" p:userName="Jack" depends-on="user1"></bean>




    三、在Sping的bean配置文件中使用外部属性文件
    在Sping配置文件里配置Bean时, 有时需要混入系统部署的细节信息(例如: 文件路径, 数据源配置信息等),而这些部署细节实际上需要和Bean配置相分离。
    Spring 提供了一个 PropertyPlaceholderConfigurer的BeanFactory后置处理器, 这个处理器允许用户将Bean配置的部分内容外移到属性文件中。可以在Bean配置文件里使用形式为 ${var}的变量, PropertyPlaceholderConfigurer从属性文件里加载属性, 并使用这些属性来替换变量。
    示例:
    假设在类路径下创建一个文件,名为db.properties,用来存放外部信息。内容如下:

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



    在bean配置文件中,可以通过如下方式访问上述外部文件信息。

      <!-- 导入外部的资源文件,classpath表示文件在类路径下-->
    	<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>
    
    



    四、Spring表达式语言(SpEL)
    Spring 表达式语言(简称SpEL):是一个支持运行时查询和操作对象图的强大的表达式语言。语法类似于 EL:SpEL 使用 #{…} 作为定界符,所有在大框号中的字符都将被认为是 SpEL。
    通过 SpEL 可以实现:通过bean的id对bean进行引用;调用方法以及引用对象中的属性;计算表达式的值;正则表达式的匹配;
    示例:
    1、字面量的表示
    <property name="count" value="#{5}"/>
    2、引用其他bean对象的属性

    <bean id="father" class="com.kang.Father">
    	<property name="fatherName" value="Jack"></property>
    </bean>
    <bean id="child" class="com.kang.Child">
            <property name="childName" value="Tom"></property>
    	<property name="fatherName" value="#{father.fatherName}"></property>
    </bean>


    3、调用其他方法,还可以链式操作
    <property name="fatherName" value="#{father.fatherName.toString()}"></property>




    五、IOC容器中Bean的生命周期
    Spring IOC容器对Bean的生命周期进行管理的过程:
    1、通过构造器或工厂方法创建Bean实例;
    2、为 Bean的属性赋值;
    3、调用Bean的初始化方法(init-method);
    4、Bean可以使用了;
    5、当容器关闭时, 调用 Bean 的销毁方法(destroy-method)。
    可以通过在Bean的声明里设置init-method和destroy-method属性, 为Bean指定初始化方法和销毁方法。
    Bean后置处理器允许在调用初始化方法前后对Bean进行额外的处理。它对IOC容器里的所有Bean实例逐一处理, 而非处理单一实例. 其典型应用是: 检查 Bean 属性的正确性或根据特定的标准更改 Bean 的属性。
    对Bean后置处理器而言, 需要实现 BeanPostProcessor这个接口。在初始化方法被调用前后, Spring将把每个Bean实例分别传递给上述接口的以下两个方法:postProcessAfterInitialization(初始化后处理)和postProcessBeforInitialization(初始化前处理)。
    这样加入后置处理器后,Spring IOC容器对Bean的生命周期进行管理的过程:
    1、通过构造器或工厂方法创建Bean实例;
    2、为 Bean的属性赋值;
    3、将Bean实例传递给Bean后置处理器的 postProcessBeforeInitialization 方法;
    4、调用Bean的初始化方法;
    5、将Bean实例传递给Bean后置处理器的 postProcessAfterInitialization方法;
    6、Bean可以使用了;
    7、当容器关闭时, 调用Bean的销毁方法。
    示例:

    public class MyBeanPostProcessor implements BeanPostProcessor {
    
    	//该方法在 init 方法之前被调用
    	/**
    	 * @param arg0: 实际要返回的对象
    	 * @param arg1: bean 的 id 值
    	 */
    	@Override
    	public Object postProcessBeforeInitialization(Object arg0, String arg1)
    			throws BeansException {
    		if(arg1.equals("user"))
    			System.out.println("postProcessBeforeInitialization..." + arg0 + "," + arg1);
    		return arg0;
    	}
    
    
    	//该方法在 init 方法之后被调用
    	/**
    	 * @param arg0: 实际要返回的对象
    	 * @param arg1: bean 的 id 值
    	 */
    	@Override
    	public Object postProcessAfterInitialization(Object arg0, String arg1)
    			throws BeansException {
    		if(arg1.equals("user")){
    			System.out.println("postProcessAfterInitialization..." + arg0 + "," + arg1);
    			//可以替代原初始化对象返回
                            User user = (User) arg0;
    			user.setUserName("kang");
    		}
    		return arg0;//替换了原来的bean对象
    	}
    
    
    }
    



    六、创建 Bean的两种方法
    1、调用静态工厂方法创建Bean
    调用静态工厂方法创建Bean是将对象创建的过程封装到静态方法中。 当客户端需要对象时, 只需要简单地调用静态方法, 而不同关心创建对象的细节。
    要声明通过静态方法创建的Bean, 需要在Bean的class属性里指定拥有该工厂的方法的类, 同时在factory-method属性里指定工厂方法的名称。最后, 使用 <constrctor-arg> 元素为该方法传递方法参数。
    示例:

       <!-- 通过工厂方法的方式来配置 bean -->
    	<!-- 在 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,需要在bean的factory-bean属性里指定拥有该工厂方法的Bean,并且在factory-method属性里指定该工厂方法的名称。之后使用 construtor-arg 元素为工厂方法传递方法参数。
    示例:

    <!-- 实例工厂方法-->
    	<!-- ①. 创建工厂对应的 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>



  • 相关阅读:
    MyBatis简介
    JDBC报错:Cannot find class: com.mysql.jdbc.Driver
    进程,线程,协程
    mamp提示 more elements...
    获取html页面的参数
    php基础函数
    返回接口
    生成订单号
    xml转数组
    判断是否是微信浏览器
  • 原文地址:https://www.cnblogs.com/kangsir/p/6653246.html
Copyright © 2011-2022 走看看