Spring IOC
一、什么是IOC
DI全称Dependency Injection,依赖注入,在Spring框架负责创建Bean对象时,动态的将依赖对象注入到Bean组件。j具体有构造器注入、setter注入、静态工厂注入、实例工程注入。
IOC全称 Inverse of Control ,控制反转。就是将系统中创建对象的控制权由Spring管理。Spring通过一个配置文件描述Bean和Bean之间的关系,利用反射功能实例化Bean并建立Bean之间的依赖关系。Spring IOC容器除了完成这些底层工作,还提供了Bean实例缓存、生命周期管理等服务。
Bean在Spring容器中的大概流程:Spring启动时读取Bean配置信息,并在Spring容器中生成一份相应的 Bean 配置注册表,然后根据这张注册表实例化 Bean,装配好 Bean 之间的依赖关系,为上层应用提供准备就绪的运行环境。其中 Bean 缓存池为 HashMap 实现。
二、Bean生命周期、
spring bean的加载流程重点说出几个问题就行了:1、加载calss准备BeanDefinition。2、BeanFactoryPostPropercessor和BeanPostProcessor的执行时间和作用。3、其他接口的实现时间,比如aware接口。4、重点说单利对象的实例化过程(检查,构造方法推断,属性注入,实例化,代理对象生成等等)。
实例化(Instantiation) —— 属性赋值 (Populate)—— 初始化 (Initialization)—— 销毁(Destructio)
------------------------------------------------------------------------------------------------------------------------------------------
1.实例化一个Bean对象
------------------------------------------------------------------------------------------------------------------------------------------
2.为Bean设置相关的属性和依赖
------------------------------------------------------------------------------------------------------------------------------------------
3.如果Bean实现BeanNameAware 执行 setBeanName
4.如果Bean实现BeanFactoryAware 执行setBeanFactory ,获取Spring容器
5.如果存在类实现 BeanPostProcessor(前置处理) ,执行postProcessBeforeInitialization
6.如果Bean实现InitializingBean 执行 afterPropertiesSet
7.调用<bean init-method="init"> 指定初始化方法 init
8.如果存在类实现 BeanPostProcessor(后置处理) ,执行postProcessAfterInitialization
9. context.getBean(); 执行业务处理
------------------------------------------------------------------------------------------------------------------------------------------
10. 执行postProcessBeforeDestruction()
11.如果Bean实现 DisposableBean 执行 destroy
12.调用<bean destroy-method="customerDestroy"> 指定销毁方法 customerDestroy
------------------------------------------------------------------------------------------------------------------------------------------
基础知识
1.【Sring中BeanFactory和FactoryBean区别】
BeanFactory是个Factory,也就是IOC容器或对象工厂,FactoryBean是个Bean。在Spring中,所有的Bean都是由 BeanFactory(也就是IOC容器)来进行管理的。但对FactoryBean而言,这个Bean不是简单的Bean,而是一个能生产 或者修饰对象生成的工厂Bean,它的实现与设计模式中的工厂模式和修饰器模式类似。
BeanFactory解释:
BeanFactory定义了IOC容器的最基本形式,并提供了IOC容器应遵守的的最基本的接口。spring中有很多不同类型的BeanFactory,比如:ApplicationContext、ClassPathXmlApplicationContext, AnnotationConfigApplicationContext等等。这些类都实现了对应的接口。
FactoryBean的解释:
FactoryBean是Spring容器中的一个对象。专门用来创建特殊的对象。一般情况下spring都是通过反射来创建对象 的,但是如果某个对象的创建过程过于复杂或者无法按照传统的方式实例化,我们就可以使用FactoryBean。
看下面的例子:
//创建复杂 public class C { //复杂操作 }
@Component public class C_FactoryBean implements FactoryBean<C> { @Override public C getObject() throws Exception { return new C(); } @Override public Class<?> getObjectType() { return C.class; } @Override public boolean isSingleton() { return false; } }
public static void main(String[] args) { ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); C c = ac.getBean(C.class); System.out.println(c.getClass()); } /** 执行结果:class com.ioc.bean.C 由此可以看出,spring没有自动加载C,但是通过FactoryBean可以得到 */
2.【BeanPostProcessor和BeanFactoryPostProcessor区别】
BeanPostProcessor:
后置处理Bean,它是bean级别的,可以在SpringBean初始化之前和之后对应Bean或者程序 进行增强。
@Component public class A { public A(){ System.out.println("创建Bean-A"); } /** * 指定初始化方法 */ @PostConstruct public void init(){ System.out.println(("初始化-A")); } }
//自定义BeanPostProcessot
@Component public class MyBeanPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("a"))//只有beanName是"a"才增强 System.out.println("Bean初始化【前】增强"); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if(beanName.equals("a")) System.out.println("Bean初始化【后】增强"); return bean; } }
//测试
public class Demo1 {
public static void main(String[] args) { ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); Object o = ac.getBean("a"); System.out.println(o.getClass()); } }
//输出结果 创建Bean-A Bean初始化【前】增强 初始化-A Bean初始化【后】增强 class com.ioc.bean.A
BeanFactoryPostProcess:
主要用于增强工厂(即Spring创建Bean之前)的功能。可以在创建SpringBean之前修改这个Bean的信息。
//不用注解也可以创建 public class B { @PostConstruct public void init(){ System.out.println("初始化-B"); } }
@Component public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("---BeanFactoryPostProcessor---"); //修改,如果传入beanName="a",则创建B类 AbstractBeanDefinition beanDefinition = (AbstractBeanDefinition) beanFactory.getBeanDefinition("a"); System.out.println("如果传入“a”,进行修改,生成B"); beanDefinition.setBeanClass(B.class); System.out.println("---BeanFactoryPostProcessor---"); } }
public class Demo1 { public static void main(String[] args) { ApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class); //通过beanName构建Bean Object o = ac.getBean("a"); System.out.println(o.getClass()); } }
---BeanFactoryPostProcessor--- 如果传入“a”,进行修改,生成B ---BeanFactoryPostProcessor--- Bean初始化【前】增强 初始化-B Bean初始化【后】增强 class com.ioc.bean.B
3.【JavaBean 和 SpringBean区别】
java对象:使用new或者其他方式直接创建,由JVM统一管理。一个java对象就只有生成这个对象的类中申明的所有 属性和功能。
springBean:通过反射创建,由spring容器统一管理。拥有自己类中申明的属性和方法之外还有spring给其增加/修 改的属性和方法。
java对象的加载和创建流程:
springBean的加载和创建流程:spring创建一个对象, 并不是参考一个类的字节码文件,而是参考了一个交在BeanDefinition的对象。spring会为每一个类生成一个BeanDefinition对象, 在其中定义spring需要的属性。