首页 > 其他分享 >Spring的ApplicationContext核心分析

Spring的ApplicationContext核心分析

时间:2024-01-04 18:11:06浏览次数:24  
标签:ApplicationContext Spring class Bean 核心 注解 Import public

跟着孙哥学Spring,b站:https://www.bilibili.com/video/BV185411477k/?spm_id_from=333.337.search-card.all.click


1.AnnotationConfigApplicationContext执行过程

public static void main(String[] args){
    AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(AppConfig.class);
    UserService userService = (UserService) ctx.getBean("userServiceImpl");
    userService.register();
}

当Spring的AnnotationConfigApplicationContext启动时,它会执行以下步骤:

public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
    this();
    register(componentClasses);
    refresh();
}

public AnnotationConfigApplicationContext() {
    this.reader = new AnnotatedBeanDefinitionReader(this);
    this.scanner = new ClassPathBeanDefinitionScanner(this);
}

2.BeanDefinitionReader接口解析

1. 常见实现类

  • XmlBeanDefinitionReader:用于配置文件。
  • AnnotatedBeanDefinitionReader:用于注解。

2. 作用

  • BeanDefinition的创建有三种方式。
  • DefaultListableBeanFactory#registerBeanDefinition:维护beanDefinitionMap

BeanDefinition创建方式

  1. XML配置:

    <bean id="" class=""/>
    
  2. 使用@Component, @Configuration, @Service, @Controller, @Repository注解:

    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    
  3. 使用BeanDefinitionBuilder

    BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(Test1.class);
    

3.@Import的使用方式

1. 使用@Import注解普通Java类

@Import(User.class)

2. 使用ImportSelector

public class MyImportSelector implements ImportSelector {
    @Override
    public String[] selectImports(AnnotationMetadata importingClassMetadata) {
        return new String[]{User.class.getName()};
    }
}

3. 自定义ImportBeanDefinitionRegistrar

// step1: 自定义ImportBeanDefinitionRegistrar
public class MyImportRegiser implements ImportBeanDefinitionRegistrar {
    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        //创建BD
        // <bean id="userDAO" class="com.xxxx.UserDAOImpl"/>
        BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(MyFactoryBean.class);
        GenericBeanDefinition beanDefinition = (GenericBeanDefinition) builder.getBeanDefinition();
        //BD进行注册
        registry.registerBeanDefinition("userDAO",beanDefinition);
    }
}


// step2: 利用FactoryBean创建代理类
public class MyFactoryBean implements FactoryBean<UserDAO> {
    @Override
    public UserDAO getObject() throws Exception {

        UserDAO userDAO = (UserDAO) Proxy.newProxyInstance(MyFactoryBean.class.getClassLoader(),new Class[]{UserDAO.class},(Object proxy, Method method, Object[] args)->{
            System.out.println("这是DAO接口的实现类");
            return null;
        });

        return userDAO;
    }

    @Override
    public Class<?> getObjectType() {
        return UserDAO.class;
    }
}

// step3: 使用@Import(MyImportRegiser.class) 进行导入
@Configuration
@ComponentScan("com.mybatis")
@Import(MyImportRegiser.class)
public class AppConfig {
    
}

4.BeanPostProcessor 和 BeanFactoryPostProcessor详解

BeanPostProcessor概述

BeanPostProcessor接口允许我们在Spring容器实例化Bean时插入自己的逻辑。它定义了两个主要方法,分别在Bean初始化前后被调用:

public class MyBeanPostProcessor implements BeanPostProcessor {
    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor.postProcessBeforeInitialization");
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("MyBeanPostProcessor.postProcessAfterInitialization");
        return bean;
    }
}

BeanPostProcessor的重要实现类

1. AutowiredAnnotationBeanPostProcessor

这个后处理器负责处理@Autowired, @Value, 和 @Inject注解,确保这些注解正确地被应用和处理。

2. CommonAnnotationBeanPostProcessor

这个后处理器处理常用的JSR-250注解,例如@Resource@PostConstruct@PreDestroy,以及init-methoddestroy-method属性,还有InitializingBeanDisposableBean接口。

BeanFactoryPostProcessor概述

BeanFactoryPostProcessor允许我们在Spring容器实例化任何其他Bean之前修改或处理BeanDefinition。其中,最常用的实现类是ConfigurationClassPostProcessor

ConfigurationClassPostProcessor的作用

  1. 处理@Configuration注解:它负责处理带有@Configuration注解的类,并确保正确处理其中的@Bean方法。

  2. 处理@ComponentScan:这个后处理器也负责扫描带有@ComponentScan注解的类,并将其中的Bean定义注册到容器中。

  3. 处理@Import@ImportResource

    • @Import注解可以通过多种方式导入其他配置类或定义Bean。 1 注册普通类 2 importSelect 3 importBeanDefinitionRegister
    • @ImportResource注解允许我们导入XML配置文件中定义的Bean。
  4. 处理@PropertySource:这个注解允许我们在@Configuration类中指定外部属性文件,使其可以被Spring容器加载。


