【Spring小解BeanFactory、ApplicationContext

2023年 7月 14日 60.6k 0

Hi,大家好,我是抢老婆酸奶的小肥仔。

在我们日常开发中,Spring是必不可少的框架,我们耳熟能详的IoC,AOP都是其思想和工具。其实在日常工作中,我们比较常用的是ApplicationContext,BeanFactory等,今天我们来说说这两个类。

废话不多说,开干。

1、BeanFactory与ApplicationContext关系

1.1 ApplicationContext继承了BeanFactory,可以使用BeanFacroty中提供的方法,例如getBean等。

1.2、BeanFactory是Spring的核心之一,ApplicationContext主要组合了BeanFactory的功能。

1.3 BeanFactory与ApplicationContext的区别?

  • ApplicationContext是BeanFactory的子类,BeanFactory是Spring的底层类
  • ApplicationContext进行了扩展,提供了国际化、统一资源文件访问方式、监听器注册bean的事件、同时加载多个配置文件。
  • BeanFactory:采用延迟加载方式注入bean,只有在使用某个bean时调用getBean(),才对该Bean进行加载实例化,因此不能发现一些存在问题的Spring配置问题。ApplicationContext:在容器启动时,一次性创建所有bean,因此在启动时就能检测出哪些配置问题有利于检查所有所依赖属性是否注入。在使用时,不用等待bean创建。
  • 由于ApplicationContext一次加载所有bean,可能导致占用内存空间不足,程序启动慢
  • BeanFactory:通常以编程的方式创建,ApplicationContext:以声明的方式创建
  • BeanFactory与ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor使用,BeanFactory使用需要手动注册,ApplicationContext则自动注入
  • 2、BeanFactory接口

    该接口主要提供了containsBeangetAliasesgetBean等方法

    DefaultListableBeanFactory是BeanFactory的一个实现类,其不仅实现了BeanFactory的方法,也实现了其他接口或方法。

    SingletonBeanRegistry:单例bean的注册

    SimpleAliasRegistry:简单的别名注册

    BeanDefinitionRegistry:bean的注册

    Serializable:序列化

    3、ApplicationContext功能

    ApplicationContext继承了BeanFactory,实现了其功能外,还实现了其他功能。

    3.1 MessageSource(国际化)

    3.1.1 在resources目录下创建messages.propertesmessages_en.propertiesmessages_ja.propertiesmessages_zh.properties配置文件,并分别编写语言对应键值对。如图:

    3.1.2 注入ApplicationContext

    @Resource
    private ApplicationContext applicationContext;
    

    3.1.3 调用getMessage()实现转换

    applicationContext.getMessage("hi", null, Locale.CHINA)
    

    3.1.4 输出结果

    3.2 ResourcePatternResolver(统一资源文件访问)

    ResourcePatternResolver即对项目中的资源文件进行访问,拿到我们想要的配置信息。

    注:如需对jar包中的资源进行获取时需在classpath前添加*,即classpath*:

    //获取当前项目目录下的message开头的资源
    Resource[] resources = context.getResources("classpath:message*.properties");
    for (Resource resource : resources) {
        System.out.println("获取资源:"+resource);
    }
    
    //获取当前项目目录下的META-INF资源,包括jar中的数据
    Resource[] facResources = context.getResources("classpath*:META-INF/spring.factories");
    for (Resource resource : facResources) {
        System.out.println("获取fac资源:"+resource);
    }
    

    执行结果:

    3.3 EnvironmentCapable(环境变量)

    EnvironmentCapable:对系统或者电脑的配置的环境变量进行获取

    获取配置文件信息时相当于@Value

    String java_home = context.getEnvironment().getProperty("java_home");
    String port = context.getEnvironment().getProperty("server.port");
    System.out.println("java_home:"+java_home);
    System.out.println("port:"+port);
    

    执行结果:

    3.4 ApplicationEventPublisher(事件监听)

    提供监听作用,实现代码的解耦。

    3.4.1 用户事件注册

    即通过继承ApplicationEvent将事件进行注册

    @Getter
    public class SelfDefineEvent extends ApplicationEvent {
        private AdminUser user;
    
        public SelfDefineEvent(Object source,AdminUser user) {
            super(source);
            this.user = user;
        }
    }
    

    3.4.2 事件发布

    即通过@Autowired注入ApplicationEventPublisher或者ApplicationContext调用publishEvent()对事件进行发布。

    @Resource
    private ApplicationContext applicationContext;
    @Autowired
    private ApplicationEventPublisher eventPublisher;
    
    @Override
    public ResultUtil selfDefineUser() {
        AdminUser adminUser = new AdminUser("queena","11111111");
        SelfDefineEvent defineEvent = new SelfDefineEvent(this, adminUser);
        //applicationContext.publishEvent(defineEvent);
        eventPublisher.publishEvent(defineEvent);
        return ResultUtil.success();
    }
    

    3.4.3 @EventListener接收事件或实现接口ApplicationListener

    1、注解@ApplicationListener

    @Component
    @Slf4j
    public class UseAnnotatedListener {
    
        @EventListener
        public void getSelfDefine(SelfDefineEvent event){
            log.info("监听事件:{}",event.getUser());
        }
    }
    

    执行结果:

    2、实现接口

    @Component
    @Slf4j
    public class SelfDefineEventListener implements ApplicationListener {
        @Override
        public void onApplicationEvent(SelfDefineEvent event) {
            AdminUser user = event.getUser();
            log.info(String.format("用户名:%s,密码:%s",user.getUserName(),user.getPassword()));
        }
    }
    

    执行结果:

    在日常开发中,很多时候为了实现业务解耦,则可以采用监听器这种方式来实现。

    好了,今天的分享就到这了,希望我的分享对大家有所帮助。

    相关文章

    JavaScript2024新功能:Object.groupBy、正则表达式v标志
    PHP trim 函数对多字节字符的使用和限制
    新函数 json_validate() 、randomizer 类扩展…20 个PHP 8.3 新特性全面解析
    使用HTMX为WordPress增效:如何在不使用复杂框架的情况下增强平台功能
    为React 19做准备:WordPress 6.6用户指南
    如何删除WordPress中的所有评论

    发布评论