spring ioc源码分析

简介: spring ioc源码分析


image.png

一.源码分析

1.创建ApplicationContext

在上面spring boot启动中的分析中,发现在SpringApplication.run中创建了ApplicationContext 并且在context = this.createApplicationContext();中创建上下文。

1. public ConfigurableApplicationContext run(String... args) {
2.         StopWatch stopWatch = new StopWatch();
3.         stopWatch.start();
4.         ConfigurableApplicationContext context = null;
5.         Collection<SpringBootExceptionReporter> exceptionReporters = new ArrayList();
6. this.configureHeadlessProperty();
7.         SpringApplicationRunListeners listeners = this.getRunListeners(args);
8.         listeners.starting();
9. 
10.         Collection exceptionReporters;
11. try {
12.             ApplicationArguments applicationArguments = new DefaultApplicationArguments(args);
13.             ConfigurableEnvironment environment = this.prepareEnvironment(listeners, applicationArguments);
14. this.configureIgnoreBeanInfo(environment);
15.             Banner printedBanner = this.printBanner(environment);
16. //创建spring上下文
17.             context = this.createApplicationContext();
18.             exceptionReporters = this.getSpringFactoriesInstances(SpringBootExceptionReporter.class, new Class[]{ConfigurableApplicationContext.class}, context);
19. this.prepareContext(context, environment, listeners, applicationArguments, printedBanner);
20. //注入bean
21. this.refreshContext(context);
22. this.afterRefresh(context, applicationArguments);
23.             stopWatch.stop();
24. if (this.logStartupInfo) {
25.                 (new StartupInfoLogger(this.mainApplicationClass)).logStarted(this.getApplicationLog(), stopWatch);
26.             }
27. 
28.             listeners.started(context);
29. this.callRunners(context, applicationArguments);
30.         } catch (Throwable var10) {
31. this.handleRunFailure(context, var10, exceptionReporters, listeners);
32. throw new IllegalStateException(var10);
33.         }
34. 
35. try {
36.             listeners.running(context);
37. return context;
38.         } catch (Throwable var9) {
39. this.handleRunFailure(context, var9, exceptionReporters, (SpringApplicationRunListeners)null);
40. throw new IllegalStateException(var9);
41.         }
42.     }

其中创建的ApplicationContext类型如下,创建的类型为AnnotationConfigServletWebServerApplicationContext,所以ioc我们可以将断点打在AnnotationConfigApplicationContext中。

1. protected ConfigurableApplicationContext createApplicationContext() {
2.         Class<?> contextClass = this.applicationContextClass;
3. if (contextClass == null) {
4. try {
5. switch(this.webApplicationType) {
6. case SERVLET:
7.                     contextClass = Class.forName("org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext");
8. break;
9. case REACTIVE:
10.                     contextClass = Class.forName("org.springframework.boot.web.reactive.context.AnnotationConfigReactiveWebServerApplicationContext");
11. break;
12. default:
13.                     contextClass = Class.forName("org.springframework.context.annotation.AnnotationConfigApplicationContext");
14.                 }
15.             } catch (ClassNotFoundException var3) {
16. throw new IllegalStateException("Unable create a default ApplicationContext, please specify an ApplicationContextClass", var3);
17.             }
18.         }
19. 
20. return (ConfigurableApplicationContext)BeanUtils.instantiateClass(contextClass);
21.     }

2 进入AbstractApplicationContext的refresh()方法

在refreshContext最终会调用AbstractApplicationContext的refresh方法。

