文章目录
IoC容器
-
容器:内部装的是对象
-
IoC:Inversion of Control,控制反转(获得依赖对象的过程反转了)。如果A需要对象B,那么A就会主动实例化B类,控制权在A手中。反转就是将控制权交给一个第三方角色(IoC容器),由他来创建B,A只需要等待对象传递给他。
比如说:初创公司是由老板统一管理所有员工,当公司发展壮大,老板就将员工的管理交给HR。老板不用关心员工的情况,只需要安排工作就好
优点:
- 资源集中管理
- 降低耦合度
IoC举例
创建一个车对象:
在传统的代码中对象创建顺序是:Car -> Framework -> Bottom -> Tire
需要在Car类中实例化Framework对象,在Framework类中实例化Bottom对象
改进之后解耦的代码的对象创建顺序是:Tire -> Bottom -> Framework -> Car

Car不需要实例化Framework类,只需要实例化Car类时将Framework对象传入。同样Framework也不需要实例化Bottom对象,在实例化将Framework类时将Bottom传入就好.
这就实现了车与 车身的解耦,车身与底盘的解耦...
将依赖关系反转了

DI
IoC控制反转是一种思想,而DI就是IoC的一种实现方式。也就是通过DI来实现IoC
Dependency Injection依赖注入:容器运行期间动态的为应用程序提供运行时所依赖的资源
依赖:类A的方法里需要调用类B的方法,就是类A依赖于类B
注入:将类B的实例提供给类A的过程
java
Tire tire=new Tire(13);
Bottom bottom=new Bottom(tire);
Framework framework=new Framework(bottom);
car c=new car(framework);
// IoC容器内就存储着这些对象
Spring IoC
Spring就是包含了众多方法的IoC容器,由Spring掌握对象的控制权
Bean
所有由Spring IoC容器负责创建、组装和管理的对象统称为Bean
- 类注解:
@Controller(控制器存储)、@Service(服务器存储)、@Repository(仓库存储)、@Configuration(配置存储)、@Component(组件存储) - 方法注解:
@Bean
类注解的使用
Bean的存储
每个类注解的使用方法类似,这里以@Component举例
将类加上@Component注解,表示这个类的实现由Spring控制
java
@Component
public class UserController {
public void sayHi(){
System.out.println("Hi");
}
}
Bean的获取
从Spring上下文中获取对象
上下文:就是指当前的运行环境,也可以看作一个容器,容器内存放着当前的运行环境
-
获取上下文
javaApplicationContext context=SpringApplication.run(IocApplication.class, args); -
通过
getBean()获取对象java//通过类型,适用于只实例化一个对象 UserController userController1= context.getBean(UserController.class); //通过Bean名,需要强转 UserController userController2= (UserController)context.getBean("userController"); //通过Bean名和类型 UserController userController3 = context.getBean("userController",UserController.class);Bean名的约定 :类名的小驼峰格式
特殊情况:前两个字母为大写,Bean名则为原类名
类名: AManager, Bean的名称为: AManager
也可以通过注解指定名称
@Controller(name)
ApplicationContext获取Bean()对象的方法,是继承自父类BeanFactory
- 继承关系和功能:Spring容器的两个顶级接口BeanFactory和ApplicationContext,BeanFactory提供了基础访问容器的能力 ,ApplicationContext是BeanFactory的子类,除继承了BeanFactory所有的方法 以外,还拥有额外的特性。如国际化支持、资源的访问、事件传播
- 性能:ApplicationContext是一次性加载并初始化所有Bean ,BeanFactory是需要哪个才去加载哪个
为什么有这么多类注解
联系
@Controller、@Service、@Repository、@Configuration这三个注解都是@Component的子注解,也称为衍生注解

与应用分层相呼应,程序员看到类注解之后,就能知道这个类的具体用途
@Controller:控制层,接收请求,对请求进行处理并进行相应@Service:业务逻辑层,处理具体的业务逻辑@Repository:数据访问层,也称为持久层,负责数据的访问操作@Configuration:配置层,处理项目中的配置信息@Component:组件层
区别
@Controller不能和其他注解替换,控制层必须使用@Controller。其他注解可以相互替换(但是不建议,因为不同注解表示的含义不同)
方法注解@Bean
使用场景:
- 一个类需要多个对象
- 一个类的实例化过程非常复杂,将这些复杂的逻放到
@Bean方法里会非常清晰 - 有些外部类,不能添加类注解,但是还需要Spring去管理这个类
java
public class Student {
public String name;
public int age;
@Bean({"s1","student1"})
public Student s1(){
return new Student("张三",11);
}
@Bean
public String name2(){
return "张三";
}
@Bean({"s2","student2"})
public Student s2(String name){
return new Student(name,13);
}
}
当Spring启动时,发现
s1(),s2()方法上有@Bean注解。Spring会主动调用这个方法,拿到返回的Student对象
@Bean的名称默认为方法名,也可在注解上进行指定(可指定多个名称)@Bean注解的方法需要接收参数时,Spring会从Spring容器中查找对应类型的对象(必须是唯一的),赋值到参数中- 获取Bean使用
context.getBean("BeanName");方法
扫描路径
默认扫描路径
启动类同级的目录及其子目录

