IOC容器
一、IOC概述
概念:控制反轉(Inverse of Control)DI 依賴註入
某一接口具體實現類的選擇控制權從調用類中移除,轉交給spring容器由Bean配置來進行控制。
IOC的類型:構造函數註入、屬性註入、接口註入。
通過容器完成依賴註入:通過new XmlBeanFactory("beans.xml")等方式啟動容器,在容器啟動時,spring根據配置文件的描述信息,自動實例化bean並完成依賴關系的裝配,從容器中即可返回Bean實例。
二、相關的Java基礎知識
類裝載器:Class文件由類加載器裝載後,在JVM中將形成一份描述Class結構的元信息對象,通過該元信息對象可以獲取Class的結構信息。用戶借助這個元信息對象間接調用Class對象的功能。
類裝載器的工作機制和方法
根裝載器使用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) { [email protected] 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容器