spring的IOC和DI
com.hong.model.User
package com.hong.model;
import org.springframework.stereotype.Component;
import java.io.Serializable;
/**
* @ClassName User
* @Description 用户
* @Author csh
* @Date 2023/1/13 14:27
*/
@Component
public class User{
private String userName;
private int age;
private String nickName;
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getNickName() {
return nickName;
}
public void setNickName(String nickName) {
this.nickName = nickName;
}
public User() {
this.userName = "hong";
}
}
com.hong.ioc.IocConfig
package com.hong.ioc;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
/**
* @ClassName IocConfig
* @Description ioc配置
* @Author csh
* @Date 2023/1/13 14:29
*/
@Configuration
@ComponentScan(basePackages = {"com.hong"})
public class IocConfig {
}
com.hong.ioc.IocSourceStudy
package com.hong.ioc;
import com.hong.model.User;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
/**
* @ClassName IocSourceStudy
* @Description ioc学习
* @Author csh
* @Date 2023/1/13 14:26
*/
public class IocSourceStudy {
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(IocConfig.class);
User user = applicationContext.getBean("user",User.class);
System.out.println(user.getUserName());
}
}
执行结果
16:12:26: Executing task 'IocSourceStudy.main()'...
> Task :buildSrc:compileJava UP-TO-DATE
> Task :buildSrc:compileGroovy NO-SOURCE
> Task :buildSrc:pluginDescriptors UP-TO-DATE
> Task :buildSrc:processResources UP-TO-DATE
> Task :buildSrc:classes UP-TO-DATE
> Task :buildSrc:jar UP-TO-DATE
> Task :buildSrc:assemble UP-TO-DATE
> Task :buildSrc:pluginUnderTestMetadata UP-TO-DATE
> Task :buildSrc:compileTestJava NO-SOURCE
> Task :buildSrc:compileTestGroovy NO-SOURCE
> Task :buildSrc:processTestResources NO-SOURCE
> Task :buildSrc:testClasses UP-TO-DATE
> Task :buildSrc:test NO-SOURCE
> Task :buildSrc:validateTaskProperties UP-TO-DATE
> Task :buildSrc:check UP-TO-DATE
> Task :buildSrc:build UP-TO-DATE
> Task :spring-core:cglibRepackJar UP-TO-DATE
> Task :spring-aop:processResources UP-TO-DATE
> Task :spring-core:objenesisRepackJar UP-TO-DATE
> Task :spring-hong-testing:processResources NO-SOURCE
> Task :spring-expression:processResources UP-TO-DATE
> Task :spring-beans:processResources UP-TO-DATE
> Task :spring-core:processResources UP-TO-DATE
> Task :spring-context:processResources UP-TO-DATE
> Task :spring-instrument:compileJava UP-TO-DATE
> Task :spring-instrument:processResources NO-SOURCE
> Task :spring-instrument:classes UP-TO-DATE
> Task :spring-instrument:jar UP-TO-DATE
> Task :kotlin-coroutines:compileKotlin UP-TO-DATE
> Task :kotlin-coroutines:compileJava NO-SOURCE
> Task :kotlin-coroutines:processResources NO-SOURCE
> Task :kotlin-coroutines:classes UP-TO-DATE
> Task :spring-jcl:compileJava UP-TO-DATE
> Task :kotlin-coroutines:inspectClassesForKotlinIC UP-TO-DATE
> Task :spring-jcl:processResources UP-TO-DATE
> Task :spring-jcl:classes UP-TO-DATE
> Task :kotlin-coroutines:jar UP-TO-DATE
> Task :spring-jcl:jar UP-TO-DATE
> Task :spring-core:compileKotlin UP-TO-DATE
> Task :spring-core:compileJava UP-TO-DATE
> Task :spring-core:classes UP-TO-DATE
> Task :spring-core:inspectClassesForKotlinIC UP-TO-DATE
> Task :spring-core:jar UP-TO-DATE
> Task :spring-expression:compileKotlin UP-TO-DATE
> Task :spring-expression:compileJava UP-TO-DATE
> Task :spring-expression:classes UP-TO-DATE
> Task :spring-expression:inspectClassesForKotlinIC UP-TO-DATE
> Task :spring-expression:jar UP-TO-DATE
> Task :spring-beans:compileGroovy UP-TO-DATE
> Task :spring-beans:compileKotlin UP-TO-DATE
> Task :spring-beans:compileJava NO-SOURCE
> Task :spring-beans:classes UP-TO-DATE
> Task :spring-beans:inspectClassesForKotlinIC UP-TO-DATE
> Task :spring-beans:jar UP-TO-DATE
> Task :spring-aop:compileJava UP-TO-DATE
> Task :spring-aop:classes UP-TO-DATE
> Task :spring-aop:jar UP-TO-DATE
> Task :spring-context:compileKotlin UP-TO-DATE
> Task :spring-context:compileJava UP-TO-DATE
> Task :spring-context:compileGroovy NO-SOURCE
> Task :spring-context:classes UP-TO-DATE
> Task :spring-context:inspectClassesForKotlinIC UP-TO-DATE
> Task :spring-context:jar UP-TO-DATE
> Task :spring-hong-testing:compileJava
> Task :spring-hong-testing:classes
> Task :spring-hong-testing:IocSourceStudy.main()
hong
BUILD SUCCESSFUL in 15s
35 actionable tasks: 2 executed, 33 up-to-date
16:12:42: Task execution finished 'IocSourceStudy.main()'.
相关依赖图
org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext(java.lang.Class>...)
public AnnotationConfigApplicationContext(Class>... componentClasses) {
//调用无参构造方法 进行实例化AnnotationConfigApplicationContext
this();
//注册类 注册分两种一种是配置文件 比如.xml 还有一种就是指定的.class(bean)
register(componentClasses);
//刷新
refresh();
}
org.springframework.context.annotation.AnnotationConfigApplicationContext#AnnotationConfigApplicationContext()
public AnnotationConfigApplicationContext() {
//初始化bean读取器
this.reader = new AnnotatedBeanDefinitionReader(this);
//初始化类扫描器
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#AnnotatedBeanDefinitionReader(org.springframework.beans.factory.support.BeanDefinitionRegistry, org.springframework.core.env.Environment)
public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
Assert.notNull(environment, "Environment must not be null");
this.registry = registry;
//@Conditional的实始化
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//初始化相关组件 比如 @Order @lazy 与@Qualifier注解 @Autowired与@Value注解的 等
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
org.springframework.context.annotation.AnnotationConfigUtils#registerAnnotationConfigProcessors(org.springframework.beans.factory.support.BeanDefinitionRegistry, java.lang.Object)
public static Set registerAnnotationConfigProcessors(
BeanDefinitionRegistry registry, @Nullable Object source) {
//@EventListener的初始化
DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
if (beanFactory != null) {
//解析@Order 初始化
if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
}
//解析@lazy 与@Qualifier注解 初始化
if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
}
}
Set beanDefs = new LinkedHashSet<>(8);
//新增解析配置类的处理器
if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//新增处理@Autowired与@Value注解的后置处理器
if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 检查是否支持JSR-250 新增处理@Resource 注解的后置处理器
if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
}
// 检查是否支持JPA,将启用JPA注解支持
if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition();
try {
def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
AnnotationConfigUtils.class.getClassLoader()));
}
catch (ClassNotFoundException ex) {
throw new IllegalStateException(
"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
}
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
}
//监听器的支持@EventListener注解
if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
}
//指定监听器的默认实现类
if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
def.setSource(source);
beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
}
return beanDefs;
}
org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean
private void doRegisterBean(Class beanClass, @Nullable String name,
@Nullable Class extends Annotation>[] qualifiers, @Nullable Supplier supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//对bean进行封装
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//如果为空或类型不一致则直接返回
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//设置bean的回调
abd.setInstanceSupplier(supplier);
//解析bean的作用域 有两种类型如下:
// @Scope("prototype") 原类型
// @Scope("singleton"),单态类型 默认不配的情况下是这种
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
//设置作用域
abd.setScope(scopeMetadata.getScopeName());
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//主要用于判断这个类有没有包含 Lazy Primary DependsOn Role Description 这些注释或属性有的话进行设置。
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
//如果不为空 匹配是 @Primary 或@Lazy 或@Qualifier 都进行初始化设置
if (qualifiers != null) {
for (Class extends Annotation> qualifier : qualifiers) {
if (Primary.class == qualifier) {
abd.setPrimary(true);
}
else if (Lazy.class == qualifier) {
abd.setLazyInit(true);
}
else {
abd.addQualifier(new AutowireCandidateQualifier(qualifier));
}
}
}
//如果存在个性化配置进行增加
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
//进行BeanDefinition的封装
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//根据作用域创建代理对象。
//默认NO 是不创建代理对象 当然还有JDK和CGLib
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//最后注册成bean对象
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
3.refresh()刷新的实现;
org.springframework.context.support.AbstractApplicationContext#refresh
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 为刷新准备上下文,保存容器启动时间和设置关闭状态为否及运行状态启动等初始化工作
prepareRefresh();
// 告诉子类刷新内部bean工厂。初始化bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//准备在此上下文中使用的bean工厂。
prepareBeanFactory(beanFactory);
try {
// 允许在上下文子类中对bean工厂进行后处理。(前置处理器)
postProcessBeanFactory(beanFactory);
//调用上下文中注册为bean的工厂处理器。(为beanFactory注册的事件处理器)
invokeBeanFactoryPostProcessors(beanFactory);
//调用bean的后置处理器
registerBeanPostProcessors(beanFactory);
// 初始化国际化资源处理器
initMessageSource();
//创建事件多播器
initApplicationEventMulticaster();
// 初始化扩展的自定义插件 比如tomcat
onRefresh();
// 检查侦听器bean并注册它们。
registerListeners();
//实例化所有剩余的(非lazy-init)单例。
finishBeanFactoryInitialization(beanFactory);
//最后容器刷新 发布刷新后的事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// destroy already created singletons to avoid dangling resources.
destroyBeans();
// 重置标记
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
//重置单例bean元数据(清空缓存)
resetCommonCaches();
}
}
}
org.springframework.context.support.AbstractApplicationContext#prepareBeanFactory
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 告诉内部bean工厂使用上下文的类装入器等。
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 使用上下文回调来配置bean工厂。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// 在普通工厂中,BeanFactory接口未注册为可解析类型。
// MessageSource作为bean注册(并找到用于自动装配)。
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//将早期的后置处理器注册为应用监听器,用于检测内部bean。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// 检查存在loadTimeWeaver 的类型则进行设置
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
//为类型匹配设置一个临时的ClassLoader。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// 注册默认环境bean。
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
最后
以上就是大致IOC的初始化流程,详细了解有利于后续深入的了解spring其他实现机制。
参考资料:
https://github.com/DocsHome/spring-docs/blob/master/pages/core/IoC-container.mdhttps://blog.csdn.net/weixin_43738764/article/details/124966670https://blog.csdn.net/weixin_41605937/article/details/115004381https://www.jianshu.com/p/de879b493893