FactoryBean 和 BeanFactory
大佬勿喷,如果有什么地方理解错了欢迎吐槽
一 、BeanFacory
首先来看看下边的代码
package com.lhf.beanfactory; public class SingleBean { private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } >>>>>>>>>>>>>>>>>>>> package com.lhf.beanfactory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Config { @Bean("singleBean") public SingleBean singleBean(){ SingleBean bean = new SingleBean(); bean.setName("liu hui fa"); return bean; } } >>>>>>>>>>>>>>>>>>>>> package com.lhf.beanfactory; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main(String[] args) { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); ConfigurableListableBeanFactory beanFactory = context.getBeanFactory(); SingleBean bean = (SingleBean)beanFactory.getBean("singleBean"); System.out.println(bean.getName()); } }
再来大概的看看ConfigurableListableBeanFactory类
上图可以看到ConfigurableListableBeanFactory是BeanFactory的一个子接口。从上边的代码可以看到,ApplicationContext是可以获取到BeanFactory,但是上边的结构图中又发现ApplicationContext也只是BeanFactory的一个子接口而已,这不难看出BeanFactory是Spring用管理bean对象的。
也就是不用ApplicationContext直接使用BeanFactor也同样可以获得bean对象。因为前者的getBean方法就是从后者的继承过去的。(有兴趣的同志可以试一下,我就懒得写了)
二、FactoryBean
在手动整合SSM框架的时候SqlSessionFactory应该是经常出现的。简单来说他也是一个bean对象。
package com.lhf.factory; import org.springframework.beans.factory.FactoryBean; import org.springframework.beans.factory.InitializingBean; import java.security.MessageDigest; public class MessageDigestFactoryBean implements FactoryBean<MessageDigest>, InitializingBean { private String algorithmName = "MD5"; private MessageDigest messageDigest = null; @Override public MessageDigest getObject() throws Exception { return messageDigest; } @Override public Class<?> getObjectType() { return MessageDigest.class; } @Override public boolean isSingleton() { return true; } public String getAlgorithmName() { return algorithmName; } public void setAlgorithmName(String algorithmName) { this.algorithmName = algorithmName; } @Override public void afterPropertiesSet() throws Exception { messageDigest = MessageDigest.getInstance(algorithmName); } }
上边代码是手动创建的一个FactoryBean,借助spring钩子创建了一个MessageDigest对象,algorithmName是加密的方法,默认是MD5。
package com.lhf.factory; import java.security.MessageDigest; public class MessageDisgester { private MessageDigest messageDigest1; private MessageDigest messageDigest2; public MessageDigest getMessageDigest1() { return messageDigest1; } public void setMessageDigest1(MessageDigest messageDigest1) { this.messageDigest1 = messageDigest1; } public MessageDigest getMessageDigest2() { return messageDigest2; } public void setMessageDigest2(MessageDigest messageDigest2) { this.messageDigest2 = messageDigest2; } private void disget(String mes,MessageDigest messageDigest){ System.out.println("使用的加密算法是:"+messageDigest.getAlgorithm()); messageDigest.reset(); byte[] bytes = mes.getBytes(); byte[] digest = messageDigest.digest(bytes); System.out.println(digest); } public void disest(String mes){ System.out.println("使用1"); disget(mes,messageDigest1); System.out.println("使用2"); disget(mes,messageDigest2); } }
MessageDisgester依赖于两个MessageDigest
package com.lhf.factory; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class Config { @Bean("messageDigest1") public MessageDigestFactoryBean messDigestFactoryBean1(){ MessageDigestFactoryBean bean = new MessageDigestFactoryBean(); bean.setAlgorithmName("SHA1"); return bean; } @Bean("messageDigest2") public MessageDigestFactoryBean messDigestFactoryBean2(){ MessageDigestFactoryBean bean = new MessageDigestFactoryBean(); return bean; } @Bean public MessageDisgester messageDisgester() throws Exception { MessageDisgester disgester = new MessageDisgester(); disgester.setMessageDigest1(messDigestFactoryBean1().getObject()); disgester.setMessageDigest2(messDigestFactoryBean2().getObject()); return disgester; } }
这个配置分别声明了三个bean,两个工厂bean,和MessageDisgester的bean。
package com.lhf.factory; import org.springframework.context.annotation.AnnotationConfigApplicationContext; public class App { public static void main(String[] args) throws Exception { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Config.class); MessageDisgester bean = context.getBean(MessageDisgester.class); bean.disest("呵呵"); System.out.println("直接访问factorybean"); MessageDigestFactoryBean bean1 = (MessageDigestFactoryBean)context.getBean("&messageDigest1"); byte[] digest = bean1.getObject().digest("呵呵呵".getBytes()); System.out.println(digest); context.close(); } }
看出了什么?像不像设计模式中的工厂模式?看看这个名字就知道了,FactoryBean就是一个bean工厂而已,他会根据不同需求创建出你需要的不同的bean对象。
总结: BeanFactory管理bean对象,通过BeanFactory可以获取到ioc容器中的bean对象,我对他的理解是管理已注册的bean,因为他功能不仅仅这样,bean之间的依赖关系等也是由他管理。而FactoryBean就可以理解成23种设计模式中的工厂模式,根据不同需要,创建出相对应的实例