不废话了,Spring 有多重要。首先是跑个 Hello World。
Spring 最基本功能是 IOC,如果不懂或者好奇原理的可以参考《极简版 Java 依赖注射》。
Hello World
怎么获取 Spring?官方推荐 Maven 依赖管理(据说 Ant 也可以),也可以下载 Java 源码构建。但本人比较追求好快多省,不喜欢加一坨坨多余的东西,就想直接下 jar 包。于是找到 http://repo.spring.io/release/org/springframework/。
不知道下载哪些必要的包?没关系,先把 Hello World 代码贴进去,有报错的咱就去下载。
Hello World 程序一个三个文件,分别如下。
// hello/MessageService.java package hello; public interface MessageService { String getMessage(); }
// hello/MessagePrinter.java package hello; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; @Component public class MessagePrinter { final private MessageService service; @Autowired public MessagePrinter(MessageService service) { this.service = service; } public void printMessage() { System.out.println(this.service.getMessage()); } }
// hello/Application.java package hello; import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.*; @Configuration @ComponentScan public class Application { @Bean MessageService mockMessageService() { return new MessageService() { public String getMessage() { return "Hello World!"; } }; } public static void main(String[] args) { ApplicationContext context = new AnnotationConfigApplicationContext(Application.class); MessagePrinter printer = context.getBean(MessagePrinter.class); printer.printMessage(); } }缺的 jar 包大概如下(如果有新版本就下新版本),
基本上官方下载都齐了,另外依赖 Apache 日志接口,下载 http://commons.apache.org/proper/commons-logging/download_logging.cgi。
这些就是运行 Spring Hello World 最基本的包了。Alt+Shift+X 运行下 Java 程序,成功运行结果如下。
虽然成功运行了,但 IDE 提示“Resource leak: 'context' is never closed”,怎么办?有人说用 Java 1.7 的 try 自动回收资源可以,但我试过不成功,于是改这个 ((ConfigurableApplicationContext) context).close(); 就 ok 了。
Spring MVC
MVC 需要 spring-web-4.2.4.RELEASE.jar、spring-webmvc-4.2.4.RELEASE.jar 包,还需要 AOP 的框架 aspectjweaver-1.6.10.jar 和 aopalliance-1.0.jar。
Spring MVC 仍旧与传统 Servlet MVC 那样配置 web.xml。当然新版 4.0 是可以作为 XML 零配置的,在 Java 里面使用注解就可以完成 XML 配置了(Servlet 3.0 开始都支持了)。
第一步,配置 web.xml 如下。
<?xml version="1.0" encoding="UTF-8"?> <web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> <display-name>MyServlet</display-name> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> <init-param> <param-name>forceEncoding</param-name> <param-value>true</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <servlet> <servlet-name>springMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <load-on-startup>1</load-on-startup> </servlet> <servlet-mapping> <servlet-name>springMVC</servlet-name> <url-pattern>/greeting</url-pattern> </servlet-mapping> </web-app>DispatcherServlet 继承自 HttpServlet 的,由它来分各种请求。每一个请求最先访问的都是 DispatcherServlet,DispatcherServlet 负责转发每一个 Request 请求给相应的Handler,Handler 处理以后再返回相应的视图(View)和模型(Model)。
该例子中我们指定了 /greeting 分发,对应执行哪个控制器呢?初始化 DispatcherServlet时会在 WEB-INF 目录中寻找一个名为 [servlet-名称]-servlet.xml 的文件,在那里执行对应的控制器。并且可以在那里定义相关的 Beans,重写在全局中定义的任何 Beans。
这个例子中是 springMVC-servlet.xml。
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <bean name="/greeting" class="hello.web.GreetingController" /> <!-- ViewResolver --> <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix" value="/WEB-INF/"/> <property name="suffix" value=".jsp"/> </bean> </beans>GreetingController 源码如下:
package hello.web; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; public class GreetingController { @RequestMapping("/greeting") public String greeting(@RequestParam(value="name", required=false, defaultValue="World") String name, Model model) { model.addAttribute("name", name); return "greeting"; } }
控制器 greeting 返回的字符串就是对应的模板文件,这一般是 jsp WEB-INF/spring-servlet.xml 配置文件中有 ViewResolver 视图控制器,所有不用我们指定模板所在目录和后缀名。
@RequestMapping 注解是 url 路径映射,可以多个。
整合 Spring
至今为止没有让 Spring IOC 和 Spring MVC 发生任何联系(貌似 MVC 可以脱离 Spring 本身独立使用,——这听上去有点不可思议)。事实上,MVC 基本可以不需要 Spring 其他繁杂的包,仅仅依赖下面这些包就可以工作了。
怎么让 Web 服务都受到 Spring IOC 容器管制呢?
在使用 Spring 容器的 web 应用中,业务对象间的依赖关系都可以用 context.xml 文件来配置,并且由 Spring 容器来负责依赖对象的创建。如果要在 servlet 中使用 Spring 容器管理业务对象,通常需要使用 WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext()) 来获得 WebApplicationContext,然后调用 WebApplicationContext.getBean("beanName") 来获得对象的引用,这实际上是使用了依赖查找来获得对象,并且在 servlet 代码中硬编码了应用对象的 bean 名字。为了能在 servlet 中感知 Spring 中 bean,可采用如下步骤来实现:
http://www.open-open.com/lib/view/open1417248512252.html
官方文档:http://docs.spring.io/spring/docs/current/spring-framework-reference/html/mvc.html
Spring MVC 用法笔记
为什么 Pojo 的 boolean 获取不到值?
如果你的字段名是 isOnline 以 is 开头的,要把 is 去掉,例如
<div class="row"> 是否上线:<label> 上线 <input type="radio" name="online" value="1" ${info.online ? 'checked' : ''} /> </label> <label> 下线 <input type="radio" name="online" value="0" ${info.online ? 'checked' : ''} /> </label> </div>
value 用 1 或者 true 皆可。