修改扫描路径
使用@ComponentScan注解可以修改扫描路径,修改后以@ComponentScan规定的路径为主
java
@ComponentScan("包名") //会扫描指定包名下所有的文件,放在启动类上方
Spring DI
依赖注入:简单来说就是将对象取出来放到某个类的属性中
- 属性注入(Field Injection)
- 构造方法输入(Construction Injection)
- Setter注入(Setter Injection)
使用@Autowired注解
原理 :在Spring创建Bean的属性填充阶段,会利用反射扫描全类,找到@Autowired标记的位置,然后遵循"先类型后变量名"的原则。从容器内找到合适的依赖对象,最后通过反射将其注入到代码中
缺陷 :如果一个类存在多个对象,且@Autowired标记的字段不是Bean名就会报错
解决办法:
-
@Primary:指定对应的默认对象 -
@Qualifier:在@Autowired上方加上@Qualifier(BeanName)注解用于指定Bean名称。也可加在参数上java@Bean public Student s2(@Qualifier("Name1") String name){ return new Student(name,13); } @Qualifier("s1") @Autowired Student s11; -
@Resource:使用@Resource(BeanName)代替@Autowired@Resource(BeanName)于@Autowired区别:@Autowired是spring框架提供的注解,而@Resource是JDK提供的注解@Autowired默认是按照类型 注入,而@Resource是按照名称注入

属性注入
java
@Autowired
UserService userService;
优点:
- 简洁,使用方便
缺点:
- 只能作用于IoC容器
- 不能注入一个Final修饰的属性,因为Final修饰的属性在编译时要有确切的值
构造函数注入
- 如果类只有一个构造函数,默认使用唯一的构造函数
- 如果类中有多个构造函数,默认使用无参的构造函数
- 使用
@Autowired注解可以指定使用的构造函数
java
final UserService userService;
UserConfig userConfig;
@Autowired
public HelloController(UserService userService, UserConfig userConfig) {
this.userService = userService;
this.userConfig = userConfig;
}
优点:
- 可以注入final修饰的属性
- 注入的对象不会被修改
- 依赖对象在使用前一定会被完全初始化,因为依赖注入是在构造函数中进行的,而构造函数是在类加载阶段执行的
- 通用性好,构造方法是JDK 支持的,更换任何框架都适用
缺点:
- 注入多个对象时,代码较为繁琐
Setter注入
Setter注入和属性的Setter方法实现类似,设置set方法时需要加上@Auto wired注解
java
UserService userService;
UserConfig userConfig;
@Autowired
public void setUserConfig(UserConfig userConfig) {this.userConfig = userConfig;}
@Autowired
public void setUserService(UserService userService) {this.userService = userService;}
优点:
- 方便在类实例之后,重新对该对象进行配置或注入
缺点:
- 不能注入一个final修饰的属性
- 注入的对象可能会被改变,因为Setter方法可能会被多次调用
总结
SpringMVC和Spring Boot都属于Spring,Spring MVC是基于Spring的一个MVC框架,而Spring Boot是基于Spring的一套快速开发整合包
Spring:
Spring: 简单来说, Spring 是一个开发应用框架 ,什么样的框架呢,有这么几个标签:轻量级、一 站式、模块化,其目的是用于简化企业级应用程序开发.
Spring的主要功能: 管理对象 ,以及对象之间的依赖关系 , 面向切面编程 , 数据库事务管理 , 数据访问 , web框架支持等. 但是Spring具备高度可开放性, 并不强制依赖Spring, 开发者可以自由选择Spring的部分或者全部, Spring可以无缝继承第三方框架, 比如数据访问框架(Hibernate 、JPA), web框架(如Struts、 JSF)
Spring MVC:
Spring MVC是Spring的一个子框架 , Spring诞生之后, 大家觉得很好用, 于是按照MVC 模式设计了一个 MVC框架(一些用Spring 解耦的组件), 主要用于开发WEB应用和网络接口 ,所以, Spring MVC 是一个Web框架.
Spring Boot:
Spring Boot是对Spring的一个封装 , 为了简化Spring应用的开发而出现的,中小型企业,没有成本研究自己的框架, 使用Spring Boot可以更加快速的搭建框架, 降级开发成本, 让开发人员更加专注于Spring应用的开发,而无需过多关注XML的配置和一些底层的实现
比如想使用SpringBoot开发Web项目 , 只需要引入Spring MVC框架 即可, 想完成数据访问, 只需要引入Mybatis框架即可.
EB应用和网络接口**,所以, Spring MVC 是一个Web框架.
Spring Boot:
Spring Boot是对Spring的一个封装 , 为了简化Spring应用的开发而出现的,中小型企业,没有成本研究自己的框架, 使用Spring Boot可以更加快速的搭建框架, 降级开发成本, 让开发人员更加专注于Spring应用的开发,而无需过多关注XML的配置和一些底层的实现
比如想使用SpringBoot开发Web项目 , 只需要引入Spring MVC框架 即可, 想完成数据访问, 只需要引入Mybatis框架即可.