一:简述
SpringIoc概念较为抽象,但其实不同之处就在于主动创建对象和被动创建对象的过程,拿饮品进行举例:要喝到果汁无疑就两种办法,自己做和买别人做的
1.主动创建对象
自己做果汁需要原料和工具,那么创建对象:JuiceMaker和Blender
package springioc.activemake;
/**
* @Auther: 洺润Star
* @Date: 2019/9/14 14:20
* @Description: 搅拌机
*/
public class Blender {
public String mix(String water,String fruit,String sugar){
String juice = "这是一杯由液体:"+water+"\n水果:"+fruit+"\n糖量:"+sugar+"组成的果汁";
return juice;
}
}
package springioc.activemake;
/**
* @Auther: 洺润Star
* @Date: 2019/9/14 14:25
* @Description: 果汁生成器
*/
public class JuiceMaker {
private Blender blender = null;//搅拌机
private String suger;
private String water;
private String fruit;
public Blender getBlender() {
return blender;
}
public void setBlender(Blender blender) {
this.blender = blender;
}
public String getSuger() {
return suger;
}
public void setSuger(String suger) {
this.suger = suger;
}
public String getWater() {
return water;
}
public void setWater(String water) {
this.water = water;
}
public String getFruit() {
return fruit;
}
public void setFruit(String fruit) {
this.fruit = fruit;
}
/**
* 果汁生成
* @return
*/
public String makeJuice(){
blender = new Blender();
return blender.mix(water,fruit,suger);
}
}
其中果汁需要我们自己制作,可能会面对自己并不了解的情况,所以我们一般更喜欢去饮品店购买,换而言之就是被动创建我们的对象
2.被动创建对象
假设现已经有了果汁制造器(JuiceMaker2),而且我们还会得到一个描述(source)我们可以借此来得到需要的饮品,下面编写果汁制造器和果汁描述清单
package springioc.passivemake;
/**
* @Auther: 洺润Star
* @Date: 2019/9/14 14:49
* @Description:
*/
public class Source {
private String fruit ;
private String sugar;
private Integer size;
public String getFruit() {
return fruit;
}
public void setFruit(String fruit) {
this.fruit = fruit;
}
public String getSugar() {
return sugar;
}
public void setSugar(String sugar) {
this.sugar = sugar;
}
public Integer getSize() {
return size;
}
public void setSize(Integer size) {
this.size = size;
}
}
package springioc.passivemake;
/**
* @Auther: 洺润Star
* @Date: 2019/9/14 14:35
* @Description:
*/
public class JuiceMaker2 {
private String beverageShop = null;
private Source source =null;
/*
* 果汁生成
* @return
*/
public String makeJuice(){
return "这是一杯由"+beverageShop+"饮品店提供的"+source.getSize()+source.getFruit()+source.getSugar();
}
public String getBeverageShop() {
return beverageShop;
}
public void setBeverageShop(String beverageShop) {
this.beverageShop = beverageShop;
}
public Source getSource() {
return source;
}
public void setSource(Source source) {
this.source = source;
}
/*xml进行描述*/
/*
* <bean id ="source" class = "">
*</bean>
* */
}
我们无需关注果汁的制造过程,可以采用xml的方式进行配置即可
3.简单阐述
通过示例得到,控制反转是通过描述(例如XML或注解)并通过第三方去获取特定对象的方式,实现控制反转的方式是倚赖注入(DI)
二:springIoc容器
从上可知,SpringIoc容器的作用就是可以容纳我们开发的bean,我们也可以从中获取需要的Bean
1.springIoc容器的设计
基于的接口:BeanFactory和ApplicatiionContext两个接口
其中第二个接口是BeanFactory的子接口之一,而BeanFactory是SpringIoc所定义的最底层的接口,下面是springIoc容器接口的主要设计
其中BeanFactory的源码如下,本人加了些许注释
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//
package org.springframework.beans.factory;
import org.springframework.beans.BeansException;
import org.springframework.core.ResolvableType;
import org.springframework.lang.Nullable;
public interface BeanFactory {
String FACTORY_BEAN_PREFIX = "&";
Object getBean(String var1) throws BeansException;
<T> T getBean(String var1, Class<T> var2) throws BeansException;
Object getBean(String var1, Object... var2) throws BeansException;
<T> T getBean(Class<T> var1) throws BeansException;
<T> T getBean(Class<T> var1, Object... var2) throws BeansException;
<T> ObjectProvider<T> getBeanProvider(Class<T> var1);
<T> ObjectProvider<T> getBeanProvider(ResolvableType var1);
//以上的多个getbean方法用于获取配置给Spring Ioc的bean
boolean containsBean(String var1);
//判断是否为单例
boolean isSingleton(String var1) throws NoSuchBeanDefinitionException;
boolean isPrototype(String var1) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String var1, ResolvableType var2) throws NoSuchBeanDefinitionException;
boolean isTypeMatch(String var1, Class<?> var2) throws NoSuchBeanDefinitionException;
@Nullable
Class<?> getType(String var1) throws NoSuchBeanDefinitionException;
//获取别名的方法
String[] getAliases(String var1);
}
现通过ApplicationContext 的一个子类ClassPathXmlApplicationContext来举一个例子
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">
<!--将对象的创建交给spring容器中,在配置文件里声明我要什么对象-->
<bean class="springioc.passivemake.Source" id="source">
<property name="fruit" value="橙汁"/>
<property name="sugar" value="少糖"/>
<property name="size" value="12"/>
</bean>
<bean class="springioc.passivemake.JuiceMaker2" id="juiceMaker2">
<property name="beverageShop" value="贡茶"/>
<property name="source" ref="source"/>
</bean>
</beans>
进行测试
@Test
public void m1(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
JuiceMaker2 juiceMaker2 = (JuiceMaker2) ctx.getBean("juiceMaker2");
System.out.println(juiceMaker2.makeJuice());
/*这是一杯由贡茶饮品店提供的12橙汁少糖*/
}
以上代码首先定义了两个bean,然后使用 ClassPathXmlApplicationContext对其进行初始化,来获得资源对象
2.SpringIoc容器的初始化和倚赖注入
首先:Bean的初始化和倚赖注入在springIoc容器中的两大步骤,而在初始化之后,才会进行倚赖注入
bean的初始化分为以下三个步骤:
- Resource定位
- BeanDefinition(获取对应Pojo)
- BeanDefinition注册
3.SpringBean的生命周期
Spring ioc容器的本质就是为了管理bean,而bean在容器中存在生命周期,在bean的销毁和创建的过程中我们可以自定义一些行为,这就需要了解Spring Bean的生命周期