Spring IoC&DI
一.IoC&DI简单介绍
IoC叫控制反转,是一种设计原则,降低代码的耦合度。简单的举例:在未使用IoC设计原则时,对象的创建是使用方进行管理的,也就导致对象的控制权在使用方手里,但使用了IoC设计原则之后,就会有一个外部容器(Spring)来进行统一管理和创建,使用方不再管理对象的创建和依赖关系,也就失去了控制权,控制权就给了IoC容器,这就是控制反转。
DI是依赖注入。
二.控制反转的简单例子和使用
1.未使用IoC设计理念时的一个代码:
public class Tire {
private int size;
public Tire(int size) {
System.out.println("Tire size: " + size + " Init...");
}
}
public class Bottom {
private Tire tire;
public Bottom(int size) {
this.tire = new Tire(size);
System.out.println("Tire Init...");
}
}
public class FrameWork {
private Bottom bottom;
public FrameWork(int size) {
this.bottom = new Bottom(size);
System.out.println("FrameWork Init...");
}
}
public class Car {
private FrameWork frameWork;
public Car(int size) {
this.frameWork = new FrameWork(size);
System.out.println("Car Init...");
}
public void run() {
System.out.println("run...");
}
}
public class Main {
public static void main(String[] args) {
Car car = new Car(20);
car.run();
}
}
当使用了IoC设计原则时,对象的创建和管理都是统一在一起的,并且也降低了代码的耦合性,像上图中的代码中,当Tire创建新的字段并成为构造方法的参数时,调用了Tire对象的每个使用方都需要在里面加上新的参数,而IoC设计原则就是这方面代码的耦合性降低了很多,代码如下:
public class Tire {
private int size;
public Tire(int size) {
System.out.println("Tire size: " + size + " Init...");
}
}
public class Bottom {
private Tire tire;
public Bottom(Tire tire) {
this.tire = tire;
System.out.println("Tire Init...");
}
}
public class FrameWork {
private Bottom bottom;
public FrameWork(Bottom bottom) {
this.bottom = bottom;
System.out.println("FrameWork Init...");
}
}
public class Car {
private FrameWork frameWork;
public Car(FrameWork frameWork) {
this.frameWork = frameWork;
System.out.println("Car Init...");
}
public void run() {
System.out.println("run...");
}
}
public class Main {
public static void main(String[] args) {
Tire tire = new Tire(20);
Bottom bottom = new Bottom(tire);
FrameWork frameWork = new FrameWork(bottom);
Car car = new Car(frameWork);
car.run();
}
}
2.使用了IoC设计原则并且使用注释来写代码:
其中Component注解是Spring统一管理对象的创建和依赖,Autowired是使用Spring统一管理的对象
3.Bean简单说明:
使用Bean注解或者下方所说的衍生注解,作用于类时,就会将这些类的对象交给Spring来进行管理,对象本身不需要负责对象的创建和依赖。(在userInfo2的方法中,参数的名字也必须和Spring管理的方法的方法名一样,如果不相同就无法使用。)
三.Bean的存储
1.Controller注解(控制器存储)
被Controller修饰的类,则其对象会被Spring统一管理,并且RestController也可以做到同样的效果。
2.获取Bean对象的其他方式
(1)根据bean的名称获取bean:
bean名称在官方文档中有规定的:
简单的来说,bean的名字当为null或者长度为0时,直接返回这个name,当name的长度大于1,并且第一个和第二个单词都是大写的name也是直接返回name,其他情况都是将name先转换成字符数组,在将第一个字母改为小写,最后转换成字符串返回name。
(2)根据bean的名字和类型获取bean
(3)根据类型获取bean,一般用于只有一个对象
也因此,Spring涉及的模式是单例模式。
四.其余注解
1.Service
2.Configuration
3.Component
4.Repository
以上获取bean的方式都与UserController相同,并且Controller,Service,Repository,Configuration都是Component的衍生注解。
五.Bean注解
1.当需要使用外部包的类时,没办法添加类注解和一个类,需要多个对象,比如数据源时,需要通过Bean方法注解获得对象(假设UserInfo是外部包的类,因为在UserInfoComponent的类中存在两个对象,若果通过类型获取,则不知道获取那个对象,所以必须通过方法名来获取):
2.重命名Bean
可以通过Bean改变方法的名字,在新的名字字符串数组中选取其中一个就可以来进行获取对象(简便的写法可以把name = 给省略了,当只有一个字符串的时候可以不用写{})。
3.扫描路径:@ComponentScan
当启动类的路径和需要使用的第三方包不在同一个路径是,需要调用第三方的包,就可以使用@ComponentScan({“”})来往其中输入路径来进行扫描,并且括号里面是一个字符串数组,则可以写多个路径来扫描:
六.DI依赖注入
1.属性注入
Autowired直接作用于类的属性,就是属性注入,Spring管理的对象就能够直接使用。
2.构造方法注入
存在多个构造方法时,需要指定默认的构造方法就是用Autowired来进行指定。
3.setter方法注入
同样使用Autowired,让程序能进入set方法,并且从Spring中拿取对象。
4.三种注入方式优缺点
属性注⼊
◦ 优点:简洁,使⽤⽅便;
◦ 缺点:
▪ 只能⽤于IoC容器,如果是⾮IoC容器不可⽤,并且只有在使⽤的时候才会出现NPE(空指
针异常)
▪ 不能注⼊⼀个Final修饰的属性
• 构造函数注⼊(Spring4.X推荐)
◦ 优点:
▪ 可以注⼊final修饰的属性
▪ 注⼊的对象不会被修改
▪ 依赖对象在使⽤前⼀定会被完全初始化,因为依赖是在类的构造⽅法中执⾏的,⽽构造⽅法
是在类加载阶段就会执⾏的⽅法.
▪ 通⽤性好,构造⽅法是JDK⽀持的,所以更换任何框架,他都是适⽤的
◦ 缺点:
▪ 注⼊多个对象时,代码会⽐较繁琐
• Setter注⼊(Spring3.X推荐)
◦ 优点:⽅便在类实例之后,重新对该对象进⾏配置或者注⼊
◦ 缺点:
▪ 不能注⼊⼀个Final修饰的属性
▪ 注⼊对象可能会被改变,因为setter⽅法可能会被多次调⽤,就有被修改的⻛险。
七.Autowired出现的问题
1.同样类型,有多个名称对象时,按照名称来匹配
2.当该类型只有一个对象时,就直接注入
3.在1.的情况下,没有名称匹配
(1)通过注解Primary来确定默认的对象:
(2)通过@Qualifier来对注入的时候进行指定对象:
(3)当传入参数名不在Spring中时,需要确定一个默认的参数的方法:
1. 通过Primary确定默认参数:
2.通过Qualifier在传递参数时指定某个参数:
(4)使用JDK的注解Resource
使用JDK的Resource注解可以指定我们使用的是哪个方法:
八.Resource和Autowired的区别
1.Resource根据名称匹配,Autowired根据类型匹配:这句话的意思只不过代表着,同类型时的多个对象,Resource是根据名称优先匹配,再根据类型进行匹配,Autowired则是先通过类型进行匹配,再进行名称进行匹配,着重去理解其中原理。
2.Autowired和Resource的基本原则都是根据类型进行匹配,只是Resource可以指定名称,而Autowired无法根据名称匹配。所谓指定根据名称进行匹配,指定是Resource的括号里可以写name = “对象名称”进行匹配,但Autowired无法指定对象名称。而不是所谓的变量名的名称。
3.Resource可以粗糙的说等于Autowired + Qualifier。
4.Resource是JDK提供的注解,Autowired是Spring提供的注解。
5,Autowired的装配顺序:
原文地址:https://blog.csdn.net/wk200411/article/details/145088271
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!