ICO\DI(控制翻转\依赖注入)是spring中比较核心的功能,也是其称霸java框架的主要原因之一,spring可以理解为众多框架的粘合剂,让项目中轻松可以引入想要使用的框架,能够让引入的框架之间解耦,可以看下在网上找到的图片,形容的很生动:
一、spring ioc初步
1、引入spirng核心包 spring-context
2、编写beans.xml,bean节点很简单,里面两个内容 id=也就是在spring容器内部的id,class=需要托管给容器的类路径
PS:
① 这里可以使用name="g1,g2,g3",都能从容器中获取到bean,id值为第一个g1。同时可以使用alias标签进行别名的命名。
② import 可以配置多个bean.xml,每个bean.xml可以使用import标签引用其它bean.xml中的配置。
3、编写单元测试,获取容器中的bean可以使用 beanFactory中的getBean()方法。
PS:其实整体的显示可以简单的概括一下,spirng开始加载xml,解析出xml后,通过反射实例化相关的bean,同时把bean存入到容器中。
二、容器的实例化
容器实例一共分为三中方式
1、构造器(推荐使用)
2、静态工厂方法
3、实例化工厂方法
构造器
ICO默认实现的方式,就是构造器实现,同时在没有指定的情况下,使用无参的构造器。如果我们覆盖了无参构造器,则会出现无法注入bean的情况。
那么内部类如何进行注入呢?进行如下编写即可,其实内部类在编译成class文件的时候,也可以看到,里面是GoodServiceImp$A.class
静态工厂方法
产生对象是又一个工厂类中的静态方法进行创建的。
实例化工厂方法
产生对象是又一个工厂类中的方法进行创建的。只不过实例化工厂需要交给IOC容器进行创建。
三、依赖注入(DI)
在业务开发中,当一个bean依赖另外一个bean的时候,这样可以把被引用的bean交给spring进行托管,这就是依赖注入,依赖注入有2中方式:
1、构造器
2、setter方法依赖注入(推荐,可以解决循环引用问题)
setter方法依赖注入
首先依赖其他bean的bean中需要提供set方法
在配置中指定两个属性的引用,只不过要注意的是,属性是bean还是一个值,如果是值直接使用value进行配置即可
集合类型:
也可以简化一下注入方式:
构造器
顾名思义使用代参构造器进行注入
首先bean需要提供一个代参的构造方法
在注入的时候,使用constructor-arg进行配置即可
PS:在平时的引用过程中,尽量使用setter注入,因为可以解决循环依赖的问题,而构造器注入是没有办法解决循环依赖的问题的。
四、依赖注入的自动配置 在配置文件中增加 <context:annotation-config/>
自动装配提供三中注解,这些注解在平时经常使用,但是不是理解具体应用场景。
1、@Autowired:字段、构造器、set方法
装配规则:默认按照属性值的Class类型进行装配,跟属性名称没关系。当接口有多个实现类的时候,程序就不知道用哪个实现类进行初始化,这个时候需要使用 @Qualifier(value = ""),来指定使用哪个实现类进行注入。
2、@Resource:字段、set方法
装配规则:默认按照属性名称实现字段装配,如果未找到此时按照属性Class类型进行装配。如果接口存在多个实现,则直接指定name = "",来指定哪个类进行注入。
五、扫描器
为了真正的减少配置操作,也就是为了减少项目中的xml。所以spring还提供了扫描器和注解进行配合使用。
1、引入扫描器:
① 引入xml的
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
② 加入标签
<context:component-scan base-package="需要扫描的包"/>
2、引入注解,spring提供了四个注解,可以满足日常相关bean注入的使用
① @Repository:习惯用于持久层
② @Service:习惯用于业务层
③ @Controller:习惯用于接口层
⑤ @Component:习惯用于其他层,需要托管给spirng容器管理类
六、spring5注解式应用开发
从spring3.x之后,spring开始的更多注解的引用,主要目的是为了减少xml配置工作,知道spirng5中,已经可以基本脱离了各种繁琐的xml配置,进行全面的注解开发了。现在常用的框架spring-boot就是完全依赖了spring的注解开发。
spring基本常用的注解:传送门
1、@Configuration:用于类,让配置类代替xml配置文件
2、@Bean:用于方法,把方法返回的bean托管给spring,一般用于组件集成
3、@Value:用于字段,把配置文件中的值注入到字段中
4、@ComponentScan:用于类,包扫描器
5、@PropertySource:用于类,配置文件的加载
当我们期望采用0配置的进行注解式开发的时候,需要提供一个类,这个类就代替了之前的.xml配置文件(其实就是在类上添加一些列的注解)
七、bean的作用域
spring提供作用域如下。我们常用的可能就是单例和原型两种方式
1、singleton(默认方式,单例):scope="singleton",@Scope("singleton") 只有一个对象
2、prototype:scope="prototype",@Scope("prototype") 每次返回的都是一个新对象
PS:
1、什么样的对象适合单例:无状态的对象适合单例,所谓无状态就是对象的属性值不轻易改变的。
2、lazy-init:懒加载,其实就是在调用对象的时候进行加载
① 当对象可能出现都用不到的时候,可以使用懒加载
② 如果对象使用频繁,并且期望在编译的时候就确定是否正确,就可以关闭懒加载
八、bean的生命周期
在spring中bean的生命周期分为5个阶段:
实例化->属性赋值->初始化->使用->销毁
详细的生命名流程可以查看文章:传送门
可以看到,在不通阶段,进行了不通的输出文字输出,同时在结束的时候关闭spring容器,输出结果如下:
同时在spirng中,针对不通的生命周期,可以实现不通的接口,对某个阶段前或者后进行功能增强。
Bean在创建过程中调用方法大概分为四类:
1、Bean自身的方法:构造方法(实例化)、set方法(属性注入)、init方法(初始化)、destroy(销毁方法)
2、Bean级生命周期接口方法(Aware):这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DisposableBean等接口
① Aware 接口,是让bean在初始化之后,可以操作一些容器的内容。
② InitializingBean接口代替xml中配置的init-method
③ DisposableBean接口代替xml中配置的destroy-method
3、容器级生命周期接口方法:这个包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”。需要注意是会影响多个bean的实例化、初始化。
① BeanPostProcessor:提供了初始化之前和之后的操作(Initialization 表示初始化,对象已经生成)
② InstantiationAwareBeanPostProcessor:是BeanPostProcessor的子类,提供了实例化之前和之后的操作(Instantiation 表示实例化,对象还未生成)
4、工厂后处理器接口方法:这个包括了AspectJWeavingEnabler,ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。在应用上下文装配配置文件之后立即调用。)
本文章主要是在复习了一下spring ioc的基础知识。