依赖注入方式
- 1.0开始,setter、构造器注入
- 2.5开始,Autowired注解的基于field方式注入
创建对象并配置如何注入
XML配置
- 可从类加载路径中加载配置文件(ClassPathXmlApplicationContext),或从文件系统中加载配置文件(FileSystemXmlApplicationContext)。
通过构造器创建bean实例
- 首先编写好Product类的Java代码
- xml配置bean:
<bean name="product" class="app01a.bean.Product"/>
- 如果是调用带参数的构造器,可以用constructor-arg参数(这里的参数不仅可以是java基本数据类型,还可以是所依赖的其他对象,如simpleAddress):
<bean name="featuredProduct" class="app01a.bean.Product">
<constructor-arg name="name" value="Ultimate Olive Oil"/>
<constructor-arg name="description" value="The purest olive oil on the market"/>
<constructor-arg name="price" value="9.95"/>
</bean>
/********************/
<bean name="simpleAddress" class="app01a.bean.Address">
<constructor-arg name="line1" value="151 Corner Street"/>
<constructor-arg name="line2" value=""/>
<constructor-arg name="city" value="Albany"/>
<constructor-arg name="state" value="NY"/>
<constructor-arg name="zipCode" value="99999"/>
<constructor-arg name="country" value="US"/>
</bean>
<bean name="employee2" class="app01a.bean.Employee">
<constructor-arg name="firstName" value="Senior"/>
<constructor-arg name="lastName" value="Moore"/>
<constructor-arg name="homeAddress" ref="simpleAddress"/>
</bean>
- ApplicationContext加载xml文件:
ApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"spring-config.xml"});
- 调用context的getBean获取product对象:
Product product1 = context.getBean("product", Product.class);
通过工厂方法创建bean实例
- 将上述1中xml配置改为
<bean name="product" class="app01a.bean.Product" factory-method="getInstance"/>
- 说明:可能还需要Product类本身支持工厂模式,具体情况稍后探究
Setter方式注入
- 首先要Product类的java代码中有setXXX的形式
- 用property属性来完成注入:
<bean name="simpleAddress" class="app01a.bean.Address">
<constructor-arg name="line1" value="151 Corner Street"/>
<constructor-arg name="line2" value=""/>
<constructor-arg name="city" value="Albany"/>
<constructor-arg name="state" value="NY"/>
<constructor-arg name="zipCode" value="99999"/>
<constructor-arg name="country" value="US"/>
</bean>
<bean name="employee1" class="app01a.bean.Employee">
<property name="homeAddress" ref="simpleAddress"/>
<property name="firstName" value="Junior"/>
<property name="lastName" value="Moore"/>
</bean>
Spring的第一个重要的类:DispatcherServlet
- DispatcherServlet将使用Spring MVC诸多默认的组件,初始时会在WEB-INF目录下寻找配置文件servletName-servlet.xml。
- 也可以设置init-param指定其他位置的配置文件
- /WEB-INF/web.xml:
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name> //注意这里的值不能变
<param-value>/WEB-INF/config/springmvc-config.xml</param-value> //注意这里的Path值应为配置文件在应用中的相对路径
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.action</url-pattern>
</servlet-mapping>
- /WEB-INF/config/springmvc-config.xml
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/jsp/"/>
<property name="suffix" value=".jsp"/>
</bean>
<bean name="/product_input.action" class="app03b.controller.InputProductController"/>
<bean name="/product_save.action" class="app03b.controller.SaveProductController"/>
Autowired注解
@Controller
- 用在类上
- 指示这个类的实例是一个控制器
- 有点:一个控制器类可以包含多个请求处理方法(通过@RequestMapping注解实现),而如果是配置的方法,则只能一个类实现Controller接口,然后实现一个处理方法handleRequest。
- 生效要求:首先在配置文件 springmvc-config.xml中声明xmlns:context和component-scan元素指定要扫描的包
<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="app04a.controller"/>
<mvc:annotation-driven/>
<mvc:resources mapping="/css/**" location="/css/"/>
<mvc:resources mapping="/*.html" location="/"/>
</beans>
- 解释:<mvc:annotation-driven/>的作用是注册用于支持基于注解的控制器的请求处理方法的bean对象,和可以使用<mvc:resources/>元素
- <mvc:resources/>元素指示Spring MVC哪些静态资源需要单独处理(不通过DispatcherServlet,即:阻止任意控制器被调用
- 若不需要使用<mvc:resources/>,则不需要<mvc:annotation-driven/>元素
@RequestMapping
- 用于注释类或方法
- 注释的方法将成为一个请求处理方法,并由调度程序在接收到对应URL请求时调用
- 注释一个控制器类时,将所有的方式都映射为相同类级别的请求,但在具体方法上还可以再设置更精确的映射地址
@RequestMapping(value="/employee_input")
public String inputEmployee() {
logger.info("inputEmployee called");
return "ProductForm";
}
Model
- import org.springframework.ui.Model;
- saveProduct()的第二个参数是Mode类型,无论是否使用,Spring MVC都会在每一个请求处理方法被调用时创建一个Model实例,用于增加需要显示在视图中的属性,通过 model.addAttribute("product", product);来添加,Product实例就可以像被添加到HttpServletRequest中那样访问了。
public String saveProduct(ProductForm productForm, Model model) {
logger.info("saveProduct called");
// no need to create and instantiate a ProductForm
// create Product
Product product = new Product();
product.setName(productForm.getName());
product.setDescription(productForm.getDescription());
try {
product.setPrice(Float.parseFloat(
productForm.getPrice()));
} catch (NumberFormatException e) {
}
// add product
model.addAttribute("product", product);
return "ProductDetails";
}
@Autowired和@Service
- @Service注释一个类,表示这是一个服务
- 服务类也需要像控制类一样设置扫描包的范围<context:component-scan base-package="app04b.service"/>
- @Autowired可以将一个服务类的实例注入到控制类中,注入后可以直接使用该服务类的实例
@Autowired
private ProductService productService;// 无需手动new ProductService,
Product savedProduct = productService.add(product);//直接使用实例productService
@RequestParam
- 请求参数采用key=value的形式,并用&分隔
- 例:http://localhost:8080/app/product?productID=3
- ?问号后面的就是请求参数,key为productID,value为3
- 传统servlet方法:
String productId = httpServletRequest.getParameter("productID")
- Spring MVC方法:直接在处理该请求的方法的参数列表中加上@RequestParam注解,
public void sendProduct(@RequestParam int productID)
- 参数类型不一定要是字符串,可以设置为自己想要的类型,Spring MVC会尽力转换为非字符串类型
@PathVariable
- 有时候参数不是采用键值对的方式,也没有?问号分割,而是直接放在了请求中
- 例如:/product/productID
- 用SpringMVC的方法,首先在RequestMapping注解的在value属性中添加一个变量,用花括号{}括起来,然后在方法形式参数上加一个同名变量,并用@PathVariable注解
@RequestMapping(value = "/product_view/{id}")
public String viewProduct(@PathVariable Long id, Model model) {
Product product = productService.get(id);
model.addAttribute("product", product);
return "ProductView";
}
网友评论