Spring IoC学习总结

Spring框架是Java应用最广的框架,它的成功来源于理念,而不是技术本身,它的理念包括IoC(Inversion of Control,控制反转)和AOP(Aspect Oriented Programming,面向切面编程)

IoC是一个容器,Spring中,会认为一切Java资源都是Java Bean,容器的目标就是管理这些Bean以及它们之间的关系。所以在Spring Ioc中装载的各种Bean,也可以理解为Java的各种资源,其中包括Java Bean的创建、事件、行为等,它们由IoC容器管理。除此之外,各个Java Bean之间会存在一定的依赖关系,这些也都是IoC容器进行管理。

只是Spring IoC管理对象和其依赖、关系,采用的不是人为的主动创建,而是由Spring IoC自己通过描述创建的,也就是说Spring是依靠描述来完成对象的创建及其依赖关系的。

控制反转的概念:控制反转是一种通过描述(在Java中可以是XML或者注解)并通过第三方去产生或获取特定对象的方式。Spring中实现控制反转的是IoC容器,实现方法是依赖注入(Dependency InJection,DI)

如何理解控制反转,举下面一个例子。榨橙汁,如果是主动地创建,我们需要实现可能不是很熟悉的工作比如搅拌橙汁,而橙汁需要依赖于水,水果,糖和搅拌机去实现,这个关系也需要我们自己去维护。而如果是一个很大的系统,如果都这样维护那么会十分复杂,我们并不需要了解这个过程,我们只需要获取最后的结果。比如由各饮品店,只要对结果进行描述,就能得到我们所需要的饮品。

我们只需要设计好自己的Bean,将Bean添加到IoC容器中,然后构建依赖关系。使用Bean时从IoC容器得到Bean即可。

IoC容器设计

Spring IoC容器的设计主要是基于BeanFactory和ApplicationContext两个接口,BeanFactory是Spring IoC容器所定义的最底层接口,而ApplicationContext是其高级接口之一,并且对BeanFactory功能做了许多有用的扩展,所以在绝大部分的工作场景下,都会使用ApplicationContext作为Spring IoC容器。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hz2uWtkd-1590394435472)(https://note.youdao.com/yws/res/15046/WEBRESOURCE60ff609a3a676db8ed15299cb2ba54d4)]

IoC容器的初始化和依赖注入

Bean的初始化和依赖注入在Spring IoC容器中是两大步骤,它是在初始化之后才会进行依赖注入

Bean的初始化分为3步:

  1. Resource定位,这步是Spring IoC容器根据开发者的配置,进行资源定位,在Spring开发中,通过XML或者注释都是很常见的方式,定位内容由开发者提供
  2. BeanDefinition的载入,这个过程就是Spring根据开发者的配置获取对应POJO,用以生成对应实例的过程
  3. BeanDefinition的注册,相当于把上一步中载入的POJO往Spring IoC容器中注册,这样就可以通过描述从中得到Spring IoC容器的Bean了

经过以上步骤,Bean就在IoC容器中得到了初始化,但是没有依赖注入,也就是没有注入其配置资源给Bean。

对于依赖注入,Spring Bean还有一个配置选项一一lazy-init,其含义就是是否初始化Spring Bean。在没有任何配置的情况下,它的默认值为default,实际值为false,也就是Spring IoC默认会自动初始化 Bean。如果将其设置为true,那么只有当我们使用Spring IoC容器的getBean方法获取它时,它才会进行初始化,完成依赖注入。

Spring Bean的生命周期

对于Bean而,在容器中存在其生命周期,它的初始化和销毁也需要一个过程,在 一些需要自定义的过程中,我们可以插入代码去改变它们的一些行为,以满足特定的需求。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vVx0cVgZ-1590394435475)(https://note.youdao.com/yws/res/15084/WEBRESOURCE64ad339ff72783037f95e2443c6ac5aa)]

注意以上的接口是针对什么而言的,大部分是针对单个Bean而言的:BeanPostProcessor接口则是针对所有Bean而言的,接口DisposableBean则是针对Spring IoC容器本身

下面有一个例子,展示出了Spring Beans的生命周期,这个例子是以果味饮料店相关的,我们可以提供给饮品店想要的口味等情况,然后饮品店会给我们产生饮料。

定义了我们想要的饮料“参数”

    public class Source {
    	private String fruit;
    	private String sugar;
    	private String size;
    	
    	/** getter and setter **/
    }

定义了饮品店,并且实现了相应的接口,重写了方法:

    public class JuiceMaker implements BeanNameAware, BeanFactoryAware, ApplicationContextAware, InitializingBean {
    	private String juiceShop = null;
    	private Source source = null;
    
    	public String makeJuice() {
    		String juice = "这是一杯由" + juiceShop + "饮品店提供的" + source.getSize() + source.getSugar() + source.getFruit();
    		return juice;
    	}
    	
    	// 自定义初始化方法
    	public void init() {
    		System.out.println("***"+this.getClass().getSimpleName()+"*** 执行自定义初始化方法");
    	}
    	
    	// 自定义销毁方法
    	public void destory() {
    		System.out.println("***"+this.getClass().getSimpleName()+"*** 执行自定义销毁方法");
    	}
    	
    	public void afterPropertiesSet() throws Exception {
    		System.out.println("***"+this.getClass().getSimpleName()+"*** 调用InitializingBean接口的afterPropertiesSet方法");
    	}
    
    	public void setApplicationContext(ApplicationContext arg0) throws BeansException {
    		System.out.println("***"+this.getClass().getSimpleName()+"*** 调用ApplicationContextAware接口的setApplicationContext方法");
    	}
    
    	public void setBeanFactory(BeanFactory arg0) throws BeansException {
    		System.out.println("***"+this.getClass().getSimpleName()+"*** 调用BeanFactoryAware接口的setBeanFactory方法");
    	}
    
    	public void setBeanName(String arg0) {
    		System.out.println("***"+this.getClass().getSimpleName()+"*** 调用BeanNameAware接口的setBeanName方法");
    	}
    	
    	/** getter and setter **/
    }

BeanPostProcessor接口的实现类,针对所有Bean

    public class BeanPostProcessorImpl implements BeanPostProcessor {
    	
    	public Object postProcessBeforeInitialization(Object bean, String beanName) {
    		System.out.println("---" + bean.getClass().getSimpleName() + "--- 对象" + beanName + "开始实例化");
    		return bean;
    	}
    	public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    		System.out.println("---" + bean.getClass().getSimpleName() + "--- 对象" + beanName + "实例化完成");
    		return bean;
    	}
    }

