JVM是Java程序惟一認識的操做系統,可執行.class文件。WEB容器是Servlet/JSP惟一認得的HTTP服務器。
容器說白了就是一個用java寫的程序,運行與JVM之上。
HTTP那些文字性的通訊協議,如何變成Servlet/JSP中可用的Java對象,其實就是容器的剖析與轉換。
只要寫的Servlet/JSP符合WEB容器的標準規範,Servlet/JSP就能夠在各類不一樣廠商實現的WEB容器上運行,而不用理會底層真正的HTTP服務器是什麼。java
依賴注入(Dependency Injection)是用於實現控制反轉(Inversion of Control)的最多見的方式之一。數據庫
控制反轉用於解耦服務器
控制反轉用於解耦,解的到底是誰和誰的耦?這是我在最初瞭解依賴注入時候產生的第一個問題。函數
下面我引用Martin Flower在解釋介紹注入時使用的一部分代碼來講明這個問題。編碼
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
public class MovieLister { private MovieFinder finder; public MovieLister() { finder = new MovieFinderImpl(); } public Movie[] moviesDirectedBy(String arg) { List allMovies = finder.findAll(); for (Iterator it = allMovies.iterator(); it.hasNext();) { Movie movie = (Movie) it.next(); if (!movie.getDirector().equals(arg)) it.remove(); } return (Movie[]) allMovies.toArray(new Movie[allMovies.size()]); } ... } |
1
2 3 |
public interface MovieFinder { List findAll(); } |
咱們建立了一個名爲MovieLister的類來提供須要的電影列表,它moviesDirectedBy方法提供根據導演名來搜索電影的方式。真正負責搜索電影的是實現了MovieFinder接口的MovieFinderImpl,咱們的MovieLister類在構造函數中建立了一個MovieFinderImpl的對象。spa
目前看來,一切都不錯。可是,當咱們但願修改finder,將finder替換爲一種新的實現時(好比爲MovieFinder增長一個參數代表Movie數據的來源是哪一個數據庫),咱們不只須要修改MovieFinderImpl類,還須要修改咱們MovieLister中建立MovieFinderImpl的代碼。操作系統
這就是依賴注入要處理的耦合。這種在MovieLister中建立MovieFinderImpl的方式,使得MovieLister不單單依賴於MovieFinder這個接口,它還依賴於MovieListImpl這個實現。 這種在一個類中直接建立另外一個類的對象的代碼,和硬編碼(hard-coded strings)以及硬編碼的數字(magic numbers)同樣,是一種致使耦合的壞味道,咱們能夠把這種壞味道稱爲硬初始化(hard init).net