Ioc容器
IoC(Inverse of Control,反转控制):将某一接口的选择控制权从调用类中移除。 由于IoC不够开门见山,最后提出DI(Dependency Injection,依赖注入)来替代IoC. 因此:IoC和DI要表达的是一件事。 IoC/DI的类型: Spring支持:构造函数注入和属性注入。 构造函数注入: 通过调用类的构造函数将依赖传入.(对象创建时就注入) 属性注入: 如果希望构造类的时候不注入,使用的时候才注入。可以通过set方法将依赖注入到属性中。 Spring通过容器完成依赖注入: 例如bean之间的依赖关系使用XML文件来描述。 那么当使用new XmlBeanFactory("bean.xml")启动容器后,容器就可以根据配置的xml,实例化Bean并完成依赖关系的装配。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 容器: Spring通过一个配置文件描述Bean之间的依赖关系,并利用Java的反射技术实例化Bean并且建立Bean之间的依赖关系。除此之外还做了一些别的高级功能。 Bean工厂是Spring的核心,它提供了IOc的核心。应用上下文在Bean工厂的基础之上提供了更过面向应用的功能。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1:BeanFactory介绍: 普通的工厂类是只能创建一种类的实例,但是BeanFactory是一个通用的类工厂,可以创建多种类型的对象。 Spring中的Bean比JavaBean宽泛,只要是Spring容器管理的类都是Bean。 1.1: Spring为BeanFactory提供了很多实现类。 beanFactory中只有一个方法:getBean(String beanName)该方法从容器中返回特定名名称的Bean,BeanFacroty的功能通过其他接口得到了不断的扩展。最常用的XmlBeanFactory在Spring3.2中被废弃,之后建议使用:XmlBeanDefinitionReader、DefaultListableBeanFactory替代下面是一些接口。 ListableBeanFactory:该接口定义了访问容器中bean基本信息的方法。例如:查询容器中bean的个数、获取bean的配置名称、查看容器中是否含有某一类型的Bean。 HierarchicalBeanFactroy:父子级联IoC容器的接口。 ConfigurableBeanFactory:是一个重要的接口,增强了IoC容器的可定制性。它提供了设置“类装载器、属性编辑器、容器初始化的后置处理器”等方法。 AotowireCapableBeanFactory:定义了将容器的bean按照某种规则(如:按照名字匹配、类型匹配等)进行自动装配的方法。 SingletonBeanRegistry:定义了允许在允许期向容器注册单例Bean的方法。 1.2:初始化Bean Factory 配置文件: <bean id = "car1" class = "com.smart.Car"> p:brand = "红旗" p:color = "黑色" p:maxSpeed="200" </bean> 通过XmlBeanDefinitionReader、DefaultListableBeanFactory实现类启动SpringIoC容器。 public void getBean(){ ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource res = resolver.getResource("classpath:com/beans.xml"); // 被废弃,不建议使用 BeanFactory fg = new XmlBeanFactory(res); // 建议使用 DefaultListableBeanFactory factory = new DefaultListableBeanFactory(); XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(factory); reader.loadBeanDefinitions(res); Car car = factory.getBean("Car" ,Car.class); car.introduce(); } (初始Beanfactory的时候需要提供一种日志框架。) >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> 1.3:ApplicationContext介绍 ApplicationContext是由Beanfactory派生而来的。提供了更加丰富的功能。 ApplicationConetct的主要实现类是:ClassPathXmlApplicationContext(默认从类路径加载配置文件)和FileSystemXmlApplicationContext(默认从文件系统加载配置文件)。 ApplicationContext类继承了HierarchicalBeanFactory和ListableBeanfactory接口,在此基础上通过其他接口扩展了beanfactory。这些接口如下: ApplicationeventPublisher:让容器拥有发布应用上下文事件的功能。实现了ApplicationListener事件监听接口的Bean可以接受到容器事件,并对事件进行相应处理。 MessageSource:为应用提供i18n国际化消息访问功能。 LiftCycle:该接口提供了start()和stop()两个方法,主要控制异步处理的过程。该接口会同同时被ApplicationContext和具体的Bean实现。ApplicationCoutext会将start/stop的信息传递给所有实现了该接口的Bean。 初始化ApplicationContext: 如果配置文件在类路径下,优先使用ClasspathXmlApplicationContext。如果配置文件放在文件系统路径下,优先使用FileSystemXmlApplicationContext。 // classpath:com/beans.xml ApplicationContext ctx = new ClassPathXmlApplicationContext("com/beans.xml"); // file:com/beans.xml ApplicationContext xtx = new FileSystemXmlApplicationContext("com/bean.xml"); 获取到ApplicationContext的实例后,就可以使用getBean()方法了,但是AppplicationCountext和Beanfactory有个重大的区别:beanfactory初始化容器时并没有实例化Bean,直到第一次访问某个Bean时才实例化目标Bean。而ApplicationContext在初始化上下文时就实例化了单例的Bean。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> Spring支持基于注解的配置方式,主要来源于一个叫做JavaConfig的子项目。现在JavaConfig已经升级为Spring核心框架的一部分。使用Configuration注释OPJO类就是一个配置类。 通过javaConfig配置可以很灵活的配置初始化Bean的过程。 AnnotationConfigApplicationContext类用于基于注解配置的bean。 AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(Beans.class); Car car = ctx.getBean("car" , Car.class); >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> WebApplicationcontext:专门为web应用准备的上下文。从相对与web根目录的路径中装载配置文件。整个Web应用上下文对象将作为属性放在ServletContext中,以便Web应用环境可以访问Spring应用上下文。Spring提供的工具类WebApplicationContextUtils.getWebApplicationContext()可以从ServletContext中获取到WebApplicationContext。 非web中,Bean有两种作用域:singleton和prototype。WebApplicationContext为Bean添加了三个新的作用于:request、session、global session。 ConfigurableWebApplicationContext扩展了WebApplicationContext,它允许通过配置的方式实例化WebApplicationContext,同时提供了两个重要的方法: setServlctContext(ServletContext servletContext):为Spring配置web上下文。 setConfigLocations(String configLocations):设置web配置文件地址,一般相对与web根目录。 如:/WEB-INF/xxx.xml (默认相对于Web根目录) 可以指定资源前缀,例如(classpath:com/xxx.xml) WebApplicationContext的初始化:WebApplicationContexst的初始化和Beanfactory、ApplicationContext的初始化有所区别。因为WebApplicationContext初始化需要ServletContext实例。也就是说先需要有web容器。可以通过在web.xml配置自启动的Servlet或者监听器来启动WebApplicationContext。 Spring分别提供了用于启动WebApplicationContext的Servlet和Web容器监听器: org.springframework.web.context.ContextLoaderServlet。 org.springframework.web.context.ContextLoaderListener。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ContextLoaderListener 使用ContextLoaderListener:(只有Servlet2.3及其以上的Web容器版本才支持Web容器监听器) <!--指定配置文件--> <context-param> <param-name>contextConfigLocation</param-name> <param-value> /WEB-INF/xxx.xml,/WEB-INF/yyy.xml </param-value> </context-param> <!--声明Web容器监听器--> <listener> <lintener-class> org.springframework.web.context.ContextLoaderListener </lintener-class> </listener> 注:ContextLoaderListener通过contextConfigLoaction参数获取配置文件。这个参数中的配置文件位置不指定前缀时表示相对与web根目录。也可以指定前缀例如。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>ContextLoaderServlet 使用ContextLoaderServlet:(所有的web容器都支持自启动的Web servlet) <context-param> <param-name> contextConfigLocation </param-name> <param-value> /WEB-INF/xxx.xml,/WEB-INF/yyy.xml </param-value> </context-param> <!--声明自启动的Servlet--> <servlet> <servlet-name> springContextLoaderServlet </servlet-name> <servlet-class> org.springframework.web.context.ContextLoaderServlet </servlet-class> <!--启动顺序--> <load-on-startup>1</load-on-startup> </servlet> 由于WebApplicationContext需要使用日志功能,Spring会到WEB-INF/classes下读取日志配置文件。如果日志配置文件放在了别的地方,需要再web.xml中指定配置文件的位置。 注:如果使用javaConfig配置依赖。则需要另外一套配置方法。上面的是配置xml。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>父子容器: 通过HierarchicalBeanFactory接口,Spring的IOc容器可以建立一个具有父子层级的容器体系。子容器可以访问父容器中的bean,但父容器中的bean无法访问子容器中的bean。子容器中可以拥有一个和父容器相同的bean Id。通过这种方式可以再现有的容器体系上扩展额外的功能。 >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>Bean生命周期
生命周期图如下,具体参考书。