Ioc的理解:调用类对某一接口的实现类的依赖关系又第三方注入,以移除调用类对接口实现类的依赖。又叫做依赖注入。调用者对接口的选择权利被剥夺,交给了第三方。举个例子,学生本来可以选择哪个老师给他上课的,但是这个权利被学校剥夺了,由学校分配学生的老师是谁。
Ioc的类型:
构造函数:将依赖的对象通过构造函数注入。第三方将需要的对象准备好,在创建对象时通过构造函数传参注入所需对象
属性:声明依赖的对象,并提供setter/getter方法。第三方通过set方法注入。
接口:将依赖的对象抽象到接口中,通过实现这个接口方法完成注入。第三方创建需要注入的对象后,通过调用接口方法实现注入。
容器完成注入工作:以上的实现都是由第三方创建所需的注入对象,我们想要把 new 的工作也去掉。
Ioc原理:spring的实现是通过配置文件注入,原理是java的反射机制,根据类的全限定名找到文件并通过类加载加载并实例化。
资源访问:加载配置文件
BeanFactory和ApplicationContext:
BeanFactory面向spring容器底层,ApplicationContext面向开发人员
BeanFactory:类工厂,创建并管理各种类的对象并交由Spring容器管理。BeanFactory位于顶端,下面提供了不同功能的实现。资源访问的相关类加载配置文件,然后将资源文件给BeanFactory装载,BeanFactory负责创建配置文件中指定的对象(创建的时机是第一调用的时候),并提供方法getBean得到对象。注意BeanFactory的初始化需要Log4j日志配置文件与jar包。
ApplicationContext:由BeanFactory派生而来,实现了更多实际可用的功能。主要实现类是ClassPathXmlApplicationContext和FileSystemApplicationContext,分别从类路径和文件系统中加载配置文件。初始化ClassPathXmlApplicationContext时直接给定配置文件的路径(可以是多个配置文件,Spring将自动融合),然后就可以调用getBean获取实例了。注意ApplicationContext的初始化和BeanFactory有重大区别就是BeanFactory初始化时不会创建配置文件中的对象,知道第一次调用时才创建,但是ApplicationContext初始化 时就会创建配置文件中配置的对象。
类注解的配置方式:@Configuration,在该注解的类中,提供实例化对象的方法并以@Bean(name="xxx")。使用ApplicationContext的实现类AnnotationApplicationContext并传入@Configuration注解的类,然后就可以调用getBean获取实例了。
WebApplicationContext:从web根目录路径装载配置文件,WebApplicationContext可以获得ServletContext的引用,整个web应用上下文对象作为属性传入ServletContext中,为此Spring提供了一个WebApplicationContextUtils,通过该类的getWebApplicationContext(ServletContext sc),可以从ServletContext对象中获取WebApplicationContext。
Bean的作用域:在非Web环境中,只有singleton和prototype。WebApplicationContext为Bean添加了三个作用域:request,session,global session。
WebApplicationContext和ServletContext的融合:WebApplicationContext实现了ApplicationContext,并定义了一个常量ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE,容器启动时,WebApplicationContext以它为键存放了ServletContext的属性列表,因此可以在web容器(Tomcat)中通过以下方式获取 WebApplicationContext:
WebApplicationContext wpc = ( WebApplicationContext ) ServletContext.getAttribute ( WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE );
WebApplicationContext的初始化:必须在拥有web容器的前提下才能初始化WebApplicationContext,因为它的启动需要ServletContext,我们可以在web.xml中配置自启动的Servlet或者ServletContextListener,借助其中任何一个都可以启动WebApplicationContext。Spring对这两种方式都有相应的实现,分别是:org.springframework.web.context.ContextLoaderListener,org.springframework.web.context.ContextLoaderServlet。我们只需在web.xml中配置即可。同样的需要注意,WebApplicationContext的启动也需要Log4j配置信息。
父子容器:通过HierarchicalBeanFactory接口,springIoc容器可以创建父子层级关联的容器体系,子容器可以访问符容器的Bean,在容器中,Bean的id必须唯一,但是子容器可以设置和父容器id相同的Bean。这提高了Spring的扩展性,第三方可以通过编程向已经存在的父容器中添加功能。比如SpringMVC,视图层Bean位于子容器中,这样视图层就可以引用业务层和持久层的Bean,但是业务层和持久层的Bean不可见视图层的Bean。
Bean的生命周期:由多个特定的生命阶段组成,每个阶段都有一个接口,允许外界对Bean加以控制。我们可以从两个层面定义Bean的生命周期,一是Bean的作用范围,二是Bean经历的一系列阶段。
BeanFactory中Bean的生命周期:
ApplicationContext中Bean的生命周期: