看清楚了,不是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
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
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
< 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名前加一个&