Spring IoC
一、IoC是Spring容器的内核,AOP、声明式事务等功能以此为基础。
二、IoC的字面意思为控制反转(依赖注入),即某一接口的选择控制权从调用类中移除,转给第三方决定。举例:比如有一个剧本的某一个角色要用刘德华来出演,现在将角色从剧本中分离出来(反转),由导演来控制(控制)。
三、IoC有三种注入方式:构造函数注入(所有的都注入)、属性注入(可选注入)与接口注入,spring支持前两种。
通过容器完成依赖关系的注入:即Spring容器通过配置文件或注解描述类与类之间的依赖关系,并完成类的初始化与依赖注入。
其原理是java语言的反射机制:Class文件由类装载器(ClassLoder)装载后,在JVM中形成一份描述Class结构的元信息对象,可以通过元信息对象得到类的结构信息,通过此信息对象来完成对类的操作。
类装载器把一个类装入JVM中,需要如下步骤:
1.装载:查找与导入Class文件
2.链接:执行校验(检查Class文件正确)、准备(类的静态变量分配空间)和解析步骤
3.初始化:静态变量与静态代码块执行初始化工作
JVM在运行时产生3个ClassLoader:根装载器(C++)、扩展类装载器与应用装载器。
四、Spring设计了一个Resource接口,支持Ant风格带通配符的资源地址。通过此接口实现了和具体资源的解耦,无论存于何种介质,都可以通过相同的实例返回。
五、BeanFactory和ApplicationContext
Spring IoC容器在完成实例化Bean与建立Bean之间的依赖关系这些底层工作的基础上,还提供了Bean实例缓存、生命周期管理、Bean实例代理、时间发布等高级服务。
Bean工厂是Spring框架最核心的接口,使管理不同类型的Java对象成为可能;应用上下文建立在BeanFactoty基础之上,提供了面向应用的功能,面向Spring本身。一般称BeanFactory为IoC容器,ApplicationContext为应用上下文(Spring容器),面向开发者,绝大多数场合都是直接使用ApplicationContext而不是BeanFactory。
1.BeanFactory
(1)使用XmlBeanDefinitionReader、DefaultListableBeanFactory实现BeanFactory;
(2)Spring通过BeanFactory来实例化、配置和管理对象,但是其只是一个接口,有一个getBean方法,我们一般不采用BeanFactory而是用ApplicationContext这个类会自动扫描xml,然后通过配置的bean来new对象,将new的对象放进一个map中,键为bean的id,值为对象。
2.ApplicationContext
(1)使用ClassPathXmlApplicationContext和FileSystemXmlApplicationContext来实现ApplicationContext;WebApplicationContext是专门为web准备的。
(2)Spring支持基于类注解的方式,源于名为JavaConfig的子项目@Configuration
(3)WebApplicationContext需要ServletContext与日志功能(Log4J)
注:非web环境下,Bean只有singlon和prototype两种作用域;WebApplicationContext为Bean添加了3个:request、session和globe session.
在web.xml中配置自启动的Servlet或定义Web容器的监听器,二者之一就可以实现Spring Web应用上下文的工作。
六、Bean的生命周期
BeanFactory中的Bean
1.当调用者通过getBean()请求,如果容器注册了InstantiationAwareBeanPostProcessor接口,则在实例化前,调用PostProcessBeforeInstantiation()方法
2.根据配置实例化Bean
3.如果容器注册了InstantiationAwareBeanPostProcessor接口,则在实例化后,调用PostProcessAfterInstantiation()方法
4.配置属性信息
5.如果Bean实现了BeanNameAware接口,则调用setBeanName()方法,将配置文件中Bean的名称设置到Bean中
6.如果Bean实现了BeanFactoryAware接口,则调用setBeanFactory()方法,将BeanFactory容器实例设置到Bean中
7.如果BeanFactory装配了BeanPostProcessor后处理器,postProcessBeforeInitialization()被调用(切入点有关)
8.如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()
9.如果<Bean>中通过init-method属性定义了初始化方法,则将执行这个方法
10.BeanPostProcessor后处理器有两个方法,一个在(7)使用,另一个为postProcessAfterInitialization(),在此调用
11.如果Bean的作用范围为scope = "prototype“,则将Bean返回给调用者,调用者负责Bean后续生命的管理,Spring不管了;如果为scope = "singleton“,则将Bean放入IoC容器的缓存池中,并将Bean引用返回给调用者,Spring继续管理Bean的生命。
12.如果Bean实现了DisposableBean接口,则调用destory()方法,在此释放资源、记录日志等
13.对于scope = "singleton“(默认),如果<bean>的destroy-method指定了销毁方法,将执行这个方法
ApplicationContex的Bean
ApplicationContext来生成并管理Bean的话则稍有不同,使用ApplicationContext来生成及管理Bean实例的话,在执行BeanFactoryAware的setBeanFactory()阶段后,若Bean类上有实现org.springframework.context.ApplicationContextAware接口,则执行其setApplicationContext()方法,接着才执行BeanPostProcessors的ProcessBeforeInitialization()及之后的流程。