Spring中的IOC(控制反转) 您所在的位置:网站首页 spring中注入的3种形式 Spring中的IOC(控制反转)

Spring中的IOC(控制反转)

2023-06-23 08:34| 来源: 网络整理| 查看: 265

一、IOC的理论推导?

我自己的理解:IOC(控制反转):由控制和反转两部分组成;

控制:就是控制权,

反转:将控制权从一个人的手中,转到另一个人手中。

以前一个接口,有多个实现,用户想要访问不同是业务,需要程序员手动调换接口,

现在,通过使用set方法注入实现类的方式,让用户自己管理和访问。

 这里就相当于以前用户想要使用业务,业务的控制权在程序员手中,程序员实现了什么接口,用户才能使用什么业务;现在就是,用户自己手中有接口实现类,用户想要使用什么业务就直接注入对应的接口实现类,然后,程序去帮用户创建对应的接口实现类的对象。

之前,程序是主动创建对象,控制权在程序员手中,

使用set注入之后,程序员不在具有主动性,而变成了被动的接收对象!

这样就将创建对象的控制权从程序员控制转变成用户自己控制。

二、IOC的本质

控制反转IOC(Inversion of Control)是一种设计思想,DI(依赖注入)是一种实现IOC的一种方法,也有人认为DI只是IOC的另一种说法,没有IOC的程序中,我们使用面向对象编程,对象的创建与对象间的依赖关系完全硬编码在程序中,对象的创建由程序员自己控制,控制反转后,将对象的创建转移给了第三方,个人认为所谓的控制反转就是,获取依赖对象的方式反转了。

这种思想,本质上解决了问题,我们程序员不用再去管理对象的创建了。系统的耦合性大大降低了,可以更加专注的在业务的实现上。

三、为什么学习Spring的IOC?

现在我们知道了,以前都是程序员在代码中将所需的对象直接new出来,现在通过IOC思想将创建对象这个过程交给了Spring容器来帮我们创建我们自己需要的业务对象。

而我们需要学习的就是Spring如何去帮我们创建的对象。IOC如何实现解耦的过程。

四、Spring中的IOC是如何实现的?

控制反转是一种通过描述(XMl或注解)并通过第三方产生或获取特定对象到的方式,在Spring中实现控制反转的是IOC容器,其实现方法是依赖注入(Dependency Injection ,DI) 。

依赖注入三种方式:构造器注入,set注入,拓展方式注入

 4.1 先学习如何通过xml创建对象

1.下标赋值

//第一种:用下标赋值 2.通过类型创建 //第二种方式:通过类型创建,不建议使用 3.通过参数名 //第三种方式:直接通过参数名设置

总结:在配置文件加载的时候,容器中管理的对象已经初始化了!

4.2 通过xml获取指定对象的方式

 采用XML方式配置Bean的时候,Bean的定义信息和实现分离的,而采用注解的方式可以把两者合为一体,Bean的定义信息直接以注解的形式定义在实现类中,从而达到了零配置的目的。

代码实现:

1.pojo实体类

public class Hello { private String str; public String getStr() { return str; } public void setStr(String str) { this.str = str; } @Override public String toString() { return "Hello{" + "str='" + str + '\'' + '}'; } }

配置类: beans.xml

测试类:通过bean获取对象

public static void main(String[] args) { //获取Spring的上下文对象 ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); //我们的对象都在Spring中管理了,我们要使用,直接去里面取出来使用就可以了!!! Hello hello = (Hello) context.getBean("hello"); System.out.println(hello.toString()); } 4.3 在学IOC容器的实现方法:依赖注入

依赖注入的三种方式:构造器注入,set注入,拓展方式注入

构造器注入:就是通过new 构造器()去创建。

Set方式注入【重点】

依赖注入:set注入!

依赖:bean对象的创建依赖于容器!

注入:bean对象中的属性,由容器来注入!

代码实现:

1.pojo实体类

public class Address { private String address; public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } }

2.真实测试对象

public class Student { private String name; private Address address; private String[] books; private List hobby; private Map card; private Set games; private String wife; private Properties info; }

3.配置文件:beans.xml

4.测试类

public class MyTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); Student student = (Student) context.getBean("student"); System.out.println(student.getName()); } }

上面的测试只是注入了Student的其中name属性,还有其他属性需要注入;

5.完善注入信息:注入的属性对应的是上面的Student实体类

西游记 水浒传 红楼梦 三国演义 打篮球 游泳 LOL QQ飞车 79 456 123 4615

以上的是set最原始的注入方式,我们需要了解第三方提供的set注入方式:c命名空间和p命名空间

他们都只是在xml配置文件注入属性对象时使用:

c命名空间:

 4.4 自动装配

自己的理解:现在我们创建一个实体类,需要在xml配置文件中去注入相关属性值,现在出现了一种情景:有三个实体类,有两个实体类(cat,dog)作为另外一个实体类(people)中的属性。这三个实体类都在xml配置文件中创建一个,但是没有注入属性,但是依然想使用people这个实体类去使用另外两个实体类中的方法,该怎么办?

