美文网首页
BeanFactory还是ApplicationContext及

BeanFactory还是ApplicationContext及

作者: 昨日已逝去 | 来源:发表于2018-12-17 16:42 被阅读32次

    Feature BeanFactory ApplicationContext
    bean实例化/注入 支持 支持
    实例生命周期管理 不支持 支持
    自动BeanPostProcessor注册 不支持 支持
    自动BeanFactoryPostProcessor注册 不支持 支持
    方便MessageSource接收 不支持 支持
    内置的ApplicationEvent发布机制 不支持 支持

    使用BeanFactroy加载时,要手动附加所需的功能。
    实例:

    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    // populate the factory with bean definitions
    
    // now register any needed BeanPostProcessor instances
    factory.addBeanPostProcessor(new AutowiredAnnotationBeanPostProcessor());
    factory.addBeanPostProcessor(new MyBeanPostProcessor());
    
    // now start using the factory
    

    DefaultListableBeanFactory factory = new DefaultListableBeanFactory();
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory);
    reader.loadBeanDefinitions(new FileSystemResource("beans.xml"));
    
    // bring in some property values from a Properties file
    PropertyPlaceholderConfigurer cfg = new PropertyPlaceholderConfigurer();
    cfg.setLocation(new FileSystemResource("jdbc.properties"));
    
    // now actually do the replacement
    cfg.postProcessBeanFactory(factory);
    

    深入源码,探索AppliContext是如何和BeanFactory建立关系


    • 1 先从ClassPathXmlApplicationContext走起
        public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {
            super(parent);
            this.setConfigLocations(configLocations);
            if (refresh) {
                this.refresh();  //beanFactory的关联函数
            }
    
        }
    
    • 2 进入refresh()
        public void refresh() throws BeansException, IllegalStateException {
            Object var1 = this.startupShutdownMonitor;
            synchronized(this.startupShutdownMonitor) {
                this.prepareRefresh();
                ConfigurableListableBeanFactory beanFactory =             this.obtainFreshBeanFactory(); //此方法是和beanFactory关联,进行xml解析和groovy解析生成bean的函数
        this.postProcessBeanFactory(beanFactory);//这里就是postProcessBeanFactory的自动注册,所以beanFactory不具备自动注册功能;注册成功后,后续bean的生命周期中会进行检查并执行相应的方法。
        this.invokeBeanFactoryPostProcessors(beanFactory);
        this.registerBeanPostProcessors(beanFactory);
        this.initMessageSource();
        this.initApplicationEventMulticaster();
        this.onRefresh();
        this.registerListeners();
        this.finishBeanFactoryInitialization(beanFactory);
        this.finishRefresh();
              ...
            }
        }
    
    • 细看obtainFreshBeanFactory方法
        protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
            this.refreshBeanFactory();
            ConfigurableListableBeanFactory beanFactory = this.getBeanFactory();
            if (this.logger.isDebugEnabled()) {
                this.logger.debug("Bean factory for " + this.getDisplayName() + ": " + beanFactory);
            }
    
            return beanFactory;
        }
    

    Aware的作用


    说到Aware必须要了解bean的生命周期(不了解的直接百度),在bean的生命周期介绍中都会提到5大接口BeanNameAware,BeanFactoryAware,ApplicationContextAware,InitializingBean,DisposableBean

    可以看出去BeanNameAware等都是Aware的继承;下面我们就分析这些接口的作用。

    BeanNameAware

    • 实现BeanNameAware的类都会实现一个setBeanName方法,而这个方法所给的值就是beanName;也就是所传递是容器的本身。同理ApplicationContextAware传递的参数是bean自己所在的上下文。

    实例

    • User
    public class User implements BeanNameAware{
    
        private String id;
    
        private String name;
    
        public void setBeanName(String beanName) {
            id = beanName;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "User{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    
    • User1
    public class User1 {
    
        private String id;
    
        private String name;
    
        public void setBeanName(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        @Override
        public String toString() {
            return "User1{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    '}';
        }
    }
    
        <bean id="user" class="com.zwd.example.test.zzz.User">
    
        </bean>
    
        <bean id="user1" class="com.zwd.example.test.zzz.User1">
    
        </bean>
    
    • Test
    public class ApplicationTest {
    
        @Test
        public void test1() {
            ApplicationContext applicationContext = new ClassPathXmlApplicationContext("tinyioc.xml");
            System.out.println("user: "+applicationContext.getBean("user"));
            System.out.println("user1: "+applicationContext.getBean("user1"));
        }
    }
    
    • 输出
    user: User{id='user', name='null'}
    user1: User1{id='null', name='null'}
    

    相关文章

      网友评论

          本文标题:BeanFactory还是ApplicationContext及

          本文链接:https://www.haomeiwen.com/subject/xisckqtx.html