目录
[一. Spring是什么](#一. Spring是什么)
[二. IoC&DI的使用](#二. IoC&DI的使用)
一. Spring是什么
Spring是一个包含众多工具的IoC容器
容器:Tomcat--->web容器
List/Map--->数据存储容器
Spring容器装的是对象。
IoC:控制反转
控制权反转,创建对象的控制权。
IoC
IoC的本质是为了解耦合。
举个例子:
建筑汽车时,汽车依赖车身,车身依赖底盘,底盘依赖轮胎。
car--->framework--->bottom--->tire
普通方式:
当想要遭不同轮胎尺寸的车辆时,修改轮胎类,把size设置为轮胎属性。于此同时要修改所有关联的类。
这种方式改动一个属性,需要需改所有关联的代码。
想要修改轮胎属性,而不影响其他的关联类,这个时候使用IoC的方式。
spring提供的IoC的思想:
每个类之间界限清晰,添加一个属性时其他的类关联性弱,而Spring IoC需要做的就是管理对象,即实现下面Main方法的作用。
Spring帮助我们管理对象,我们需要做的事情:
1.告诉Spring,帮我们管理哪些对象
2.知道如何取出来这些对象
DI
IoC是一种思想,DI是一种实现方式。(注入依赖)
注入依赖,比如:上面的Car类中,把Framework注入Car中。
二. IoC&DI的使用
@Autowired:(英文:自动装配),用来注入依赖
@Componemt:(英文意为组件,即对象),用来存取对象
以之前的图书管理系统为例:
IoC
1.类注解:@Controller、 @Service、@Repository、@Componemt、@Configuration
2.方法注解:@Bean
1.@Controller(控制器存储)
用@Controller存储bean的代码
2.@Service(服务存储)
用@Service储bean的代码
getBean()提供的三种获取bean的方式
java
@SpringBootApplication
public class IoCDemoApplication {
public static void main(String[] args) {
//Spring上下文,返回Spring的运行环境
ApplicationContext context=SpringApplication.run(IoCDemoApplication.class, args);
//从context中获取bean
UserController bean = context.getBean(UserController.class);
bean.doController();
UserService userService = context.getBean(UserService.class);
userService.doService();
//按照名称来获取bean
UserService userService2 = (UserService)context.getBean("userService");
userService2.doService();
//根据名称和类型获取bean
UserService userService3 = context.getBean("userService", UserService.class);
userService3.doService();
}
}
bean的命名约定:小写字母开头,采用驼峰命名。
特殊情况:如果类名的前两位都是大写,bean的名称不变
eg: UController------> "UController"
3.@Repository(仓库存储)
4.@Componemt(组件存储)
5.@Configuration(配置存储)
多种类注解的作用
这些类注解的用法相似,有这么多的类注解的目的是为了更好的应用分层,根据不同的类注解能直接了解当前类的用途。
@Controller(控制层)、 @Service(业务逻辑层)、@Repository(数据访问层)、@Configuration(配置层)
注解之间的关系
@Controller、 @Service、@Repository都是@Componemt的衍生类,即@Componemt是他们的父类
若想让外界访问到,程序的入口只能使用@Controller
6.@Bean(方法注解)
1.上述五大注解只能加在类上,并且只能加在自己的代码上,当想要引入一个第三方jar包,也希望交给Spring管理
2.当对于一个类想要定义多个对象时,无法用上述五大注解完成。
这两种情况需可以使用@Bean方法注解
使用
1.@Bean必须搭配五大注解使用
2.使用@Bean注解时,一个类型存在多个bean时,不能使用类型获取对象,使用bean的名称获取对象,bean的名称是方法名
@Bean传递参数
如果需要的Bean的类型对应的对象只有一个时,就直接赋值。如果有多个时通过名称来匹配。
指定路径注解---@ComponentScan
SpringBoot的特点:约定大于配置
springBoot默认扫描路径是启动类所在的目录及子孙目录
比如:启动类的代码、位置大于我们自己的代码
启动类在哪里就只扫描哪个路径下的文件内容
使用@ComponentScan指定路径
bean的命名
1.五大注解存储的bean
1.前两位名称全为大写,bean名称为类名
2.其他的为类名首字母小写
3.通过value设置属性,@Controller(value=xxx")
2.@Bean注解储存
1.bean名称为方法名
2.通过name属性设置@Bean(name="aaa ","bbb")
DI
对依赖对象的注入,也被叫做"属性装配"、"依赖装配"。
1.属性注入
使用@Autowired
2.构造方法注入
存在无参的构造函数和有参的构造函数时,不加注释会默认使用无参的构造函数
如果存在多个构造函数时,需要加上@Autowired注明使用哪个构造函数
如果只有一个构造函数,@Autowired可以省略掉
3.Set方法注入
三种注入方式的优缺点
1.属性注入
优点:简洁、使用方便
缺点:只能使用IoC容器、不能注入final修饰的属性
2.构造函数注入
优点:可注入final修饰的属性、注入的对象不会被修改;依赖对象在使用前一定会被初始化,因为依赖是在类的构造方法中执行的,而构造方法是在类加载阶段就会执行;通用性好,构造方法是JDK支持的,所以更换任何框架都是试用的。
缺点:注入多个对象时,代码会比较繁琐。
3.Set方法注入
优点:方便实例后,重新对对象进行配置或注入。
缺点:注入对象可能会被改变,因为Setter方法可能会被多次调用,就有被修改的风险;不能注入一个final修饰的属性。
@Autowired存在问题的解决方式
当程序中一个类型有多个对象时,使用@Autowired会报错
解决方式:
1.属性名和需要使用的对象名保持一致
2.使用@Primary注解标识默认的对象
3.使用@Qualifier
指定要使用的属性
4.使用@Resource注解
使用@Autowired和使用@Resource的区别
1.@Autowired是Spring框架提供的,@Resource是JDK提供的
2.@Autowired默认按照类型注入,如果一个类型存在多个对象,按名称匹配不上,就会报错。而@Resource按照名称注入,相比之下@Resource支持更多的参数设置