BeanFactory与ApplicationContext基本介绍

这篇具有很好参考价值的文章主要介绍了BeanFactory与ApplicationContext基本介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

接口定义能力,抽象类实现接口的一些重要方法,最后实现类可以实现自己的一些逻辑

BeanFactory简介

仅仅是一个接口,Spring 的核心容器,并不是IOC容器的具体实现,它的一些具体实现类才是

BeanFactory 与 ApplicationContext 的区别

  • BeanFactory 是 ApplicationContext 的父接口
  • BeanFactory才是 Spring 的核心容器, 主要的 ApplicationContext 实现和【组合】了它的功能

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

BeanFactory的作用

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

  • 表面上只有 getBean(通过名称或者类型)
  • 实际上控制反转、基本的依赖注入、直至 Bean 的生命周期的各种功能, 都由它的实现类提供

SpringBoot启动方法返回对象就是BeanFactory实现类之一ConfigurableApplicationContext

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

@SpringBootApplication
public class SpringDemoApplication {

    public static void main(String[] args) {
        ConfigurableApplicationContext context = SpringApplication.run(SpringDemoApplication.class, args);
        System.out.println(context);
    }
}

DefaultListableBeanFactory是一个比较重要的实现类

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

使用反射,通过其一个父类DefaultSingletonBeanRegistry获得spring容器中以component名称开头的Bean对象:

public class DefaultSingletonBeanRegistry extends SimpleAliasRegistry implements SingletonBeanRegistry {
    // beanName -> 单例对象
    private final Map<String, Object> singletonObjects = new ConcurrentHashMap(256);
    // ...
}
        ConfigurableApplicationContext context = SpringApplication.run(SpringDemoApplication.class, args);
        Field singletonObjects = DefaultSingletonBeanRegistry.class.getDeclaredField("singletonObjects");
        // 私有属性设置可访问
        singletonObjects.setAccessible(true);
        ConfigurableListableBeanFactory beanFactory = context.getBeanFactory();
		// 通过反射获得类中属性
        Map<String, Object> map = (Map<String, Object>) singletonObjects.get(beanFactory);
        map.entrySet().stream().filter(e -> e.getKey().startsWith("component"))
                .forEach(e -> {
                    System.out.println(e.getKey() + "=" + e.getValue());
                });

ApplicationContext的主要功能

四大功能

来源于四个父接口

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

MessageSource-国际化资源

准备不同国际语言配置文件:

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

打印不同配置文件的内容:

        System.out.println(context.getMessage("hi", null, Locale.CHINA));
        System.out.println(context.getMessage("hi", null, Locale.ENGLISH));
        System.out.println(context.getMessage("hi", null, Locale.JAPANESE));

ResourcePatternResolver-通配符匹配资源

获取指定路径下的资源:

        Resource[] resources = context.getResources("classpath*:META-INF/spring.factories");
        for (Resource resource : resources) {
            System.out.println(resource);
        }

EnvironmentCapable-处理环境信息

打印配置信息:

        // java配置信息
		System.out.println(context.getEnvironment().getProperty("java_home"));
		// yml配置信息
        System.out.println(context.getEnvironment().getProperty("server.port"));

【观察者模式】ApplicationEventPublisher-发布事件对象【事件解耦】

首先定义不同事件对象

// 继承类且无需@Component注解,也可以自定义属性在事件对象中
public class UserRegisteredEvent extends ApplicationEvent {
    public UserRegisteredEvent(Object source) {
        super(source);
    }
}

其次发布者发布事件

@Component
public class ComponentPublisher {

    private static final Logger log = LoggerFactory.getLogger(ComponentPublisher.class);

	// 实际上是该类 ApplicationContext
    @Autowired
    private ApplicationEventPublisher publisher;

    public void register() {
        log.debug("用户注册");
        // source:发布消息
        publisher.publishEvent(new UserRegisteredEvent(this));
    }
}

最后不同对象处理事件(监听事件)

@Component
public class ComponentListener {

    private static final Logger log = LoggerFactory.getLogger(ComponentListener.class);

