解决问题:
如何创建并注入不能简单地使用new运算符创建的依赖项
FactoryBean是一个bean,可以作为其他bean的工厂。
当spring容器调用getBean方法时,它并不返回FactoryBean,而是调用FactoryBean.getObject()方法并返回调用的结果.
spring内典型应用场景
- 创建事务代理(第9章介绍)
- 从JNDI上下文中自动获取资源
- 构建自己的应用程序也可以使用
说明
FactoryBean接口
实现
getObject方法:FactoryBean创建的对象
和
getObjectType方法:返回对象的类型
样例
MessageDigest消息摘要的生成,MessageDigest.getInstance生成MessageDigest实例
源码 chapter04/factory-bean
package com.apress.prospring5.ch4;
import java.security.MessageDigest;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.beans.factory.InitializingBean;
public class MessageDigestFactoryBean implements
FactoryBean<MessageDigest>, InitializingBean {
private String algorithmName = "MD5";
private MessageDigest messageDigest = null;
public MessageDigest getObject() throws Exception {
return messageDigest;
}
public Class<MessageDigest> getObjectType() {
return MessageDigest.class;
}
public boolean isSingleton() {
return true;
}
public void afterPropertiesSet() throws Exception {
messageDigest = MessageDigest.getInstance(algorithmName);
}
public void setAlgorithmName(String algorithmName) {
this.algorithmName = algorithmName;
}
}
package com.apress.prospring5.ch4;
import java.security.MessageDigest;
public class MessageDigester {
private MessageDigest digest1;
private MessageDigest digest2;
public void setDigest1(MessageDigest digest1) {
this.digest1 = digest1;
}
public void setDigest2(MessageDigest digest2) {
this.digest2 = digest2;
}
public void digest(String msg) {
System.out.println("Using digest1");
digest(msg, digest1);
System.out.println("Using digest2");
digest(msg, digest2);
}
private void digest(String msg, MessageDigest digest) {
System.out.println("Using alogrithm: " + digest.getAlgorithm());
digest.reset();
byte[] bytes = msg.getBytes();
byte[] out = digest.digest(bytes);
System.out.println(out);
}
}
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="shaDigest" class="com.apress.prospring5.ch4.MessageDigestFactoryBean"
p:algorithmName="SHA1"/>
<bean id="defaultDigest"
class="com.apress.prospring5.ch4.MessageDigestFactoryBean"/>
<bean id="digester"
class="com.apress.prospring5.ch4.MessageDigester"
p:digest1-ref="shaDigest"
p:digest2-ref="defaultDigest"/>
</beans>
package com.apress.prospring5.ch4;
import org.springframework.context.support.GenericXmlApplicationContext;
public class MessageDigestDemo {
public static void main(String... args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:spring/app-context-xml.xml");
ctx.refresh();
MessageDigester digester = (MessageDigester) ctx.getBean("digester");
digester.digest("Hello World!");
/*
执行结果
Using digest1
Using alogrithm: SHA1
[B@441772e
Using digest2
Using alogrithm: MD5
[B@7334aada
*/
//MessageDigestFactoryBean messageDigestFactoryBean1 = (MessageDigestFactoryBean) ctx.getBean("messageDigestFactoryBean");
//Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'messageDigestFactoryBean' available
//访问产生bean的factory bean: &beanName
MessageDigestFactoryBean messageDigestFactoryBean2 = (MessageDigestFactoryBean) ctx.getBean("&shaDigest");
ctx.close();
}
}
4.10 直接访问FactoryBean
访问产生bean的factory bean: &beanName
4.11 使用factory-bean和factory-method属性
问题:有时需要实例化第三方应用程序提供的javaBean,可能不知道如何实例化该类,但是第三方提供了一个可获取该bean的类,典型工厂模式
<bean>的factory-bean和factory-method属性
样例
源码 chapter04/factory-bean-and-factory-method-attributes
package com.apress.prospring5.ch4;
import java.security.MessageDigest;
public class MessageDigestFactory {
private String algorithmName = "MD5";
public MessageDigest createInstance() throws Exception {
return MessageDigest.getInstance(algorithmName);
}
public void setAlgorithmName(String algorithmName) {
this.algorithmName = algorithmName;
}
}
package com.apress.prospring5.ch4;
import java.security.MessageDigest;
public class MessageDigester {
private MessageDigest digest1;
private MessageDigest digest2;
public void setDigest1(MessageDigest digest1) {
this.digest1 = digest1;
}
public void setDigest2(MessageDigest digest2) {
this.digest2 = digest2;
}
public void digest(String msg) {
System.out.println("Using digest1");
digest(msg, digest1);
System.out.println("Using digest2");
digest(msg, digest2);
}
private void digest(String msg, MessageDigest digest) {
System.out.println("Using alogrithm: " + digest.getAlgorithm());
digest.reset();
byte[] bytes = msg.getBytes();
byte[] out = digest.digest(bytes);
System.out.println(out);
}
}
<?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:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="shaDigestFactory"
class="com.apress.prospring5.ch4.MessageDigestFactory"
p:algorithmName="SHA1"/>
<bean id="defaultDigestFactory"
class="com.apress.prospring5.ch4.MessageDigestFactory"/>
<bean id="shaDigest"
factory-bean="shaDigestFactory"
factory-method="createInstance">
</bean>
<bean id="defaultDigest"
factory-bean="defaultDigestFactory"
factory-method="createInstance"/>
<bean id="digester"
class="com.apress.prospring5.ch4.MessageDigester"
p:digest1-ref="shaDigest"
p:digest2-ref="defaultDigest"/>
</beans>
package com.apress.prospring5.ch4;
import org.springframework.context.support.GenericXmlApplicationContext;
public class MessageDigestFactoryDemo {
public static void main(String... args) {
GenericXmlApplicationContext ctx = new GenericXmlApplicationContext();
ctx.load("classpath:spring/app-context-xml.xml");
ctx.refresh();
MessageDigester digester = (MessageDigester) ctx.getBean("digester");
digester.digest("Hello World!");
ctx.close();
}
}
网友评论