1.IOC的类型
(1)构造方法注入------将对象作为构造函数的参数传入,注入时机为实例化时
(2)属性注入-----------通过属性的setter方法,将对象传入,注入时机为实例化后
(3)接口注入-----------接口注入和属性注入无本质区别,不提倡使用
(1)装载:查找和导入class文件
(2)链接:执行校验、准备和解析步骤(可选)
- 校验-->检查载入的class文件数据的正确性
- 准备-->给类的静态变量分配存储空间
- 解析-->将符号引用转成直接引用
(3)初始化:对类的静态变量、静态代码执行初始化工作
(4)JVM在运行时会产生3个ClassLoader
- 根装载器--------------不是ClassLoader的子类
- ExtClassLoader(扩展类装载器)------------ClassLoader的子类,负责装载jre扩展目录ext中的jar包
- AppClassLoader(系统类装载器)-----------ExtClassLoader的子类,负责装载classpath路径下的类包
(5)反射中,在访问非public的成员变量和方法时,要通过调用成员变量和方法的setAccessible(true)方法取消java语言访问检查
spring提供了强大的资源加载方式,可以不显示指定Resource实现类,仅通过资源地址的特殊标识就可以加载相应的资源
3.1资源地址表达式
- classpath: classpath:和classpath:/是等价的,都是相对于类的根路径
- file: 使用UrlResource装载,可采用绝对或相对路径
- http:// 使用UrlResource从web服务器中装载
- ftp:// 使用UrlResource从FTP服务器中装载
- 无前缀 根据ApplicationContext的具体实现类采用相应类型的Resource
(1)classpath:和classpath*:
假设有多个JAR包和文件系统类路径都有一个相同的包名
- classpath:只会在第一个加载的包下查找
- classpath*:会扫描所有JAR包下及类路径下出现的类路径
(2)Ant风格的资源地址支持3种匹配符
?:匹配文件名中的一个字符
* :匹配文件名中的任意个字符
**:匹配多层路径
4.BeanFactory和ApplicationContext
(1)BeanFactory是Spring框架的基础设施,面向Spring本身,一般称为IOC容器
ApplicationContext是应用的上下文,面向Spring框架开发者,一般称为Spring容器
(2)通过BeanFactory启动IoC容器时,并不会初始化配置文件中定义的Bean,初始化动作只发生在第一次调用时,对于单例模式的Bean来说,BeanFactory会缓存Bean实例,所以后续的获取bean将直接从IoC容器的缓存中获取
(3)ApplicationContext在初始化应用上下文时就实例化所有单实例的Bean,ApplicationContext的主要实现类:
ApplicationContext ctx=new ClassPathXmlApplicationContext("类路径");
ApplicationContext ctx=new
FileSystemXmlApplicationContext("文件路径");
(4)
WebApplicationContext和ServletContext
①上下文启动时,WebApplicationContext作为属性放置在ServletContext中,所以可以通过WebApplicationContextUtils.
getWebApplicationContext(ServletContext sc)可以取得WebApplicationContext
实例
②WebApplicationContext.getServletContext()又可以获取ServletContext,这样spring的web应用上下文就可以和web容器的上下文实现互相访问
③ConfigurableWebApplicationContext扩展了WebApplicationContext,实现了通过配置加载,和设置ServletContext引用的方法
④
WebApplicationContext的初始化不同于BeanFactory和ApplicationContxt,它需要ServletContext实例,所以只有在启动Web容器的前提下才能初始化WebApplicationContext,我们可以借助web.xml的自启动servlet或监听器实现,
spring提供了2种方式:
- servlet:org.springframework.web.context.ContextLoaderServlet
- 监听器:org.springframework.web.context.ContextLoaderListener
(5)父子容器
- 通过HierarchicalBeanFactory接口,spring的IoC容器可以建立父子层级关系,子容器可以访问父容器的Bean,但父容器不可以访问子容器的Bean。
- 每个容器内Bean的id必须唯一,但子容器可以拥有一个和父容器id相同的Bean。例如springMVC就是将展现层的Bean放在springMVC子容器中。
5.1、我们可以从2个层面定义Bean的生命周期:
- 第一个层面是Bean的作用域
- 第二个层面是 实例化Bean时所经历的一系列阶段
5.2、BeanFactory中Bean的生命周期
(1)通过InstantiationAwareBeanPostProcessor初始化上下文,设置属性值
(2)通过BeanNameAware设置beanName
(3)通过BeanFactoryAware设置beanFactory
(4)调用BeanPostProcessor(
是AOP和动态代理的入口)
(5)调用InitializingBean的afterPropertiesSet()方法
(6)单例模式的bean就放在spring缓存池中,prototype的bean就交给调用者
总结:
Bean的生命周期中所调用的方法大致分为3类:
①Bean自身的方法,如构造函数,设置属性的set方法,<bean/>节点中定义的init-method和destroy-method方法。
②Bean级接口方法,如BeanNameAware、BeanFactoryAware和InitializingBean的方法,这些方法由Bean直接实现。
③容器级接口方法,如InstantiationAwareBeanPostProcessor和BeanPostProcessor的方法,一般称为“后处理器”,后处理器不由Bean实现,它们独立于Bean,以配置的形式注册到spring容器,它们的影响是全局性的。
④Bean级接口和容器级接口是个性和共性的关系,前者解决个性化问题,后者解决共性问题。
⑤后处理器实现Ordered接口,就可以按顺序执行
注意:
①为了不和spring框架的耦合,推荐业务类全部POJO化,因此,可以通过指定<bean/>节点的init-method方法和destory-method方法,来替代实现InitializingBean接口和DisposableBean接口所达到的效果。
②也可以通过@PostConstruct(实例化前)和@PreDestory(销毁前)注解实现①中的效果。
(1)ApplicationContext和BeanFactory的最大不同之处在于:
ApplicationContext可以通过反射机制自动识别出容器后处理器,并将它们注册到应用上下文,而使用BeanFactory需要手工进行注册。
(2)ApplicationContext在启动时,将首先为配置文件中每个<bean/>生成一个BeanDefinition对象。BeanDefinition是<bean/>在Spring容器中的内部表示,当配置文件中所有的<bean/>都被解析成BeanDefinition时,ApplicationContext将调用工厂后处理器的方法,因此我们有机会通过程序的方式调整Bean的配置信息。