this.refreshContext(context);
1. @Override
2. public void refresh() throws BeansException, IllegalStateException {
3. synchronized (this.startupShutdownMonitor) {
4. // Prepare this context for refreshing.
5. //刷新上下文环境
6.         prepareRefresh();
7. // Tell the subclass to refresh the internal bean factory.
8. //这里是在子类中启动 refreshBeanFactory() 的地方
9. ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
10. // Prepare the bean factory for use in this context.
11. //准备bean工厂,以便在此上下文中使用
12.         prepareBeanFactory(beanFactory);
13. try {
14. // Allows post-processing of the bean factory in context subclasses.
15. //设置 beanFactory 的后置处理
16.             postProcessBeanFactory(beanFactory);
17. // Invoke factory processors registered as beans in the context.
18. //调用 BeanFactory 的后处理器,这些处理器是在Bean 定义中向容器注册的
19.             invokeBeanFactoryPostProcessors(beanFactory);
20. // Register bean processors that intercept bean creation.
21. //注册Bean的后处理器,在Bean创建过程中调用
22.             registerBeanPostProcessors(beanFactory);
23. // Initialize message source for this context.
24. //对上下文中的消息源进行初始化
25.             initMessageSource();
26. // Initialize event multicaster for this context.
27. //初始化上下文中的事件机制
28.             initApplicationEventMulticaster();
29. // Initialize other special beans in specific context subclasses.
30. //初始化其他特殊的Bean
31.             onRefresh();
32. // Check for listener beans and register them.
33. //检查监听Bean并且将这些监听Bean向容器注册
34.             registerListeners();
35. // Instantiate all remaining (non-lazy-init) singletons.
36. //实例化所有的(non-lazy-init)单件
37.             finishBeanFactoryInitialization(beanFactory);
38. // Last step: publish corresponding event.
39. //发布容器事件,结束Refresh过程
40.             finishRefresh();
41.         } catch (BeansException ex) {
42. if (logger.isWarnEnabled()) {
43.                 logger.warn("Exception encountered during context initialization - " +
44. "cancelling refresh attempt: " + ex);
45.             }
46. // Destroy already created singletons to avoid dangling resources.
47.             destroyBeans();
48. // Reset 'active' flag.
49.             cancelRefresh(ex);
50. // Propagate exception to caller.
51. throw ex;
52.         } finally {
53. // Reset common introspection caches in Spring's core, since we
54. // might not ever need metadata for singleton beans anymore...
55.             resetCommonCaches();
56.         }
57.     }
58. }

1.this.obtainFreshBeanFactory();装载初始化的bean

1. protected final void refreshBeanFactory() throws BeansException {
2. if (this.hasBeanFactory()) {
3. this.destroyBeans();
4. this.closeBeanFactory();
5.         }
6. 
7. try {
8. //创建BeanFactory
9.             DefaultListableBeanFactory beanFactory = this.createBeanFactory();
10.             beanFactory.setSerializationId(this.getId());
11. this.customizeBeanFactory(beanFactory);
12. //载入bean
13. this.loadBeanDefinitions(beanFactory);
14.             synchronized(this.beanFactoryMonitor) {
15. this.beanFactory = beanFactory;
16.             }
17.         } catch (IOException var5) {
18. throw new ApplicationContextException("I/O error parsing bean definition source for " + this.getDisplayName(), var5);
19.         }
20.     }
21. 
22. 
23. 
24.

2.this.prepareBeanFactory(beanFactory);

1. protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
2. //添加类加载器
3.         beanFactory.setBeanClassLoader(this.getClassLoader());
4. // 配置EL表达式
5.         beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
6. // 添加属性编辑器 PropertyEditor
7.         beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, this.getEnvironment()));
8. //添加后置处理器
9.         beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
10. 
11. //忽略以下类
12.         beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
13.         beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
14.         beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
15.         beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
16.         beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
17.         beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
18. 
19. //放入resolvableDependencies属性
20.         beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
21.         beanFactory.registerResolvableDependency(ResourceLoader.class, this);
22.         beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
23.         beanFactory.registerResolvableDependency(ApplicationContext.class, this);
24.         beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
25. if (beanFactory.containsBean("loadTimeWeaver")) {
26.             beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
27.             beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
28.         }
29. 
30. //以下为单例
31. if (!beanFactory.containsLocalBean("environment")) {
32.             beanFactory.registerSingleton("environment", this.getEnvironment());
33.         }
34. 
35. if (!beanFactory.containsLocalBean("systemProperties")) {
36.             beanFactory.registerSingleton("systemProperties", this.getEnvironment().getSystemProperties());
37.         }
38. 
39. if (!beanFactory.containsLocalBean("systemEnvironment")) {
40.             beanFactory.registerSingleton("systemEnvironment", this.getEnvironment().getSystemEnvironment());
41.         }
42. 
43.     }

3.postProcessBeanFactory

postProcessBeanFactory()方法向上下文中添加了一系列的Bean的后置处理器。后置处理器工作的时机是在所有的beanDenifition加载完成之后,bean实例化之前执行。简单来说Bean的后置处理器可以修改BeanDefinition的属性信息。

4.invokeBeanFactoryPostProcessors-->parse