    // 注解,监听事件对象
    @EventListener(UserRegisteredEvent.class)
    public void sendMsg(UserRegisteredEvent event) {
        log.debug("{}", event);
        log.debug("发送短信操作");
    }
}

或者:用这种方式监听事件(两者二选一),如一个事件有多个监听器,可以使用@Order注解,决定执行顺序,越小越先执行

@Order(0) // 越小越先执行
@Component
// 实现接口
public class ComponentListener1 implements ApplicationListener<UserRegisteredEvent> {

    private static final Logger log = LoggerFactory.getLogger(ComponentListener1.class);
    
    public void sendMsg(UserRegisteredEvent event) {
        log.debug("{}", event);
        log.debug("发送短信操作");
    }
}

BeanFactory常见实现类

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

DefaultListableBeanFactory

DefaultListableBeanFactory只是一个空的容器,需要往容器里注册一些bean,默认没有一些后置处理器,要想具备这些功能,需要手动添加后置处理器并且执行

public class TestBeanFactory {

    public static void main(String[] args) {
        DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
        // bean 的定义(class, scope, 初始化, 销毁)
        AbstractBeanDefinition beanDefinition =
BeanDefinitionBuilder.genericBeanDefinition(Config.class).setScope("singleton").getBeanDefinition();
        beanFactory.registerBeanDefinition("config", beanDefinition);

        // 给 BeanFactory 添加一些常用的后处理器 同时也会设置比较器
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        // BeanFactory 后处理器主要功能,补充了一些 bean 定义
        beanFactory.getBeansOfType(BeanFactoryPostProcessor.class).values().forEach(beanFactoryPostProcessor -> {
            beanFactoryPostProcessor.postProcessBeanFactory(beanFactory);
        });

        // Bean 后处理器, 针对 bean 的生命周期的各个阶段提供扩展, 例如 @Autowired @Resource ...
        beanFactory.getBeansOfType(BeanPostProcessor.class).values().stream()
                // 这里就可以获取比较器了
                .sorted(beanFactory.getDependencyComparator())
                .forEach(beanPostProcessor -> {
            System.out.println(">>>>" + beanPostProcessor);
            beanFactory.addBeanPostProcessor(beanPostProcessor);
        });

        for (String name : beanFactory.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        // 准备好所有单例	
        beanFactory.preInstantiateSingletons(); 
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> ");
//        默认延迟创建bean对象
//        System.out.println(beanFactory.getBean(Bean1.class).getBean2());
        System.out.println(beanFactory.getBean(Bean1.class).getInter());

        System.out.println("Common:" + (Ordered.LOWEST_PRECEDENCE - 3));
        System.out.println("Autowired:" + (Ordered.LOWEST_PRECEDENCE - 2));
    }

    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2() {
            return new Bean2();
        }

        @Bean
        public Bean3 bean3() {
            return new Bean3();
        }

        @Bean
        public Bean4 bean4() {
            return new Bean4();
        }
    }

    interface Inter {

    }

    static class Bean3 implements Inter {

    }

    static class Bean4 implements Inter {

    }

    static class Bean1 {
        private static final Logger log = LoggerFactory.getLogger(Bean1.class);

        public Bean1() {
            log.debug("构造 Bean1()");
        }

        @Autowired
        private Bean2 bean2;

        public Bean2 getBean2() {
            return bean2;
        }

        @Autowired
        @Resource(name = "bean4")
        private Inter bean3;

        public Inter getInter() {
            return bean3;
        }
    }

    static class Bean2 {
        private static final Logger log = LoggerFactory.getLogger(Bean2.class);

        public Bean2() {
            log.debug("构造 Bean2()");
        }
    }
}

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

小结

  • beanFactory 不会做的事

  • 不会主动添加、调用 BeanFactory 后置处理器

  • 不会主动添加 Bean 后置处理器

  • 不会主动初始化单例

  • 不会解析beanFactory 还不会解析 ${ } 与 #{ }

  • bean 后处理器会有排序的逻辑 根据order排序

