Spring的ApplicationContext核心分析

跟着孙哥学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容器加载。


posted @   zzusjw  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
点击右上角即可分享
微信分享提示