IOC容器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了IOC容器相关的知识,希望对你有一定的参考价值。

一、IOC概述

  1. 概念:控制反转(Inverse of Control)DI 依赖注入

    某一接口具体实现类的选择控制权从调用类中移除,转交给spring容器由Bean配置来进行控制。


  2. IOC的类型:构造函数注入、属性注入、接口注入。


  3. 通过容器完成依赖注入:通过new XmlBeanFactory("beans.xml")等方式启动容器,在容器启动时,spring根据配置文件的描述信息,自动实例化bean并完成依赖关系的装配,从容器中即可返回Bean实例。



二、相关的Java基础知识

  1. 类装载器:Class文件由类加载器装载后,在JVM中将形成一份描述Class结构的元信息对象,通过该元信息对象可以获取Class的结构信息。用户借助这个元信息对象间接调用Class对象的功能。


  2. 类装载器的工作机制和方法

    根装载器使用C++编写,在java中看不到,它负责装载JRE的核心类库。根装载器->ExtClassLoader->AppClassLoader。JVM使用全盘负责委托机制。先委托父装载器,没法再有子。


三、资源访问器

  1.spring设计了一个Resource接口,exitst()资源是否存在、isOpen()资源是否打开、getURL()、getFile()、getInputStream()返回资源对应的输入流。

  如果有一个文件位于Web应用的类路径下,用户可以通过以下方式访问:

  1)通过FileSystemResource以文件系统绝对路径的方式进行访问。

  2)通过ClassPathResource以类路径的方式进行访问。

  3)通过ServletContextResource以相对于web应用根目录的方式进行访问。


   在获取资源后,用户可以通过Resource接口定义的方法访问文件的数据和信息。getFileName()获取文件名、getFile()获取File对象、getInputStream()获取文件的输入流。

   而WritableResource接口,通过getOutputStream()方法直接获取文件的输入流。

public class FileSourceExample {
   
   public static void main(String[] args) {
      try {

         String filePath = "D:/cnslp/hello.txt";
         //使用系统文件路径方式加载文件
         WritableResource res1 = new PathResource(filePath);
         //使用类路径方式加载文件
         Resource res2 = new ClassPathResource("conf/file1.txt");

         //使用WritableResource接口写资源文件
         OutputStream stream1 = res1.getOutputStream();
         stream1.write("欢迎光临\ncnslp论坛".getBytes());
         stream1.close();
         
         //使用Resource接口读取资源文件
            InputStream ins1 = res1.getInputStream();
         InputStream ins2 = res2.getInputStream();

         ByteArrayOutputStream baos = new ByteArrayOutputStream();
         int i;
         while((i=ins1.read())!=-1){
            baos.write(i);
         }
         System.out.println(baos.toString());

            System.out.println("res1:"+res1.getFilename());
            System.out.println("res2:"+res2.getFilename());            
      } catch (IOException e) {
         e.printStackTrace();
      }
   }
}

   2.通过EncodeResource对资源进行编码,以保证内容的正确性。

Resource res = new ClassPathResource("conf/file1.txt");
EncodedResource encRes = new EncodedResource(res,"UTF-8");//使用UTF-8编码
String content  = FileCopyUtils.copyToString(encRes.getReader());
System.out.println(content);

   3.资源加载

    通过资源地址的特殊标识来访问相对应的资源

    1)classpath:从类路径中加载资源,classpath:和classpath:/是等价的;

    2)file: 使用url从文件系统目录中装载资源;

    3)http:// 使用UrlResource从web服务器中装载资源;

    4)ftp://  使用UrlResource从FTP服务器中装载资源;
注意:classpath*:会扫描所有jar包及类路径;

Ant风格:?匹配文件名的一个字符

     *匹配文件名中任意字符

     **匹配多层路径

ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
Resource resource = resolver.getResource("classpath:conf/file1.txt");
System.out.println(resource.getFilename());
System.out.println(resource.getDescription());

注意:使用Resource操作文件,如果项目发布打包,则不能使用Resource的getFile()方法,应该使用getInputStream()来读取。


四、BeanFactory和ApplicationContext

  应用上下文建立在BeanFactory基础上,一般称BeanFactory为IOC容器、ApplicationContext为应用上下文或者spring容器。

  1.BeanFactory类的通用工厂,不过开发一般直接使用ApplicationContext

  2.ApplicationContext

  1)ApplicationContext类的体系结构

  ApplicationContext的主要实现类是ClassPathXmlApplicationContext(默认从类路径加载配置文件)和FileSystemXmlApplicationContext(默认从文件系统中装载配置文件)

注:BeanFactory在初始化容器时,并未实例化bean,直到第一次使用才实例化,而ApplicationContext则在初始化上下文的时候就实例化bean。

@Configuration//表示是一个配置信息提供类
public class Beans {

   @Bean(name = "car")//定义一个Bean
   public Car buildCar() {
      Car car = new Car();
      car.setBrand("红旗CA72");
      car.setMaxSpeed(200);
      return car;
   }
}
public static void main(String[] args) {
   //通过一个带@Configuration的POJO装载Bean配置
   ApplicationContext ctx = new AnnotationConfigApplicationContext(Beans.class);
   Car car =ctx.getBean("car",Car.class);
}


  2)WebApplicationContext类的体系结构

  WebApplicationContext专门为web应用准备的,它允许从相对应Web根目录路径中装配配置文件完成初始化。WebApplicationContext初始化需要ServletContext实例,必须在web容器的前提下才能完成启动工作,在web.xml中配置自启动的Servlet或定义Web容器监听器可以完成启动spring web应用上下网的工作。

  由于WebApplicationContext需要使用日志功能,所以用户把log4j的配置文件放在WEB-INF/classes下,这时log4j引擎即可顺利启动。如果log4j配置文件放在其他位置,需要在web.xml中指定器位置。

<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>/WEB-INF/classes/log4j.properties</param-value>
</context-param>

<servlet>
    <servlet-name>log4jServlet</servlet-name>
    <servlet-class>org.springframework.web.util.Log4jConfigServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>

<servlet>
    <servlet-name>springServlet</servlet-name>
    <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>


本文出自 “赤霄” 博客,请务必保留此出处http://cnslp.blog.51cto.com/11387491/1932419

以上是关于IOC容器的主要内容,如果未能解决你的问题,请参考以下文章

Spring IoC容器

IoC 之 2.2 IoC 容器基本原理(00000001)

Spring IOC源代码具体解释之容器初始化

深入理解Spring的IOC容器

Spring系列之IOC容器

IOC容器基本原理