Spring是目前JavaWeb开发中比较常用的开发框架,本人在过往的项目中有不少使用到Spring的difan。这次我们来简单谈谈控制反转(Inversion Of Controll,即 IOC)。
首先,我们来看看Spring官方是如何定义IOC的。
翻译过来的大概意思就是:
IoC也被称为依赖注入(DI)。它是一个对象定义其依赖关系的过程,也就是它们使用的其他对象,只通过构造函数参数、对工厂方法的参数,或在构建或从工厂方法返回后在对象实例上设置的属性。然后容器在创建bean时注入这些依赖项。这个过程从根本上说是反向的,因此称之为控制反转(IoC),bean本身通过直接构造类或服务定位器模式等机制来控制其依赖关系的实例化。
通过这个定义,我们对IOC有了概念上的了解,另外可以结合下面的图来理解这段定义:
Spring对依赖关系的管理,是通过配置的形式来实现的,有多种途径,下文我们会谈到。如上图所示,我们理清一下步骤:
-
首先Spring读取配置(依赖关系);
-
初始化好的IOC容器(其实就是BeanFactory);
-
根据依赖关系找到对应的POJO,然后创建并组装Bean;
-
从容器获取Bean.
以上就是Spring的IOC的实现过程,那么我们具体可以怎么用呢?
Spring主要提供三种装备机制:
-
在XML中进行显式配置;
-
在Java中进行显式配置;
-
隐式的bean发现机制和自动装配
1、在XML中配置:
我们需要在spring的配置文件中进行配置,没有则需要创建,最简单的配置文件写法如下:
几种不同的方式需要再配置文件上添加一些标签:
-
通过构造器注入:
-
直接指定类(较为常用):
-
借助构造器实现注入:
这里的意思就是,Spring会根据person这个id找到对应的引用,然后把这个bean作为参数传递给Coder.class的带参构造函数中.
借助Setter实现属性注入:
property标签中的name是对应这个属性的名称,后者是引用的id.
以上该部分就是通过XML配置注入的主要方式,完全使用XML配置时,实体bean中不需要作其他配置。
2、通过Java代码装配bean:
由于在某些应用场景上,如要将第三方库中的组件装配到自己的应用里,这个时候就无法在实体类上添加@Component和@Autowired注解,无法实现自动装备,所以这时候可以采用更个性化的配置方式Java代码装配。
1) 首先,我们要创建配置类:
该类使用了@Configuration注解,使用该注解,Spring就会把这个类识别为配置类。
2) 声明简单的bean
使用@Bean注解的方法就是返回一个实体的,createPerson方法中返回Person实例,而coder的方法实例化需要一个Person实体,这时候就会根据JavaConfig获得返回的Person实体,然后实体化Coder.
Spring的对象初始化只会执行一次,而且是单例的,所以我们会由始至终的使用这个coder对象,其实上面这种写法容易误解,以为两个方法有点相互引用的样子,更容易理解的代码是这样的:
3、自动装配bean:
Spring从两个角度来实现自动化装配:
- 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean。
- 自动装配(autowiring):Spring自动满足bean之间的依赖。
使用@Compnent注解这一步还不能让Spring自动创建bean,因为组件扫描默认是不启用的。我们还需要显式配置下Spring,从而让Spring寻找带有@Component注解的类,有两种方式,个人偏向后者:
- 在所在的包里,定义配置类:
- 在XML中配置,添加下面的配置信息,启用组件扫描:
通过自动装配的类,如何在其他类中引用呢?这个时候autowiring派上用场了,我们只需要在对应的类上通过以下方式,就可以调用创建好的bean,以及使用该类的方法等:
由开篇至此,IOC的使用使用方法都列举了。不过,一般而言,项目中并用Spring的IOC来初始化实体类,而是用来实例化dao,service和controller,因为项目可能是对多个实体进行操作的,而Spring的IOC是单例的。
后面部分是关于IOC的底层实现原理,有兴趣的朋友可以继续往下看。
Spring源码底层实现原理(通过XML方式初始化bean),实现步骤是这样的:
-
读取XML配置
-
初始化容器——beanFactory
-
为bean注入属性
-
注册生成bean
-
获取bean
-
将bean交回给applicationContext
博客与公众号同步更新,有兴趣的朋友可以关注下.