Spring与SpringMVC
文章目录
一. Spring
1. Spring概述
-
Spring是一个开源框架
-
Spring为简化企业级开发而生,使用Spring,JavaBean就可以实现很多以前要靠EJB才能实现的功能。同样的功能,在EJB中要通过繁琐的配置和复杂的代码才能够实现,而在Spring中却非常的优雅和简洁。
-
Spring是一个IOC(DI)和AOP容器框架。
-
Spring的优良特性
依赖注入:DI——Dependency Injection,反转控制(IOC)最经典的实现。
面向切面编程:Aspect Oriented Programming——AOP
一站式:在IOC和AOP的基础上可以整合各种企业应用的开源框架和优秀的第三方类库(实际上Spring 自身也提供了表述层的SpringMVC和持久层的Spring JDBC)。 -
Spring模块
2. IOC 和 DI 简介
2.1 IOC(Inversion of Control):反转控制
在应用程序中的组件需要获取资源时,传统的方式是组件主动的从容器中获取所需要的资源,在这样的模式下开发人员往往需要知道在具体容器中特定资源的获取方式,增加了学习成本,同时降低了开发效率。
反转控制的思想完全颠覆了应用程序组件获取资源的传统方式:反转了资源的获取方向——改由容器主动的将资源推送给需要的组件,开发人员不需要知道容器是如何创建资源对象的,只需要提供接收资源的方式即可,极大的降低了学习成本,提高了开发的效率。这种行为也称为查找的被动形式。
通俗点说就是组件获取容器中的对象的方式由主动变为被动
2.2 DI(Dependency Injection):依赖注入
IOC的另一种表述方式:即组件以一些预先定义好的方式(例如:setter 方法)接受来自于容器的资源注入。相对于IOC而言,这种表述更直接。
IOC 描述的是一种思想,而DI 是对IOC思想的具体实现。
3. Spring Bean配置
3.1 Bean配置解释
: 让IOC容器管理一个具体的对象.id: 唯一标识class: 类的全类名. 通过反射的方式创建对象. Class cls = Class.forName("helloworld.Hello");Object obj = cls.newInstance(); 无参数构造器: 给对象的属性赋值.name: 指定属性名 ,要去对应类中的set方法. value:指定属性值
3.2 获取bean的方式
applicationContext.xml
/*** 获取bean的方式* 1. 根据名称(id属性值)获取* Hello hello = (Hello)ioc.getBean("hello");* * 2.根据bean的类型获取* -要求:IOC容器中该类型的bean是唯一的,否则会抛出异常* 即 class="helloworld.Hello" 只能有一个*/
// 1. id属性值获取
Hello hello1 = (Hello)ioc.getBean("hello");
// 2. bean类型获取 这个不用强转
Hello hello2 = ioc.getBean(Hello.class);
3.3 给bean的属性赋值
给bean的属性赋值方式
- 通过value属性赋值: integer string等基本类型可以用value
- 通过ref属性赋值: 引用类型属性用ref
3.4 引用外部属性文件
当bean的配置信息逐渐增多时,查找和修改一些bean的配置信息就变得愈加困难。这时可以将一部分信息提取到bean配置文件的外部,以properties格式的属性文件保存起来,同时在bean的配置文件中引用properties属性文件中的内容,从而实现一部分属性值在发生变化时仅修改properties属性文件即可。这种技术多用于连接数据库的基本信息的配置。
4. 基于注解配置bean
4.1 自动装配
- 手动装配:以value或ref的方式明确指定属性值都是手动装配。
- 自动装配:根据指定的装配规则,不需要明确指定,Spring自动将匹配的属性值注入bean中。
4.2 通过注解配置bean
- 普通组件:@Component
标识一个受Spring IOC容器管理的组件 - 持久化层(Dao)组件:@Repository
标识一个受Spring IOC容器管理的持久化层组件 - 业务逻辑层(Service)组件:@Service
标识一个受Spring IOC容器管理的业务逻辑层组件 - 表述层控制器组件:@Controller
标识一个受Spring IOC容器管理的表述层控制器组件 - 组件命名规则
①默认情况:使用组件的简单类名首字母小写后得到的字符串作为bean的id
②使用组件注解的value属性指定bean的id
注意:事实上Spring并没有能力识别一个组件到底是不是它所标记的类型,即使将@Respository注解用在一个表述层控制器组件上面也不会产生任何错误,所以 @Respository、@Service、@Controller这几个注解仅仅是为了让开发人员自己明确当前的组件扮演的角色。
Dao层实现类
/** 通过注释将当前类交给IOC容器管理之后,* 默认在IOC容器中对象的id是类名的首字母小写 userDaoImpl* 可以通过value属性来指定该id,而且value可以不写*/
//@Repository(value="userDao")
@Repository("userDao")
public class UserDaoImpl implements UserDao{@Overridepublic void saveUser() {System.out.println("User信息被保存了");}
}
Service层实现类
@Service("userService")
public class UserServiceImpl implements UserService{@Autowiredprivate UserDao userDao;@Overridepublic void saveUser() {System.out.println("service的saveUser()方法,调用dao层saveUser()");userDao.saveUser();}
}
4.3 扫描组件
在Dao或Service等层的实现类加了注解,但是spring怎么知道呢?通过配置xml文件。
4.4 组件装配
Service层实现类
@Service("userService")
public class UserServiceImpl implements UserService{/** 在Service层需要调用Dao层方法是,传统是new UserDaoImpl()一个对象* 但在spring中可以通过添加@Autowired注解实现自动装配* @Autowiredprivate UserDao userDao;*//** 自动装配规则:* 1. 根据属性类型实现自动装配* * 2. 如果根据类型无法实现自动装配(例如有两个UserDao实现类),会以属性名作为id从IOC容器中寻找以实现自动装配* 例如在UserDaoImpl中 @Repository("userDao") 在UserDaoImpl2中 @Repository("userDao2")* 会装配UserDaoImpl* * 3. 但假如UserDaoImpl中 @Repository("userDao1"),通过1和2都不能实现自动装配* 可以通过@Qualifier的value属性来指定id实现自动装配,并且value可省略不写*/@Qualifier("userDao2")@Autowiredprivate UserDao userDao;/** 添加了@Autowired注解的属性默认必须注入成功,否则抛异常* 但可以通过required属性的值为false来告诉Spring当前属性可以不装配* 不装配就是null,空指针,但不会报错*/@Autowired(required=false)private User user;@Overridepublic void saveUser() {System.out.println("service 的saveUser()方法,调用dao层");userDao.saveUser();}
}
二. SpringMVC
1. SpringMVC 概述
- 一种轻量级的、基于MVC的Web层应用框架。偏前端而不是基于业务逻辑层。Spring框架的一个后续产品;
- Spring 为展现层提供的基于 MVC 设计理念的优秀的 Web 框架,是目前最主流的 MVC 框架之一;
- Spring MVC 通过一套 MVC 注解,让 POJO 成为处理请求的控制器,而无须实现任何接口。
执行流程:
- 启动服务器,加载一些配置文件
(1) web.xml
springDispatcherServlet org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml 1 springDispatcherServlet /
DispatcherServlet对象被创建 以及 springmvc.xml配置文件被加载
(2) springmvc.xml
此时自动扫描的包下注解了@Controller的类HelloWorld被创建成对象,以及通过配置方式生成的bean对象:视图解析器
- 发送请求,后台处理流程:
2. @RequestMapping 映射请求注解
2.1 @RequestMapping 概念
- SpringMVC使用@RequestMapping注解为控制器指定可以处理哪些 URL 请求
- 作用:DispatcherServlet 截获请求后,就通过控制器上 @RequestMapping 提供的映射信息确定请求所对应的处理方法。
2.2 标注位置
类和方法上
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;@RequestMapping("/springmvc")
@Controller
//这个类是一个处理器
public class HelloWorld {/** 方法的返回值会被springmvc配置文件的InternalResourceViewResolver这个视图解析器解析为真实的物理视图* 然后自动进行请求的转发* 真实的物理视图 = 前缀 + 方法的返回值 + 后缀* 即 /WEB-INF/views/success.jsp*/@RequestMapping("/hello")public String testHelloWorld(){System.out.println("hello springmvc!");return "success";}
}
同时标注在类和方法上,则此时要映射的请求路径为 /springmvc/hello;
如果只在方法上标注,此时的路径为 /hello
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
Insert title here
Hello Springmvc
2.3 @RequestMapping 映射请求URL与 请求方式
@RequestMapping注解中的属性:
- value:用来设置要映射的请求地址,值的类型是String类型的数组
如果只映射一个请求地址,那么value的值不需要添加大括号{},value属性名可以省略不写 - method:用来设置映射的请求方式
如果没有设置该属性,那么只看映射的请求地址,不管请求方式
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;@RequestMapping("/springmvc")
@Controller
//这个类是一个处理器
public class HelloWorld {@RequestMapping("/hello")public String testHelloWorld(){System.out.println("hello springmvc!");return "success";}//映射多个请求地址@RequestMapping(value={"/testValue","/testValue2"})public String testValue(){System.out.println("hello testValue!");return "success";}//请求方式为post@RequestMapping(value="/testMethod",method=RequestMethod.POST)public String testMethod(){System.out.println("hello testMethod!");return "success";}
}
<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
Insert title here
Hello Springmvc Test Value Test Value2 Test Method
3. 处理请求数据
3.1 @RequestParam注解
在处理方法入参处使用 @RequestParam 可以把请求参数传递给请求方法
用来映射请求参数,该注解的属性:
- value:设置请求参数的参数名
- required:设置请求参数是否是必须的,默认是true
- defaultValue:设置请求参数的默认值,如果没有传入该请求参数将使用该值
Test RequestParam
@RequestMapping(value="/testParam")
public String testRequestParam(@RequestParam(value="username")String name,@RequestParam(value="age",required=false,defaultValue="0")int age){System.out.println("hello testParam!");System.out.println("用户名:" + name + "年龄:" + age);return "success";
}
解释:
1)假如方法入参处如下:
public String testRequestParam(@RequestParam(value="username")String name,@RequestParam(value="age")Integer age)
则会出错,因为在jsp文件中/springmvc/testParam?username=admin
,没有输入age以及数值;此时可以加上required=false
,即
public String testRequestParam(@RequestParam(value="username")String name,@RequestParam(value="age",required=false)Integer age)
2)假如方法入参处如下:
public String testRequestParam(@RequestParam(value="username")String name,@RequestParam(value="age",required=false)int age)
将Integer改成int,会报错,因为无法将null类型转换成Integer包装类型,此时可以加上默认值defaultValue="0"
3.2 使用POJO作为参数
1)使用 POJO 对象绑定请求参数值
2)Spring MVC 会按请求参数名和 POJO 属性名进行自动匹配,自动为该对象填充属性值。支持级联属性。如:dept.deptId、dept.address.tel 等
要求:中name的值一定要和Employee和Department中的属性名字一样
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
@RequestMapping(value="/testPOJO")
public String testPOJO(Employee employee){System.out.println("员工信息是:"+employee);return "success";
}
3.3 使用Servlet原生API作为参数
MVC 的 Handler 方法可以接受哪些 ServletAPI 类型的参数
Test ServletAPI
//使用Servlet原生API作为参数
@RequestMapping(value="/testServletAPI")
public String testServletAPI(HttpServletRequest request,HttpServletResponse response){String username = request.getParameter("username");System.out.println(username);String age = request.getParameter("age");System.out.println(age);return "success";
}
4. 处理响应数据
1)ModelAndView: 处理方法返回值类型为 ModelAndView 时, 方法体即可通过该对象添加模型数据
2)Map 及 Model: 入参为 org.springframework.ui.Model、org.springframework.ui.ModelMap 或 java.uti.Map 时,处理方法返回时,Map 中的数据会自动添加到模型中。
4.1 处理响应数据之 ModelAndView
1)控制器处理方法的返回值如果为 ModelAndView, 则其既包含视图信息,也包含模型数据信息。
2)添加模型数据:
MoelAndView addObject(String attributeName, Object attributeValue)
ModelAndView addAllObject(Map
3)设置视图:
void setView(View view)
void setViewName(String viewName)
设置超链接
Test ModelAndView
编写处理方法
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(){//1.创建ModelAndView对象ModelAndView mv = new ModelAndView();//假设从数据库中查询出来一个Employee对象 里面就是模型数据Employee employee = new Employee(1,"张三丰","a@b.com",null);//2.将模型数据设置到ModelAndView对象中mv.addObject("emp", employee);//3.设置视图名mv.setViewName("success");return mv;
}
在视图上显示数据
${emp }
结果:
4.2 处理响应数据之 Map 、Model
1)Spring MVC 在内部使用了一个 org.springframework.ui.Model 接口存储模型数据
具体使用步骤
2)Spring MVC 在调用方法前会创建一个隐含的模型对象作为模型数据的存储容器。
3)如果方法的入参为 Map 或 Model 类型,Spring MVC 会将隐含模型的引用传递给这些入参。
4)在方法体内,开发者可以通过这个入参对象访问到模型中的所有数据,也可以向模型中添加新的属性数据
相比ModelAndView,这种方法更加便捷。
/** 处理响应数据方式2:在Handler犯法入参处传入Map、Model、ModelMap* 不管是将Handler方法返回值设置为ModelAndView还是在Handler方法入参处传入Map、Model、ModelMap* SpringMVC都会转换为一个ModelAndView对象*/
@RequestMapping("/testMap")
public String testMap(Map map){//假设从数据库中查询出来一个Employee对象Employee employee = new Employee(1,"张三丰","a@b.com",null);//将employee对象放到map中,最后会放到request域中map.put("emp",employee);return "success";
}
结果:
4.3 @ResponseBody注解
在Handler方法上添加该注解之后,方法的返回值将以字符串的形式直接响应给浏览器。可以加到类上或方法上。
在类上添加了@ResponseBody注解之后,Handler的方法的返回值将直接返回给浏览器,但是前提是在springmvc的配置文件中配置了
标签。
设置超链接
Test ResponseBody
处理方法
@RequestMapping("/testResponseBody")
@ResponseBody
public String testResponseBody(){System.out.println("testResponseBody");return "success";
}
结果:
4.4 重定向
1)一般情况下,控制器方法返回字符串类型的值会被当成逻辑视图名处理
2)如果返回的字符串中带 forward: 或 redirect: 前缀时,SpringMVC 会对他们进行特殊处理:将 forward: 和 redirect: 当成指示符,其后的字符串作为 URL 来处理
3)redirect:success.jsp:会完成一个到 success.jsp 的重定向的操作
4)forward:success.jsp:会完成一个到 success.jsp 的转发操作
Test ReDirect
/** 重定向*/
@RequestMapping("/testReDirect")
public String testReDirectDirect(){System.out.println("testReDirect");//可以重定向到jsp页面//return "forward:/redirect.jsp";//也可以到其他方法return "redirect:/springmvc/testMap";
}
三. Spring与SpringMVC的整合
Spring和SpringMVC的整合:
问题1:在SpringMVC中DispatcherServlet会帮我们自动初始化SpringMVC的IOC容器,那Spring的IOC容器如何初始化?
web.xml文件中配置一下信息:
springDispatcherServlet org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml 1 springDispatcherServlet / contextConfigLocation classpath:beans.xml org.springframework.web.context.ContextLoaderListener
问题2:在beans.xml与springmvc.xml中,都各自创建了Handler和Service对象,即Handler和Service对象被创建了两次。
beans.xml
springmvc.xml
标签:
相关文章
-
无相关信息