ApplicationContext常见实现类

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言

ApplicationContext相当于会自动给BeanFactory容器后置处理器,操作更加方便一点

public class TestApplicationContext {
    private static final Logger log = LoggerFactory.getLogger(TestApplicationContext.class);

    public static void main(String[] args) {
        testClassPathXmlApplicationContext();
//        testFileSystemXmlApplicationContext();
//        testAnnotationConfigApplicationContext();
//        testAnnotationConfigServletWebServerApplicationContext();

        /*
            学到了什么
                a. 常见的 ApplicationContext 容器实现
                b. 内嵌容器、DispatcherServlet 的创建方法、作用
         */
    }

    // 较为经典的容器, 基于 classpath 下 xml 格式的配置文件来创建
    private static void testClassPathXmlApplicationContext() {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("spring-beans.xml");

        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());
    }

    // 基于磁盘路径下 xml 格式的配置文件来创建
    private static void testFileSystemXmlApplicationContext() {
        FileSystemXmlApplicationContext context =
                new FileSystemXmlApplicationContext(
                        "src\\main\\resources\\spring-beans.xml");
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());
    }

    // 较为经典的容器, 基于 java 配置类来创建
    private static void testAnnotationConfigApplicationContext() {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(Config.class);

        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());
    }

    // 较为经典的容器, 基于 java 配置类来创建, 用于 web 环境
    private static void testAnnotationConfigServletWebServerApplicationContext() {
        AnnotationConfigServletWebServerApplicationContext context =
                new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }

    @Configuration
    static class WebConfig {

        /**
         * 注册Tomcat服务器
         */
        @Bean
        public ServletWebServerFactory servletWebServerFactory(){
            return new TomcatServletWebServerFactory();
        }

        /**
         * 注册 DispatcherServlet
         */
        @Bean
        public DispatcherServlet dispatcherServlet() {
            return new DispatcherServlet();
        }

        /**
         * 注册 DispatcherServlet路径 到 Tomcat 服务器上
         */
        @Bean
        public DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet) {
            return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
        }
        @Bean("/hello")
        public Controller controller1() {
            return (request, response) -> {
                response.getWriter().print("hello");
                return null;
            };
        }
    }

    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2(Bean1 bean1) {
            Bean2 bean2 = new Bean2();
            bean2.setBean1(bean1);
            return bean2;
        }
    }

    static class Bean1 {
    }

    static class Bean2 {

        private Bean1 bean1;

        public void setBean1(Bean1 bean1) {
            this.bean1 = bean1;
        }

        public Bean1 getBean1() {
            return bean1;
        }
    }
}

ClassPathXmlApplicationContext

较为经典的容器, 基于 classpath 下 xml 格式的配置文件来创建

	private static void testClassPathXmlApplicationContext() {
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("spring-beans.xml");

        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());
    }


	// 以上代码相当于
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    System.out.println("读取之前...");
    for (String name : beanFactory.getBeanDefinitionNames()) {
        System.out.println(name);
    }
    System.out.println("读取之后...");
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
    reader.loadBeanDefinitions(new ClassPathResource("spring-beans.xml"));
    for (String name : beanFactory.getBeanDefinitionNames()) {
        System.out.println(name);
    }

spring-beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- 控制反转, 让 bean1 被 Spring 容器管理 -->
    <bean id="bean1" class="com.lkl.spring.chapter2.TestApplicationContext.Bean1"/>

    <!-- 控制反转, 让 bean2 被 Spring 容器管理 -->
    <bean id="bean2" class="com.lkl.spring.chapter2.TestApplicationContext.Bean2">
        <!-- 依赖注入, 建立与 bean1 的依赖关系 -->
        <property name="bean1" ref="bean1"/>
    </bean>
</beans>

FileSystemXmlApplicationContext

