我正在尝试掌握 Spring 的 FactoryBean 并且遇到过问题。您能否在下面查看我的来源并回答。这是我的应用程序上下文:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd">
<context:annotation-config/>
<bean id="SHADigest" class="com.dtoryanik.spring.factorybean.MessageDigestFactoryBean">
<property name="algorithmName">
<value>SHA1</value>
</property>
</bean>
<bean id="defaultDigest" class="com.dtoryanik.spring.factorybean.MessageDigestFactoryBean"/>
<bean id="digester" class="com.dtoryanik.spring.factorybean.MessageDigester">
<property name="messageDigest1">
<ref local="SHADigest"/>
</property>
<property name="messageDigest2">
<ref local="defaultDigest"/>
</property>
</bean>
</beans>
它实际上是一个工厂 bean:
public class MessageDigestFactoryBean implements FactoryBean<MessageDigest>{
private String algorithmName = "MD5";
private MessageDigest messageDigest = null;
@Override
public MessageDigest getObject() throws Exception {
System.out.println("<> MessageDigestFactoryBean.getObject()");
return messageDigest;
}
@Override
public Class<?> getObjectType() {
System.out.println("<> MessageDigestFactoryBean.getObjectType()");
return MessageDigest.class;
}
@Override
public boolean isSingleton() {
System.out.println("<> MessageDigestFactoryBean.isSingleton()");
return true;
}
@PostConstruct
public void postConstructHandler() throws NoSuchAlgorithmException {
System.out.println("<> MessageDigestFactoryBean.postConstructHandler()");
messageDigest = MessageDigest.getInstance(algorithmName);
}
public void setAlgorithmName(String algorithmName) {
this.algorithmName = algorithmName;
}
}
还有另一个类 - MessageDigester,但它对主题没有任何帮助。我有一个主要方法类:
public class MessageDigestDemo {
public static void main(String[] args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:app-ctx.xml");
ctx.refresh();
MessageDigester messageDigester = (MessageDigester) ctx.getBean("digester");
messageDigester.digest("Hello World!");
}
}
问题出在我的输出中。看来我有一个双重实例化。方法 isSingleton(), getObject() 为每个 bean 调用两次(尽管我只从工厂检索 2 个实例)。为什么会发生?也许我做错了什么?
<> MessageDigestFactoryBean.postConstructHandler()
<> MessageDigestFactoryBean.postConstructHandler()
<> MessageDigestFactoryBean.isSingleton()
<> MessageDigestFactoryBean.getObject()
<> MessageDigestFactoryBean.isSingleton()
<> MessageDigestFactoryBean.getObject()
<> MessageDigestFactoryBean.isSingleton()
<> MessageDigestFactoryBean.getObjectType()
<> MessageDigestFactoryBean.isSingleton()
<> MessageDigestFactoryBean.getObjectType()