标签:ApplicationContext,Spring,class,Bean,核心,注解,Import,public
From: https://www.cnblogs.com/zzusjw/p/17945854

相关文章

  • Spring 应用合并之路(一):摸石头过河 | 京东云技术团队
    公司在推进降本增效,在尝试多种手段之后,发现应用太多,每个应用都做跨机房容灾部署,则最少需要4台机器(称为容器更合适)。那么,将相近应用做一个合并,减少维护项目,提高机器利用率就是一个可选方案。经过前后三次不同的折腾,最后探索出来一个可行方案。记录一下,分享出来,希望对有相关需求的......
  • SpringCloud微服务实战——搭建企业级开发框架(三十一):自定义MybatisPlus代码生成器实现
      理想的情况下,代码生成可以节省很多重复且没有技术含量的工作量,并且代码生成可以按照统一的代码规范和格式来生成代码,给日常的代码开发提供很大的帮助。但是,代码生成也有其局限性,当牵涉到复杂的业务逻辑时,简单的代码生成功能无法解决。  目前市面上的代码生成器层出不穷,大多......
  • 一款神仙级SpringCloud微服务开源项目,接私活吊到不行!(附源码)
    今天给大家推荐一个牛逼的接私活项目,SpringCloud微服务架构项目!一个由商业级项目升级优化而来的微服务架构,采用SpringBoot2.7、SpringCloud等核心技术构建,提供基于React和Vue的两个前端框架用于快速搭建企业级的SaaS多租户微服务平台。架构图项目介绍采用前后端分离的模式......
  • RocketMQ系统性学习-SpringCloud Alibaba集成RocketMQ以及消息追踪、延时消息实战
    欢迎关注公众号:【11来了】发送“资料”可领取深入理解Redis系列文章结合电商场景讲解Redis使用场景、中间件系列笔记和编程高频电子书!作者为在读研究生,目前研二,计划在公众号记录学习常用中间件笔记,以及明年更新面试经历!消息追踪设置消息追踪需要修改broker启动的配置文件......
  • 手拉手后端Springboot整合JWT
    环境介绍技术栈springboot+mybatis-plus+mysql+java-jwt软件版本mysql8IDEAIntelliJIDEA2022.2.1JDK1.8SpringBoot2.7.13mybatis-plus3.5.3.2JsonWeb令牌简称JWTToken是在服务端产生的一串字符串是客户端访问资源接口(AP)时所需要的资源凭证。Token认证Token是在服务端产生的一......
  • 手拉手Springboot整合JWT
    环境介绍技术栈springboot+mybatis-plus+mysql+java-jwt软件版本mysql8IDEAIntelliJIDEA2022.2.1JDK1.8SpringBoot2.7.13mybatis-plus3.5.3.2JsonWeb令牌简称JWTToken是在服务端产生的一串字符串是客户端访问资源接口(AP)时所需要的资源凭证。 Token认证流程1、客户端使用用......
  • 使用springcloud 实现 蓝绿发布、灰度发布(金丝雀发布)
    介绍工作中经常要涉及到功能发布,这个时候也经常是业务系统最有可能遇到问题的时候,需要要尽量减少发布引起的风险。比如在系统负载比较小的时候使用。还有蓝绿发布、灰度发布等等,今天介绍一下这几种常见的发布,并使用springcloud实现。1.传统发布方式一个系统最初的时候,使用量小,用户......
  • 程序员的50大Spring面试问题及答案
    文章目录1.Spring框架?2.Spring的整体架构?3.Spring可以做什么?4.Spring的优点?缺点?5.你能说几个Spring5的新特性吗?6.IOC?7.什么是依赖注入?8.IOC注入哪几种方式?9.IOC优点?缺点?10.bean的生命周期?11.Spring有几种配置方式?12.Spring中的bean有几种scope?13.什么是AOP(面向切面编程)?14.......
  • 程序员的30大SpringBoot面试问题及答案
    文章目录1.什么是SpringBoot?2.SpringBoot的特征?3.如何快速构建一个SpringBoot项目?4.SpringBoot启动类注解?它是由哪些注解组成?5.什么是yaml?6.SpringBoot支持配置文件的格式?7.SpringBoot启动方式?8.SpringBoot需要独立的容器运行?9.SpringBoot配置途径?10.application.properties和......
  • Spring 七种事务传播性介绍
    作者:vivo互联网服务器团队-ZhouShaobin本文主要介绍了Spring事务传播性的相关知识。Spring中定义了7种事务传播性:PROPAGATION_REQUIREDPROPAGATION_SUPPORTSPROPAGATION_MANDATORYPROPAGATION_REQUIRES_NEWPROPAGATION_NOT_SUPPORTEDPROPAGATION_NEVERPROPAGATION_NESTED在Spri......