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类
FactoryBean 和 BeanFactory

 

 上图可以看到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种设计模式中的工厂模式,根据不同需要,创建出相对应的实例


 
上一篇:对明文字符串进行MD5加密


下一篇:Java 14 新功能介绍