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创建方式
-
XML配置:
<bean id="" class=""/> -
使用
@Component
,@Configuration
,@Service
,@Controller
,@Repository
注解:AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); -
使用
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-method
和destroy-method
属性,还有InitializingBean
和DisposableBean
接口。
BeanFactoryPostProcessor概述
BeanFactoryPostProcessor
允许我们在Spring容器实例化任何其他Bean之前修改或处理BeanDefinition
。其中,最常用的实现类是ConfigurationClassPostProcessor
。
ConfigurationClassPostProcessor的作用
-
处理
@Configuration
注解:它负责处理带有@Configuration
注解的类,并确保正确处理其中的@Bean
方法。 -
处理
@ComponentScan
:这个后处理器也负责扫描带有@ComponentScan
注解的类,并将其中的Bean定义注册到容器中。 -
处理
@Import
和@ImportResource
:@Import
注解可以通过多种方式导入其他配置类或定义Bean。 1 注册普通类 2 importSelect 3 importBeanDefinitionRegister@ImportResource
注解允许我们导入XML配置文件中定义的Bean。
-
处理
@PropertySource
:这个注解允许我们在@Configuration
类中指定外部属性文件,使其可以被Spring容器加载。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix