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