《Pro Spring》学习笔记之FactoryBean使用(非BeanFactory)

看清楚了,不是BeanFactory,而是FactoryBean

使用spring的时候,我们或许後碰到这样的问题:如何创建,然后注入纳西无法直接用new关键字创建的依赖对象,为解决这个问题,spring提供了FactoryBean接口,使用FactoryBean.getObject()来返回实例,典型用途可以说是创建事务型代理 ,但本文以加密类MessageDigest做例子讲解

Java的MessageDigest提供了为任何数据类型摘要的功能,本身为abstract,通过MessageDigest.getInstnace()来返回使用不同算法的实例,如messageDigest=MessageDigest.getInstance("MD5");/

如果想使用spring管理MessageDigest对象的创建,不用FactoryBean的话,最佳方法是位bean增加一个algorthmName,然后通过初始化回调来调用MessageDigest.getInstnace()。借助FactoryBean,我么可以把上述逻辑封装在一个bean里任何需要MessageDigest的实例bean可以直接生命属性messageDigest,通过FactoryBean来获得这个实例

MessageDigestFactoryBean.java

 

package  ch5.FactoryBean;

import  java.security.MessageDigest;

import  org.springframework.beans.factory.FactoryBean;
import  org.springframework.beans.factory.InitializingBean;

public   class  MessageDigestFactoryBean  implements  InitializingBean, FactoryBean  {
    
private String algorithName="MD5";
    
private MessageDigest messageDigest=null;
    
public String getAlgorithName() {
        
return algorithName;
    }


    
public void setAlgorithName(String algorithName) {
        
this.algorithName = algorithName;
    }


    
public void afterPropertiesSet() throws Exception {
        messageDigest
=MessageDigest.getInstance(algorithName);

    }


    
public Object getObject() throws Exception {
        
return messageDigest.clone();
    }


    
public Class getObjectType() {
        
return MessageDigest.class;
    }


    
public boolean isSingleton() {
        
return true;
    }


}

 

MessageDigester.java

 

package  ch5.FactoryBean;

import  java.security.MessageDigest;

import  sun.misc.BASE64Decoder;
import  sun.misc.BASE64Encoder;

public   class  MessageDigester  {
  
private MessageDigest digest1=null;
  
private MessageDigest digest2=null;
  
  
  
public void digest(String msg)
  
{
    System.out.println(
"Using digest1");
    digest(msg,digest1);
    System.out.println(
"Using digest2");
    digest(msg,digest2);
  }

  
  
public void digest(String msg,MessageDigest digest){
      System.out.println(
"Using algorithem:"+digest.getAlgorithm());
      digest.reset();
      
byte[] bytes=msg.getBytes();
      
byte[] out=digest.digest(bytes);
      BASE64Encoder encoder
=new BASE64Encoder();
      System.out.println(encoder.encode(out));
  }

  
public MessageDigest getDigest1() {
    
return digest1;
}

public void setDigest1(MessageDigest digest1) {
    
this.digest1 = digest1;
}

public MessageDigest getDigest2() {
    
return digest2;
}

public void setDigest2(MessageDigest digest2) {
    
this.digest2 = digest2;
}

}

 

配置文件:一个使用SHA1算法,一个是默认的MD5

 

<? 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-2.0.xsd" >


< bean  id ="shaiDigest"  class ="ch5.FactoryBean.MessageDigestFactoryBean" >
  
< property  name ="algorithName" >
    
< value > SHA1 </ value >
  
</ property >
</ bean >

< bean  id ="defalutDigent"  class ="ch5.FactoryBean.MessageDigestFactoryBean" >   
</ bean >

< bean  id ="digester"  class ="ch5.FactoryBean.MessageDigester" >
  
< property  name ="digest1" >
    
< ref  local ="shaiDigest" />
  
</ property >
  
< property  name ="digest2" >
    
< ref  local ="defalutDigent" />
  
</ property >
</ bean >
</ beans >

 

运行结果:

Using digest1
Using algorithem:SHA1
Kq5sNclPz7QV2+lfQIuc6R7oRu0=
Using digest2
Using algorithem:MD5
XrY7u+Ae7tCTyyK7j1rNww==

尽管BeanFactory中没有配置MessageDigest,但还是有两个MessageDigester实现,这就是FactoryBean的作用

PS:我们也可以直接获得FactoryBean实例,用下面的方法,bean名前加一个&

 

MessageDigestFactoryBean messageDigestFactoryBean = (MessageDigestFactoryBean)factory.getBean( " &shaiDigest " );

你可能感兴趣的:(《Pro Spring》学习笔记之FactoryBean使用(非BeanFactory))