1. public void refresh() throws BeansException, IllegalStateException {
2.                      ...
3. this.invokeBeanFactoryPostProcessors(beanFactory);
4.                      ...
5.     }
6. 
7. 
8. 
9. protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
10. PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, this.getBeanFactoryPostProcessors());
11.                      ...
12. 
13.     }
14. 
15. 
16. public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
17.                      ...
18. 
19. invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
20.                 currentRegistryProcessors.clear();
21.                      ...
22.     }
23. 
24. 
25. private static void invokeBeanDefinitionRegistryPostProcessors(Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, 
26.                     ...
27. 
28.             postProcessor.postProcessBeanDefinitionRegistry(registry);
29. 
30. 
31.     }
32. 
33. 
34. public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
35.                    ...
36. this.processConfigBeanDefinitions(registry);
37.                    ...
38.     }
39. 
40. 
41. public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
42.                    ...
43.                 parser.parse(candidates);
44.                    ...
45.     }
1. // ConfigurationClassParser类
2. public void parse(Set<BeanDefinitionHolder> configCandidates) {
3. Iterator var2 = configCandidates.iterator();
4. 
5. while(var2.hasNext()) {
6. BeanDefinitionHolder holder = (BeanDefinitionHolder)var2.next();
7. BeanDefinition bd = holder.getBeanDefinition();
8. 
9. try {
10. //SpringBoot项目项目启动时AnnotatedBeanDefinition 上面注入的启动类的BeanDefinition
11. if (bd instanceof AnnotatedBeanDefinition) {
12. this.parse(((AnnotatedBeanDefinition)bd).getMetadata(), holder.getBeanName());
13.                 } else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition)bd).hasBeanClass()) {
14. this.parse(((AbstractBeanDefinition)bd).getBeanClass(), holder.getBeanName());
15.                 } else {
16. this.parse(bd.getBeanClassName(), holder.getBeanName());
17.                 }
18.             } catch (BeanDefinitionStoreException var6) {
19. throw var6;
20.             } catch (Throwable var7) {
21. throw new BeanDefinitionStoreException("Failed to parse configuration class [" + bd.getBeanClassName() + "]", var7);
22.             }
23. 
24. // 加载默认的配置 就是加载.pom中的的依赖 
25. this.deferredImportSelectorHandler.process();
26.     }
1. protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
2. this.processConfigurationClass(new ConfigurationClass(metadata, beanName));
3.     }
4. 
5. 
6. 
7. protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
8.               ...
9. 
10. do {
11. //递归处理Bean,如果有父类,递归处理,直到顶层父类
12.                 sourceClass = this.doProcessConfigurationClass(configClass, sourceClass);
13.             }
14.               ...
15.         }
16.     }
17. 
18. 
19. 
20. // ConfigurationClassParser类
21. protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
22.                 throws IOException {
23. 
24. // Recursively process any member (nested) classes first
25. //首先递归处理内部类,(SpringBoot项目的主类一般没有内部类)
26.             processMemberClasses(configClass, sourceClass);
27. 
28. // Process any @PropertySource annotations
29. // 针对 @PropertySource 注解的属性配置处理
30. for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
31.                     sourceClass.getMetadata(), PropertySources.class,
32.                     org.springframework.context.annotation.PropertySource.class)) {
33. if (this.environment instanceof ConfigurableEnvironment) {
34.                     processPropertySource(propertySource);
35.                 } else {
36.                     logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
37. "]. Reason: Environment must implement ConfigurableEnvironment");
38.                 }
39.             }
40. 
41. // Process any @ComponentScan annotations
42. // 根据 @ComponentScan 注解,扫描项目中的Bean(SpringBoot 启动类上有该注解)
43.             Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
44.                     sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
45. if (!componentScans.isEmpty() &&
46.                     !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
47. for (AnnotationAttributes componentScan : componentScans) {
48. // The config class is annotated with @ComponentScan -> perform the scan immediately
49. // 立即执行扫描,(SpringBoot项目为什么是从主类所在的包扫描,这就是关键了)
50.                     Set<BeanDefinitionHolder> scannedBeanDefinitions =
51. this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
52. // Check the set of scanned definitions for any further config classes and parse recursively if needed
53. for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
54.                         BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
55. if (bdCand == null) {
56.                             bdCand = holder.getBeanDefinition();
57.                         }
58. // 检查是否是ConfigurationClass(是否有configuration/component两个注解),如果是,递归查找该类相关联的配置类。
59. // 所谓相关的配置类,比如@Configuration中的@Bean定义的bean。或者在有@Component注解的类上继续存在@Import注解。
60. if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
61.                             parse(bdCand.getBeanClassName(), holder.getBeanName());
62.                         }
63.                     }
64.                 }
65.             }
66. 
67. // Process any @Import annotations
68. //递归处理 @Import 注解(SpringBoot项目中经常用的各种@Enable*** 注解基本都是封装的@Import)
69.             processImports(configClass, sourceClass, getImports(sourceClass), true);
70. 
71. // Process any @ImportResource annotations
72.             AnnotationAttributes importResource =
73.                     AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
74. if (importResource != null) {
75.                 String[] resources = importResource.getStringArray("locations");
76.                 Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
77. for (String resource : resources) {
78.                     String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
79.                     configClass.addImportedResource(resolvedResource, readerClass);
80.                 }
81.             }
82. 
83. // Process individual @Bean methods
84.             Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
85. for (MethodMetadata methodMetadata : beanMethods) {
86.                 configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
87.             }
88. 
89. // Process default methods on interfaces
90.             processInterfaces(configClass, sourceClass);
91. 
92. // Process superclass, if any
93. if (sourceClass.getMetadata().hasSuperClass()) {
94.                 String superclass = sourceClass.getMetadata().getSuperClassName();
95. if (superclass != null && !superclass.startsWith("java") &&
96.                         !this.knownSuperclasses.containsKey(superclass)) {
97. this.knownSuperclasses.put(superclass, configClass);
98. // Superclass found, return its annotation metadata and recurse
99. return sourceClass.getSuperClass();
100.                 }
101.              }
102. 
103. // No superclass -> processing is complete
104. return null;
105.          } 
106. 
107. 
108.

