小伙伴们,你们好,我是老寇
Spring最重要的概念就算IOC和AOP,本篇主要记录Spring IOC容器的相关知识,本文适合有spring相关基础并且想了解spring ioc的相关原理的人看
本文采用的源码为Spring 5.3.23,基于注解的方式讲解Spring IOC
一、引入依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.23</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
spring-context会自动将spring-expression、spring-core、spring-beans、spring-aop这几个基础jar包带进来
二、获取bean的例子
TestConfig.java
@Configuration
public class TestConfig {
@Bean
public Test test() {
return new Test();
}
}
Test.java
@Data
public class Test {
private String value;
}
Test1.java
@Data
public class Test1 {
private String value;
}
TestMain.java
public class TestMain {
public static void main(String[] args) {
ApplicationContext app = new AnnotationConfigApplicationContext(TestConfig.class, Test1.class);
Test test = app.getBean(Test.class);
test.setValue("123");
System.out.println("Test实例为" + test);
Test1 test1 = app.getBean(Test1.class);
test1.setValue("456");
System.out.println("Test1实例为" + test1);
System.out.println("扫描到的类:");
for (String beanDefinitionName : app.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
}
}
Test实例为Test(value=123)
Test1实例为Test1(value=456)
扫描到的类:
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
testConfig
test1
test
三、AnnotationConfigApplicationContext简介
AnnotationConfigApplicationContext类继承图(多余的类去除掉了)
AnnotationConfigApplicationContext类官网文档解释
独立的应用程序上下文,接受组件类作为输入 — 特别是@Configuration注释类,还有纯@Component类型和符合 JSR-330 类使用注释。
允许使用寄存器(类...)逐个注册类以及使用扫描(字符串...)进行类路径扫描。
在多个类的情况下,@Bean方法 在后面的类中定义的将覆盖在早期类中定义的那些。这可以 利用它通过一个额外的类故意覆盖某些 Bean 定义。
AnnotationConfigApplicationContext app = new AnnotationConfigApplicationContext(...) 扫描指定的类来构建ApplicationContext,即使有组件类型注解修饰的类不放入ApplicationContext就直接报错,因此必须将所有扫描到类放入ApplicationContext(5种组件类型注解:@Configuration、@Service、@Controller、@Component、@Repository)
修改代码,去掉TestConfig
ApplicationContext app = new AnnotationConfigApplicationContext(Test1.class);
Test test = app.getBean(Test.class);
test.setValue("123");
System.out.println("Test实例为" + test);
Test1 test1 = app.getBean(Test1.class);
test1.setValue("456");
System.out.println("Test1实例为" + test1);
System.out.println("扫描到的类:");
for (String beanDefinitionName : app.getBeanDefinitionNames()) {
System.out.println(beanDefinitionName);
}
接下来,我们看一看ApplicationContext类
ApplicationContext类继承图(多余的类去除掉了)
ApplicationContext类官网文档解释
为应用程序提供配置的中央界面。 这在应用程序运行时是只读的,但可能是 如果实现支持,则重新加载。
应用程序上下文提供:
- 用于访问应用程序组件的 Bean 工厂方法。 继承自ListableBeanFactory。
- 以通用方式加载文件资源的能力。 继承自ResourceLoader接口。
- 将事件发布到已注册侦听器的功能。 继承自ApplicationEventPublisher接口。
- 解析消息的能力,支持国际化。 继承自MessageSource接口。
- 从父上下文继承。后代上下文中的定义 将始终优先考虑。这意味着,例如,单亲父母 上下文可以由整个 Web 应用程序使用,而每个 servlet 都有 它自己的子上下文独立于任何其他 servlet 的子上下文。
除了标准的BeanFactory生命周期功能之外,ApplicationContext 实现还可以检测并调用ApplicationContextAwarebean 以及ResourceLoaderAware、ApplicationEventPublisherAware和MessageSourceAwarebean。
111111111111