posts - 66,  comments - 11,  trackbacks - 0
构造函数注入:
Set注入法的缺点是,它无法清晰的表示出哪些属性是必须的,哪些是可选的。而构造函数注入法的优势是通过构造函数来强制依赖关系。
使用Set注入时,我们通过<property>元素来注入属性的值。构造函数注入也一样,只不过是通过<bean>元素下的<constructor-arg>元素来指定实例化这个bean的时候需要传递的参数。constructor-arg没有name属性。

解决构造函数参数的不确定性:
有2种方法可以用来处理构造函数的不确定性:通过序号和类型。<constructor-arg>元素有一个可选的index属性,可以用它来指定构造函数的顺序。
<bean id="foo" class="com.springinaction.Foo">
    <constructor-arg index="1">
        <value>http://www.manning.com</value>
    </constructor>
    <constructor-arg index="0">
        <value>http://www.springinaction.com</value>
    </constructor>
</bean>
另一种方法是使用type属性。可以通过type属性确定参数的类型
<bean id="foo" class="com.springinaction.Foo">
    <constructor-arg type="java.lang.String">
        <value>http://www.manning.com</value>
    </constructor>
    <constructor-arg type="java.net.URL">
        <value>http://www.springinaction.com</value>
    </constructor>
</bean>

使用构造函数注入的理由:
1、构造函数注入强制使用依赖契约。就是如果没有提供所有需要的依赖,一个Bean就无法被实例化。
2、由于Bean的依赖都通过它的构造函数设置了,所以没有必要再写多余的Set方法。
3、因为只能通过构造函数设置类的属性,这样你有效的保证了属性的不可变性。
Set注入的依据:
1、如果Bean有很多依赖,那么构造函数的参数列表会很长。
2、构造函数只能通过参数的个数和类型来区分。
3、如果构造函数的参数中有2个以上是相同类型的,那么很难确定每个参数的用途。
4、构造函数注入不利于自身的继承。

自动装配:
你可以让Spring自动装配,只要设置需要自动装配的<bean>中的autowire属性。
<bean id="foo" class="com.springinaction.Foo" autowire="autowire type"/>
byName-视图在容器中寻找和需要自动装配的属性名相同的Bean.
byType-视图在容器中寻找一个与需要自动配置的属性类型相同的Bean.
constructor-视图在容器中查找与需要自动装配的Bean的构造参数一致的一个或多个Bean.
autodetect-首先尝试使用congstructor来自动装配,然后使用byType方式。

使用Spring的特殊Bean
编写一个后处理Bean,Spring为你提供了2次机会,让你切入到Bean的生命周期中,检查或者修改它的配置,这叫做后处理,后处理实在Bean实例化以及装配完成之后发生的。postProcessBeforeInitialization()方法在Bean初始化之前被调用。postProcessAfterInitialization()方法在初始化之后马上被调用。
package com.wyq.hibernate;


import java.lang.reflect.Field;

import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;

public class Fuddifier implements BeanPostProcessor {
    
/**
     * postProcessAfterInitialization()方法循环Bean的所有属性,寻找java.lang.String类型的属性。对于每个String属性,把它传递给
     * fuddify()方法,这个方法将String将变成唠叨用语。
     
*/
    
public Object postProcessAfterInitialization(Object bean, String name)
            
throws BeansException {
        Field[] fields 
= bean.getClass().getDeclaredFields();
        
try{
            
for(int i=0;i<fields.length;i++){
                
if(fields[i].getType().equals(java.lang.String.class)){
                    fields[i].setAccessible(
true);
                    String original 
= (String)fields[i].get(bean);
                    fields[i].set(bean,fuddify(original));
                }
            }
        }
catch(IllegalAccessException e){
            e.printStackTrace();
        }
        
return bean;
    }
    
/**
     * postProcessBeforeInitialization()方法没有做任何有意义的工作,它只是简单的返回没有修改过的Bean.
     
*/
    
public Object postProcessBeforeInitialization(Object bean, String name)
            
throws BeansException {
        
return bean;
    }
    
private String fuddify(String orig){
        
if(orig==null)return orig;
        
return orig.replaceAll("(r|l)""w").replaceAll("(R|L)""W");
    }

}


注册后处理Bean:如果你的应用系统运行在Bean工厂中,你需要调用工厂的addBeanPostProcessor()方法来注册BeanPostProcessor.
BeanPostProcessor fuddifier = new Fuddifier();
factory.addBeanPostProcessor(fuddifier);
如果你是使用应用上下文,你只需要像注册其他Bean那样注册后处理Bean.



posted on 2009-10-29 14:59 王永庆 阅读(250) 评论(0)  编辑  收藏 所属分类: SPRING

只有注册用户登录后才能发表评论。


网站导航:
博客园   IT新闻   Chat2DB   C++博客   博问  
 
<2009年10月>
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

常用链接

留言簿(1)

随笔分类

随笔档案

关注blogs

搜索

  •  

最新评论

阅读排行榜

评论排行榜