进入Set scannedBeanDefinitions =  this.componentScanParser.parse(componentScan,  sourceClass.getMetadata().getClassName());

1. public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
2.                   ...
3. return scanner.doScan(StringUtils.toStringArray(basePackages));
4.     }
5. 
6. 
7. 
8. protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
9. 
10. 
11. for(int var5 = 0; var5 < var4; ++var5) {
12.             String basePackage = var3[var5];
13. //扫描注解 查到bean 转为BeanDefinition
14.             Set<BeanDefinition> candidates = this.findCandidateComponents(basePackage);
15.             Iterator var8 = candidates.iterator();
16. 
17. while(var8.hasNext()) {
18.                 BeanDefinition candidate = (BeanDefinition)var8.next();
19.                 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
20.                 candidate.setScope(scopeMetadata.getScopeName());
21.                 String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
22. if (candidate instanceof AbstractBeanDefinition) {
23. this.postProcessBeanDefinition((AbstractBeanDefinition)candidate, beanName);
24.                 }
25. 
26. if (candidate instanceof AnnotatedBeanDefinition) {
27.                     AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition)candidate);
28.                 }
29. 
30. if (this.checkCandidate(beanName, candidate)) {
31.                     BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
32.                     definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
33.                     beanDefinitions.add(definitionHolder);
34. //注入ioc
35. this.registerBeanDefinition(definitionHolder, this.registry);
36.                 }
37.             }
38.         }
39. 
40. return beanDefinitions;
41.     }

二.个人理解,获取bean的过程

  1. 获取要扫描的包的地址。
  2. 通过注解扫描出bean 。
  3. BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder,  this.registry);将该BeanDefinition注册到IoC容器的beanDefinitionMap中 。    
1. public static void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) throws BeanDefinitionStoreException {
2. String beanName = definitionHolder.getBeanName();
3.         registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
4. String[] aliases = definitionHolder.getAliases();
5. if (aliases != null) {
6. String[] var4 = aliases;
7. int var5 = aliases.length;
8. 
9. for(int var6 = 0; var6 < var5; ++var6) {
10. String alias = var4[var6];
11.                 registry.registerAlias(beanName, alias);
12.             }
13.         }
14. 
15.     }

其中在 parse 中的 this.deferredImportSelectorHandler.process(); 加载pom文件中的依赖。

其中后置处理器可以修改BeanDefinition,可以参考以下实例

业务复杂=if else?刚来的大神竟然用策略+工厂彻底干掉了他们! - 掘金