基于磁盘路径下 xml 格式的配置文件来创建

	private static void testFileSystemXmlApplicationContext() {
        FileSystemXmlApplicationContext context =
                new FileSystemXmlApplicationContext(
                        "src\\main\\resources\\spring-beans.xml");
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());
    }

	// 相当于
    DefaultListableBeanFactory beanFactory = new DefaultListableBeanFactory();
    System.out.println("读取之前...");
    for (String name : beanFactory.getBeanDefinitionNames()) {
        System.out.println(name);
    }
    System.out.println("读取之后...");
    XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(beanFactory);
    reader.loadBeanDefinitions(new FileSystemResource("src\\main\\resources\\spring-beans.xml"));
    for (String name : beanFactory.getBeanDefinitionNames()) {
        System.out.println(name);
    }

AnnotationConfigApplicationContext

较为经典的容器,基于 java 配置类来创建

	private static void testAnnotationConfigApplicationContext() {
        AnnotationConfigApplicationContext context =
                new AnnotationConfigApplicationContext(Config.class);

        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }

        System.out.println(context.getBean(Bean2.class).getBean1());
    }
    @Configuration
    static class Config {
        @Bean
        public Bean1 bean1() {
            return new Bean1();
        }

        @Bean
        public Bean2 bean2(Bean1 bean1) {
            Bean2 bean2 = new Bean2();
            bean2.setBean1(bean1);
            return bean2;
        }
    }

    static class Bean1 {
    }

    static class Bean2 {

        private Bean1 bean1;

        public void setBean1(Bean1 bean1) {
            this.bean1 = bean1;
        }

        public Bean1 getBean1() {
            return bean1;
        }
    }

AnnotationConfigServletWebServerApplicationContext

较为经典的容器,基于 java 配置类来创建,用于 web 环境【内嵌Tomcat】

	private static void testAnnotationConfigServletWebServerApplicationContext() {
        AnnotationConfigServletWebServerApplicationContext context =
                new AnnotationConfigServletWebServerApplicationContext(WebConfig.class);
        for (String name : context.getBeanDefinitionNames()) {
            System.out.println(name);
        }
    }
    @Configuration
    static class WebConfig {

        /**
         * 注册Tomcat服务器
         */
        @Bean
        public ServletWebServerFactory servletWebServerFactory() {
            return new TomcatServletWebServerFactory();
        }

        /**
         * 注册 DispatcherServlet
         */
        @Bean
        public DispatcherServlet dispatcherServlet() {
            return new DispatcherServlet();
        }

        /**
         * 注册 DispatcherServlet路径 到 Tomcat 服务器上
         */
        @Bean
        public DispatcherServletRegistrationBean registrationBean(DispatcherServlet dispatcherServlet) {
            return new DispatcherServletRegistrationBean(dispatcherServlet, "/");
        }

        /**
         * 提供一个web访问接口
         */
        @Bean("/hello")
        public Controller controller1() {
            return (request, response) -> {
                response.getWriter().print("hello");
                return null;
            };
        }
    }

启动容器,访问http://localhost:8080/hello可以得到相应的响应

BeanFactory与ApplicationContext基本介绍,spring,java,开发语言文章来源地址https://www.toymoban.com/news/detail-537015.html

到了这里,关于BeanFactory与ApplicationContext基本介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Spring之BeanFactory与ApplicationContext区别、实例化Bean的三种⽅式、延迟加载(lazy-Init )

    BeanFactory是Spring框架中IoC容器的顶层接⼝,它只是⽤来定义⼀些基础功能,定义⼀些基础规范,⽽ApplicationContext是它的⼀个⼦接⼝,所以ApplicationContext是具备BeanFactory提供的全部功能的。 通常,我们称BeanFactory为SpringIOC的基础容器, ApplicationContext是容器的⾼级接⼝,⽐BeanFactory要拥

    2024年02月11日
    浏览(38)
  • 理解SpringIOC和DI第一课(Spring的特点),IOC对应五大注解,ApplicationContext vs BeanFactory

    对象这个词在Spring范围内,称为bean Spring两大核心思想 1.IOC     (IOC是控制反转,意思是 控制权反转-控制权(正常是谁用这个对象,谁去创建,)-控制对象的控制权,反转的意思是创建对象的控制权,交给了Spring) 优点:解耦合 高内聚:一个模块内部的关系 低耦合:各个模

    2024年02月04日
    浏览(45)
  • BeanFactory和ApplicationContext的区别

    BeanFactory与ApplicationContext的关系 BeanFactory是Spring的早期接口,称为 Spring的Bean工厂 ,ApplicationContext是后期更高级接口,称之为 Spring容器 ; ApplicationContext在BeanFactory基础上对功能进行了扩展,例如: 监听功能、国际化功能 等。 BeanFactory 的API更 偏向底层 , ApplicationContext 的A

    2024年02月06日
    浏览(38)
  • 第一讲:BeanFactory和ApplicationContext接口

    BeanFactory是ApplicationContext的父接口,是真正的Spring核心容器,主要的ApplicationContext实现都【组合】了他的功能。 首先先看一下BeanFactory的接口定义: 表面上只有getBean功能,实际上控制反转、基本的依赖注入、直至Bean的生命周期的各种功能,都由他的实现类提供, 例如:Defau

    2024年02月12日
    浏览(35)
  • BeanFactory和ApplicationContext区别及详解

    ​ Spring 框架带有两个 IOC 容器—— BeanFactory 和 ApplicationContext 。 BeanFactory 是 IOC 容器的最基本版本, ApplicationContext 扩展了 BeanFactory 的特性。 ​ Spring容器最基本的接口就是BeanFactory。BeanFactory负责配置、创建、管理Bean,它有一个子接口ApplicationContext,也被称为Spring上下文,

    2023年04月10日
    浏览(36)
  • 解锁ApplicationContext vs BeanFactory: 谁更具选择性?

    目录 一、聚焦源码回顾 (一)源码分析和理解 (二)简短的回顾对比建议 二、ApplicationContext vs BeanFactory特性对比 (一)主要特性总结 (二)直接建议 三、案例简单说明 (一)加载少量的 Bean的案例 (二)简单的命令行工具:用于读取配置文件并生成报告 (三)启动时加

    2024年04月25日
    浏览(33)
  • 【Spring Security OAuth2 Client】基本介绍以及定制开发

    OAuth2 协议起来越普及,大多数企业都有自己的一套单点登录系统,通常都会支持 OAuth 协议,但这个单点登录系统通常会在 OAuth 标准协议上多多少少会有改造,我们在企业内部开发一个应用服务,需要对接单点登录 SSO ,只要支持 OAuth 协议,我们就可以使用 spring-boot-starter-

    2024年02月14日
    浏览(39)
  • Java开发框架:Spring介绍

    Spring 是 Java EE 编程领域中的一个轻量级开源框架,由 Rod Johnson 在 2002 年最早提出并随后创建,目的是解决企业级编程开发中的复杂性,实现敏捷开发的应用型框架 。其中,轻量级表现在 Spring 是非侵入式的,即开发应用中的对象可以不依赖于 Spring 的 API 类。另外,Spring 针对

    2024年02月08日
    浏览(54)
  • Spring MVC学习随笔-控制器(Controller)开发详解:调用业务对象、父子工厂拆分(applicationContext.xml、dispatcher.xml)

    学习视频:孙哥说SpringMVC:结合Thymeleaf,重塑你的MVC世界!|前所未有的Web开发探索之旅 💡 1. 接收客户端(Client)请求参数【讲解完毕】2. 调用业务对象【讲解】3. 页面跳转 dispatcher.xml DAO Service Controller 现有SSM开发中存在的问题 MVC层的对象(Controller, mvc:annotation-driven/,视图解

    2024年02月05日
    浏览(49)
  • Spring源码-浅识BeanFactory

    在SpringBoot出现之前,我们使用Spring需要以配置文件的方式进行启动.如果使用XML文件配置.则通过 XmlWebApplicationContext.java 进行启动.常应用在Web项目的开发中. 以此为例,通过阅读源码发现和 XmlWebApplicationContext.java \\\"平级\\\"的类如下所示 由此我们可以知道 ApplicationContext 遵循 Applicat

    2024年02月03日
    浏览(44)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包