zoukankan      html  css  js  c++  java
  • 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种设计模式中的工厂模式,根据不同需要,创建出相对应的实例


     
  • 相关阅读:
    一、初识数据库
    面向对象—基础、名称空间、三大特性
    六、内置函数
    五、迭代器、生成器、装饰器
    四、global和nonlocal、函数名应用、格式化输出
    三、名称空间
    二、函数的参数
    shell脚本
    线性代数
    [模块] python调用java代码-jpype
  • 原文地址:https://www.cnblogs.com/Tiandaochouqin1/p/12188470.html
Copyright © 2011-2022 走看看