DisposableBean接口实现类,针对Spring IoC容器的销毁

    public class DisposableBeanImpl implements DisposableBean {
    	public void destroy() throws Exception {
    		System.out.println("调用接口DisposableBean的destroy方法");
    	}
    }

spring配置文件,里面定义了bean以及它们之间的依赖关系。在执行初始化时,是按照xml中标签的顺序进行初始化的。

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd">
    	
    	<bean id="beanPostProcessor" class="bean.BeanPostProcessorImpl" />
    	<bean id="disposableBean" class="bean.DisposableBeanImpl" />
    	
    	<bean id="source" class="pojo.Source">
    		<property name="fruit" value="橙汁" />
    		<property name="sugar" value="少糖" />
    		<property name="size" value="大杯" />
    	</bean>
    	
    	<bean id="juiceMaker" class="pojo.JuiceMaker" init-method="init" destroy-method="destory">
    		<property name="juiceShop">
    			<value>七粒冰</value>
    		</property>
    		<property name="source" ref="source" />
    	</bean>
    </beans>

下面是我们的测试类

    public class Test {
    	public static void main(String[] args) {
    		ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
    		JuiceMaker juiceMaker = (JuiceMaker) context.getBean("juiceMaker");
    		System.out.println(juiceMaker.makeJuice());
    		context.close();
    	}
    }

输出结果如下:

---DisposableBeanImpl--- 对象disposableBean开始实例化
---DisposableBeanImpl--- 对象disposableBean实例化完成
---Source--- 对象source开始实例化
---Source--- 对象source实例化完成
***JuiceMaker*** 调用BeanNameAware接口的setBeanName方法
***JuiceMaker*** 调用BeanFactoryAware接口的setBeanFactory方法
***JuiceMaker*** 调用ApplicationContextAware接口的setApplicationContext方法
---JuiceMaker--- 对象juiceMaker开始实例化
***JuiceMaker*** 调用InitializingBean接口的afterPropertiesSet方法
***JuiceMaker*** 执行自定义初始化方法
---JuiceMaker--- 对象juiceMaker实例化完成
这是一杯由七粒冰饮品店提供的大杯少糖橙汁
***JuiceMaker*** 执行自定义销毁方法
调用接口DisposableBean的destroy方法
  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值