三.bean的生命周期

  • 实例化Bean对象,这个时候Bean的对象是非常低级的,基本不能够被我们使用,因为连最基本的属性都没有设置,可以理解为连Autowired注解都是没有解析的;
  • 填充属性,当做完这一步,Bean对象基本是完整的了,可以理解为Autowired注解已经解析完毕,依赖注入完成了;
  • 如果Bean实现了BeanNameAware接口,则调用setBeanName方法;
  • 如果Bean实现了BeanClassLoaderAware接口,则调用setBeanClassLoader方法;
  • 如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory方法;
  • 调用BeanPostProcessor的postProcessBeforeInitialization方法;
  • 如果Bean实现了InitializingBean接口,调用afterPropertiesSet方法;
  • 如果Bean定义了init-method方法,则调用Bean的init-method方法;
  • 调用BeanPostProcessor的postProcessAfterInitialization方法;当进行到这一步,Bean已经被准备就绪了,一直停留在应用的上下文中,直到被销毁;
  • 如果应用的上下文被销毁了,如果Bean实现了DisposableBean接口,则调用destroy方法,如果Bean定义了destory-method声明了销毁方法也会被调用。


相关文章
|
4天前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
20 1
|
3月前
|
XML Java 数据格式
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
这篇文章是Spring5框架的实战教程,主要介绍了如何在Spring的IOC容器中通过XML配置方式使用外部属性文件来管理Bean,特别是数据库连接池的配置。文章详细讲解了创建属性文件、引入属性文件到Spring配置、以及如何使用属性占位符来引用属性文件中的值。
Spring5入门到实战------7、IOC容器-Bean管理XML方式(外部属性文件)
|
19天前
|
XML 缓存 Java
搞透 IOC、Spring IOC ,看这篇就够了!
本文详细解析了Spring框架的核心内容——IOC(控制反转)及其依赖注入(DI)的实现原理,帮助读者理解如何通过IOC实现组件解耦,提高程序的灵活性和可维护性。关注【mikechen的互联网架构】,10年+BAT架构经验倾囊相授。
|
20天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
29 1
|
21天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
25 1
|
1月前
|
缓存 JavaScript Java
Spring之FactoryBean的处理底层源码分析
本文介绍了Spring框架中FactoryBean的重要作用及其使用方法。通过一个简单的示例展示了如何通过FactoryBean返回一个User对象,并解释了在调用`getBean()`方法时,传入名称前添加`&`符号会改变返回对象类型的原因。进一步深入源码分析,详细说明了`getBean()`方法内部对FactoryBean的处理逻辑,解释了为何添加`&`符号会导致不同的行为。最后,通过具体代码片段展示了这一过程的关键步骤。
Spring之FactoryBean的处理底层源码分析
|
2月前
|
XML Java 数据格式
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
Spring 第二节内容补充 关于Bean配置的更多内容和细节 万字详解!
212 18
Spring IOC—基于XML配置Bean的更多内容和细节(通俗易懂)
|
11天前
|
安全 Java 测试技术
Java开发必读,谈谈对Spring IOC与AOP的理解
Spring的IOC和AOP机制通过依赖注入和横切关注点的分离,大大提高了代码的模块化和可维护性。IOC使得对象的创建和管理变得灵活可控,降低了对象之间的耦合度;AOP则通过动态代理机制实现了横切关注点的集中管理,减少了重复代码。理解和掌握这两个核心概念,是高效使用Spring框架的关键。希望本文对你深入理解Spring的IOC和AOP有所帮助。
24 0
|
2月前
|
XML Java 测试技术
spring复习01,IOC的思想和第一个spring程序helloWorld
Spring框架中IOC(控制反转)的思想和实现,通过一个简单的例子展示了如何通过IOC容器管理对象依赖,从而提高代码的灵活性和可维护性。
spring复习01,IOC的思想和第一个spring程序helloWorld
|
18天前
|
前端开发 Java Spring
Spring MVC源码分析之DispatcherServlet#getHandlerAdapter方法
`DispatcherServlet`的 `getHandlerAdapter`方法是Spring MVC处理请求的核心部分之一。它通过遍历预定义的 `HandlerAdapter`列表,找到适用于当前处理器的适配器,并调用适配器执行具体的处理逻辑。理解这个方法有助于深入了解Spring MVC的工作机制和扩展点。
21 0