系列文章目录
提示:阅读这篇文章的时候先提前阅读一下系列文章
IOC
提到IOC容器大家都不陌生这个容器是什么?到底以什么形式存在,那么我们从今天开始陆续去解开Spring 源码揭开IOC的神秘面纱。
首先知其然,我们平常框架中开发怎么去把自己写的类交给IOC容器管理呢?
Spring5.0中我们开发时候就很少去写xml配置文件去注入IOC了 ,所以我们直接从常用的来
IOC容器是单例的吗?
默认是,他是可以指定的
@Scope(“模式”)有以下四种模式
- singlton 单例模式:全局仅有一个
- prototype 原型模式:每次获取Bean的时候都会有一个新的实例
- request:标识针对每次请求都会产生一个新的Bean对象并且该对象尽在当前Http请求内有效
- session:session作用域标识每次请求都会产生一个新的Bean对象,尽在当前Http请求内有效
eg:
@Controller
@Scope("singleton")
@Lazy
public class TestController {
public TestController() {
System.out.println("无参构造函数执行");
}
}
@Lazy是干什么的呢?@lazy(true /false) 参数为boolean
- @lazy如果为true情况下,懒汉式,在获取类的时候才被初始化
- @lazy如果为false情况下,饿汉式式,在启动的时候就创建对象了
(1)@Bean注入
eg:去注入我们的User实体类
@Configuration
public class Config {
@Bean//通过Bean去注入容器
public User user() {
return new User(1, "小王", "123456");
}
}
取出来
public static void main(String[] args) {
annotationConfigApplicationContext = new AnnotationConfigApplicationContext(Config.class);
User user = annotationConfigApplicationContext.getBean("user", User.class);
System.out.println(user);
//打印spring注入的所有对象
String[] beanDefinitionNames = annotationConfigApplicationContext.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println(beanDefinitionName);
}
}
打印结果
User{id=1, name=‘小王’, password=‘123456’}
org.springframework.context.annotation.internalConfigurationAnnotationProcessor
org.springframework.context.annotation.internalAutowiredAnnotationProcessor
org.springframework.context.annotation.internalCommonAnnotationProcessor
org.springframework.context.event.internalEventListenerProcessor
org.springframework.context.event.internalEventListenerFactory
config
user
结果分析:可以看来我们已经把User注入到IOC中并且通过user取出来了。@Bean注入的名是首拼小写类名
(2)@Import注解注入
@Configuration
@Import(User.class)
//作用主要讲外部的jar包注入到IOC容器中 这个注解等同于bean
//Import注册的bean对象 id为当前类的全路径
public class Config {
}
我们可以看出@Import注入方式比bin简单多了那么,Import注入他的名称是什么呢?和Bean注入不一样,@Import注入容器的对象需要我们通过对象的全限定类名去取!!
(3)Service
@Servic
public class TestService{
public TestController() {
System.out.println("无参构造函数执行");
}
}
(4)Repository
@Repository
public class TestService{
public TestController() {
System.out.println("无参构造函数执行");
}
}
这两种方式再不适用@SpringbootApplication竹节虾
@Configuration
@ComponentScan("com.spring.annotation")
public class Config {
}
@ComponentScan :
value=扫描哪个包下边的注解
includeFilters:指定扫描类型
扫描类型:我们看源码
public enum FilterType {
//注解类型
ANNOTATION,
//注解类型指定的类型
ASSIGNABLE_TYPE,
//ASPECTJ表达式(基本不用)
ASPECTJ,
//正则表达式
REGEX,
//自定义规则
CUSTOM
}
eg:
@ComponentScan(value = "",includeFilters = {@ComponentScan.Filter(type = FilterType.ANNOTATION)},useDefaultFilters = false)
然后通过我们的AnnotationConfigApplicationContext加载配置文件的时候就会扫描到,然后和Bean注入一样去取就好啦,注入名和Bean一样都是首字母小写的类名
(5)@Compoment
和Service 、Repository一样的
我们看一下Service 和Repository注解情况
他们都是用了@Compoment 那么这三个有什么区别吗?
注入对象更好区分应用场景,仅仅是为了更好的划分层次更好区分,归类。使用上没有区别
当然还有Controller Mapper(不是Spring中的标签是Mybatis中的)很多方式。