代码重现情景模式:

1.猫  的pojo实体类 

2.狗 的pojo实体类

3.人 的pojo实体类

4.配置文件:

 这个时候就需要用到Bean的自动注入:让Spring容器帮我们去注入属性。

有个前提:你需要让Spring帮你注入属性,前提一定要将这个属性以bean的形式注册到配置文件中,否则会注入失败。

因此我们就要学习bean的自动装配的两种方式:通过xml文件配置和通过注解配置。

xml文件配置:又分两种:byName和byType

1.byName进行自动装配;

2.byType进行自动装配。

小结:

byName的时候,需要保证所有bean的id唯一,并且这个bean需要和自动注入的属性的set方法的值一致。

byName:会自动在容器上下文中查找,和自己对象set方法后面的值对应的bean id

byType的时候,需要保证所有bean的class唯一,并且这个bean需要和自动注入的属性的类型一致。

注解配置

jdk 1.5支持注解,Spring2.5就支持注解了!

要使用注解须知:

1.导入约束:context约束

2.配置注解的支持:

3.配合@Autowired进行使用

使用Autowired 我们可以不用编写Set方法了,前提是你这个自动装配的属性在IOC(spring)容器中存在,且符合名字byName!

代码理解:

1.首先在你想要使用注解自动配置的属性或者set方式上直接添加@Autowired注解就行

public class People { private String name; @Autowired private Dog dog; @Autowired private Cat cat; public People(@NonNull String name) { this.name = name; } public People() { } public People(String name, Dog dog, Cat cat) { this.name = name; this.dog = dog; this.cat = cat; } }

2.在xml配置文件中开启注解

扩展:

 @NonNull    字段标记了这个注解,说明这个字段可以为null,

//如果显示定义了Autowired的required属性为false,说明这个对象可以为null,否则不许为空 @Autowired(required = false) private Dog dog;

如果@Autowired自动装配环境比较复杂,自动装配无法通过一个注解【@Autowired】完成时,我们可以使用@Qualifier搭配使用。

指定唯一的bean对象注入。

@Autowired @Qualifier(value = "dog222")

@Resoure 注解和@Autowired效果一致

使用他时,如果bean的id是对应且唯一的,可以有多个bean,或者id不对应,但是后面的class是唯一的也可以使用。

public class People { private String name; @Resource(name = "dog222") private Dog dog; @Resource private Cat cat; }

小结:

@Resoure和@Autowired的区别?

1.@Resoure是java的,@Autowired是来自spring的

2.java的注解,属性较多,type无法分辨时可以用name分辨;

spring的注解,一个属性,type无法分辨时需要借助@Qualifier注解才能使用 使用@Autowired方式最好使用构造函数的方式注入。

3.都是用来自动转配的,都可以放在属性字段上

4.@Autowired 通过byType的方式实现的,而且必须要求这个对象存在!【常用】

@Resoure默认通过byName的方式实现,如果找不到名字,则通过Type实现,如果两个都找不到的情况下,就报错!【常用】

5.执行顺序不同:@Autowired自动装配通过类型,名字

如果Autowired不能唯一的自动装配,则需要通过@Qualifier(value=“ ”)

@Resoure:自动装配通过名字,类型

五、使用注解开发

上面全都需要自己将实体类对应的一个一个的手动注册到xml配置文件中,现在只需要在实体类前添加一个注解@Component(组件),就相当于在xml配置文件中进行了注册。大大简化了开发过程。

使用注解开发的前提

在Spring4之后,要使用注解开发,必须要保证aop的包导入了

使用注解开发步骤:

1.使用注解需要导入context约束,添加注解的支持和你注解使用在那个包下,开启包扫描使注解生效完成,注册。 

 2.在实体类中添加注解,将实体类交给Spring去管理

//等价于 //@Component 组件 @Component public class User { //相当于 @Value("lx") public String name ; public void setName(String name) { this.name = name; } }

测试使用:

public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml"); User user = context.getBean("user", User.class); System.out.println(user.name); }

3.衍生的注解

@Component有几个衍生注解。我们在web开发中,会按照mvc三层架构分层!

dao 【@Repository】

service 【@Service】

controller 【@Controller】

这四个注解功能都是一样的,都是代表某个注解注册到Spring中,装配bean。

小结

xml与注解:

xml更加万能,适用于任何场合!维护简单方便

注解 不是自己类使用不了,维护相对复杂!

xml与注解最佳实践:

xml用来管理bean

注解只负责完成属性的注入

我们在使用的过程中,只需要注意一个问题:必须让注解生效,就需要开启注解的支持

第一次正式发表博客,如果各位网友发现了有什么问题,可以在评论区进行留言讨论,相互学习。

本博客是我通过观看哔哩哔哩up主的视频进行学习的:如有不懂,可通过链接进行学习:1、Spring简介_哔哩哔哩_bilibili



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有