SpringMVC
一 、建立一个mvc项目
web.xml就三个东西,处理请求方法的过滤器和处理编码的过滤器和一个Dispatcherservlet
@Primary 优先装配bean
@PropertySource(“classpath:db.properties”) 在配置类上加载文件
@ComponentScan(“cn.webrx.service”) (2)@Import
|1.引入springmvc pom依赖
<dependencies>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.17</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.1</version>
<scope>provided</scope>//打包时不打进去
</dependency>
<!-- https://mvnrepository.com/artifact/ch.qos.logback/logback-classic -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.2.11</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.thymeleaf/thymeleaf-spring5 -->
<dependency>
<groupId>org.thymeleaf</groupId>
<artifactId>thymeleaf-spring5</artifactId>
<version>3.0.15.RELEASE</version>
</dependency>
</dependencies>
|2.增加webapp目录
|3.然后在项目结构,模块中点击web加入web.xml文件(路径要修改一下)
二、扩展配置xml文件
|默认配置方式配置时,xml文件默认位置在web-inf目录下,我们要把xml文件放在resouces目录下,就需要扩展配置<init-param>
|浏览器无法访问类文件所以需要配置servlet。
/ 除了jsp页面不匹配
/* jsp页面也匹配
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
version="4.0">
<!-- 配置SpringMVC的前端控制器,对浏览器发送的请求进行统一处理-->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 配置SpringMVC配置文件的位置和名称-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:springMVC.xml</param-value>
</init-param>
<!-- 将前端控制器启动的时间提前-->
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
|在springMVC.xml中配置Thymeleaf视图解析器
<contex:component-scan base-package="com.jsm.controller"/>
<!-- 配置thymeleaf视图解析器-->
<bean id = "viewResolver" class = "org.thymeleaf.spring5.view.ThymeleafViewResolver">
<!-- 好多模板引擎 优先级-->
<property name="order" value = "1"/>
<property name="characterEncoding" value="UTF-8"/>
<property name="templateEngine">
<bean class = "org.thymeleaf.spring5.SpringTemplateEngine">
<property name="templateResolver">
<bean class = "org.thymeleaf.spring5.templateresolver.SpringResourceTemplateResolver">
<!-- 视图前缀-->
<property name="prefix" value="/WEB-INF/templates/"/>
<!-- 视图后缀-->
<property name="suffix" value=".html"/>
<property name="templateMode" value="HTML5"/>
<property name="characterEncoding" value="UTF-8"/>
</bean>
</property>
</bean>
</property>
</bean>
@RequestMapping() //请求映射
th:href="@{/target} //thymeleaf动态拼接路径
|总结
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Y7yhWLUI-1649760328407)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220328165530792.png)]
三、springmvc的注解
|@Required
默认为true,请求参数必须传输,否则报错。
|@RequestMapping()属性 设置的属性越多匹配的条件越多
value属性: 可以有多个值value{"/index","/index1","index2"}404
method属性: 通过请求方式匹配映射。post(对应添加)参数有请求体。get(对应查询)请求参数拼接在地址栏内。delete(删除)。put(修改)。405
params属性:{}里面的所有的请求参数必须都得符合。400
headers属性:{"host=localhost:8080"}请求头。404
|派生注解 可以不用设置method属性
@GetMapping:处理get请求
@PostMapping:处理post请求
@PutMapping:处理put请求
@DeleteMapping:处理delete请求
|请求映射支持ant风格模糊路径
? 任意单个字符
* 任意0个或多个字符
** 表示任意一层或多层目录
注意:在使用**时,只能使用/**/xxx的方式**两边不能有。
|SpringMVC支持路径中的占位符
原始方式:/delete User?id=1
restful方式:/deleteUser/1 (将某些数据通过路径的方式传输到服务器中,可以在value属性中通过占位符{xxx}表示传输数据,在通过@PathVarlable注解,赋值。)
四、SpringMVC获取请求参数
|1.通过ServletAPI获取
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iDcGa2vf-1649760328408)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220329185759303.png)]
|2.通过控制器参数获取
请求参数名跟控制器方法参数名保持一致就会自动赋值给形参。
如果有同名参数例如复选框,就用String,或者String[]获取。
如果请求参数跟控制器的参数不一样就使用@RequestParam("user_name"),注解映射控制器的参数username。
@RequestParam有三个属性。是将请求参数与控制器参数联系
value:请求参数名
required属性:默认为true,请求参数必须传输,否则报错。400
defaultValue属性:请求参数没有传就可以设置一个默认值。
@RequestHeader(value="Host",required = true,defaultValue = "localhost:8080")同上。是将请求头信息和控制器参数联系。
@CookieValue("JSESSIONID") 同上三个属性 将cookie信息与控制器参数联系。
五、通过pojo获取请求参数
|可以在控制器方法的形参位置设置一个实体类型的形参,此时若浏览器传输的请求参数的参数名和实体类中的属性名一致,那么请求参数就会为此属性赋值。
public String testPojo(User user){}
解决post乱码问题,为什么会出现乱码问题呢,因为tomcat的原因,那么在什么时候设置处理乱码呢,不能在控制器里设置因为,参数已经在服务器启动时加载了。在tomcat中监听器(只执行一次)先启动,然后是过滤器,所以在过滤器中设置编码问题。
<filter>
<filter-name>CharacterEncodingFilter</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>forceResponseEncoding</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
六、域对象共享数据
|1、使用servletAPI向request域对象共享数据
@Controller
public class TestRequest {
@RequestMapping("/")
public String index(){
return "index";
}
@RequestMapping("/testRequest")
public String testRequest (HttpServletRequest request){
request.setAttribute("RequestKey","RequestValues");
return "success";
}
}
index.html
<a th:href="@{/testRequest}">testRequest</a>
success.html
success
<p th:text="${RequestKey}"></p>
|2.使用ModelAndView向request域对象共享数据
ModelAndView有两个功能,Model用于向请求域共享数据,View用于视图返回
@RequestMapping("/testModelAndView")
public ModelAndView testModelAndView(ModelAndView mv){
//向共享域中添加数据
mv.addObject("RequestKey","ModelAndViewValues");
mv.setViewName("success");
return mv;
}
|3.使用Model向request域对象共享数据
@RequestMapping("/testModel")
public String testModel(Model mv){
mv.addAttribute("RequestKey","ModelValue");
return "success";
}
|4.使用Map向request域对象共享数据
@RequestMapping("/testMap")
public String testMap(Map<String,Object> map){
map.put("RequestKey","MapValue");
return "success";
}
|5.使用MadelMap向request域对象共享数据
@RequestMapping("/testModelMap")
public String testModelMap(ModelMap mm){
mm.addAttribute("RequestKey","ModelMapValue");
return "success";
}
|6.Model、ModelMap、Map的关系
本质上都是BindingAwareModelMap类型的
Model和Map都是接口,ModelMap是类
|所有的方式最终都会封装为ModelAndView。
|向session域共享数据
@RequestMapping("/testSession")
public String testSession(HttpSession session){
session.setAttribute("SessionKey","SessionValue");
return "success";
}
接受session的key
<p th:text="${session.SessionKey}"></p>
|向application域共享数据
@RequestMapping("/testApplication")
public String testAppliaction(HttpSession session){
ServletContext application = session.getServletContext();
application.setAttribute("ApplicationKey","ApplicationValue");
return "success";
}
<p th:text="${application.ApplicationKey}"></p>
七、SpringMVC的视图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1rM9B8uE-1649760328408)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220330104737683.png)]
1.ThtmeleafView
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NjZ4e6ri-1649760328408)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220330110302488.png)]
2.转发视图
转发可以访问WEB-INF里的内容
forward:/请求资源,:后面不能是具体的页面
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-w8ICTz7l-1649760328409)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220330111308376.png)]
3.重定向视图
重定向不可以访问WEB-INF里的内容
redirect:/请求资源,:后面不能是具体的页面,而是具体的请求
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vlzm4Bm4-1649760328409)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220330112411567.png)]
4.视图控制器view-controller
当控制器方法中只是用来实现页面跳转,可以将处理方法使用view-controller标签进行表示。
就是把
@RequestMapping("/")
public String index(){return "index";}
变成
<mvc:view-controller path="/" view-name="index"/>
<!-- 开启注解驱动-->
<mvc:annotation-driven/>
当设置配置文件时,controller里的所有映射就失效了。必须开启注解驱动。
八、RESTFul
|表现层资源状态转移
表现层就是controller和视图,资源就是一个类,一个页面一张图片。状态就是资源的形式比如是一张图片,是一个类。
REST风格就是用URL地址使用统一的风格设计,去获取资源。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oF632D60-1649760328410)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220330180724635.png)]
|处理put和delete方法请求
<!--配置HiddenHttpMethodFilter-->
<filter>
<filter-name>HiddenHttpMethodFilter</filter-name>
<filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>HiddenHttpMethodFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<form th:action="@{/user}" method="post">
<input type="hidden" name="_method" value="PUT">
<label>用户名:<input type="text" name="username" value="jsm"> </label><br>
<label>密码:<input type="password" name="pwd" value="123456"> </label><br>
<label><input type="submit" value="提交"> </label>
</form>
九、HttpMessageConverter
报文信息转换器,将请求报文转换为java对象,或将java对象转换为响应报文。
提供了两个注解和两个类型,@RequestBody,@ResponseBody,RequestEntity,ResponseEntity
1、@RequestBody
可以获取请求体,需要在控制器方法设置一个形参,使用此注解标识,当前请求体就会为当前注解所标识的形参赋值
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l243LYH2-1649760328410)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220401103522217.png)]
2、RequestEntity
可以接受请求头和请求体。封装请求报文的一种类型,需要在控制器方法的形参中设置类型的形参,请求赋值给该形参,可以通过getHeaders()获取请求头信息,通过getBody()获取请求体信息
3、@ResponseBody
用于标识一个控制器方法,可以将该方法的返回值直接作为响应报文的响应体响应到浏览器
4、RestController
相当于Controller和ResponseBody,
十、spring处理ajax
list和set转化为json为json数组,User对象和map转换为json对象。
|加入依赖
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.13.2</version>
</dependency>
|index
<div id="rajax">
<a @click="responajax" th:href="@{/responAjax}">AJAX</a></div>
<script type="text/javascript" th:src="@{/static/js/vue.js}"></script>
<script type="text/javascript" th:src="@{/static/js/axios.min.js}"></script>
<script type="text/javascript">
var vue = new Vue({
el:"#rajax",
methods:{
responajax:function (event) {
axios({
method:"post",
url:event.target.href,
params:{
username:"admin",
pwd:"123"
}
}).then(function (response){
alert(response.data);
});
event.preventDefault();
}
}
});
</script>
十一、文件下载
@RequestMapping("/file")
public ResponseEntity<byte[]> testFile(HttpSession session) throws IOException{
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.jpg");
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeader对象设置响应头信息
MultiValueMap<String,String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition","attachment;filename=1.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes,headers,statusCode);
//关闭输入流
is.close();
return responseEntity;
}
上传不能用get
上传文件
首先引入pom
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.4</version>
</dependency>
<form th:action="@{/file1}" method="post" enctype="multipart/form-data">
<label>上传文件:<input type="file" name="photo"></label>
<label><input type="submit"></label>
</form>
@RequestMapping("/file1")
public String file1(MultipartFile photo){
//获取文件名
String filename = photo.getOriginalFilename();
ServletContext servletContext = session.getServletContext();
String photoPath = servletContext.getRealPath("photo");
File file = new File(photoPath);
if (!file.exists()){
file.mkdirs();
}
String finalPath = photoPath+File.separator+filename;
photo.transferTo(new File(finalPath));
return "success";
}
<!-- 配置文件上传解析器,将上传的文件封装为MultipartFile,-->
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"/>
下载
@RequestMapping("/file")
public ResponseEntity<byte[]> testFile(HttpSession session) throws IOException{
//获取ServletContext对象
ServletContext servletContext = session.getServletContext();
//获取服务器中文件的真实路径
String realPath = servletContext.getRealPath("/static/img/1.jpg");
//创建输入流
InputStream is = new FileInputStream(realPath);
//创建字节数组
byte[] bytes = new byte[is.available()];
//将流读到字节数组中
is.read(bytes);
//创建HttpHeader对象设置响应头信息
MultiValueMap<String,String> headers = new HttpHeaders();
//设置要下载方式以及下载文件的名字
headers.add("Content-Disposition","attachment;filename=1.jpg");
//设置响应状态码
HttpStatus statusCode = HttpStatus.OK;
//创建ResponseEntity对象
ResponseEntity<byte[]> responseEntity = new ResponseEntity<>(bytes,headers,statusCode);
//关闭输入流
is.close();
return responseEntity;
}
十二、拦截器
|过滤器是作用在浏览器和控制器之间的,拦截器是作用于控制器执行前后的。
<!--配置拦截器-->
<mvc:interceptors>
<!-- 默认对所有请求进行拦截-->
<!-- <bean class="com.jsm.controller.FileController"/>-->
<!-- <ref bean="firstInterceptors"/>-->
<mvc:interceptor>
<mvc:mapping path="/*"/>
<mvc:exclude-mapping path="/"/>
<ref bean="firstInterceptors"/>
</mvc:interceptor>
</mvc:interceptors>
@Component
public class FirstInterceptors implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("FirstInterceptor-->preHandle");
return false;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
System.out.println("FirstInterceptor-->postHandle");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
System.out.println("FirstInterceptor-->afterCompletion");
}
}
|配置多个拦截器的执行顺序
preHandle以配置文件的先后顺序执行。
postHandle、afterCompletion以配置文件的逆序执行。
|如果有5个拦截器,其中第3个拦截器返回false
则第三个拦截器及以前的拦截器的preHandle会执行,而postHandle一个都不会执行,第三个以前的1,2的afterCompletion会执行。
十二、异常处理器
<!--配置异常处理器-->
<bean class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver">
<property name="exceptionMappings">
<props>
<!-- key表示处理器方法执行过程中出现的异常,value表示设置一个新的试图error-->
<prop key="java.lang.ArithmeticException">error</prop>
</props>
</property>
<!-- 获取异常信息-->
<property name="exceptionAttribute" value="jsm"/>
</bean>
<p th:text="${jsm}"></p>
基于注解
@ControllerAdvice
public class Exception {
@ExceptionHandler(value = {ArithmeticException.class,NullPointerException.class })
public String testException(java.lang.Exception jsm, Model model){
model.addAttribute("jsm",jsm);
return "error";
}
}
十三、注解配置SpringMVC
/**
* @Auther Justin-ming
* @Date 2022/4/5 20:15
* 1.扫描组件、视图解析器、view-controller、default-servlet-handler
* mvc注解驱动、文件上传解析器、异常处理、拦截器
*/
//将当前类标识为一个配置类
@Configuration
//扫描组件
@ComponentScan("com.jsm")
//mvc注解驱动
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer {
//视图解析器
@Bean
public ITemplateResolver templateResolver(){
WebApplicationContext webApplicationContext = ContextLoader.getCurrentWebApplicationContext();
ServletContextTemplateResolver templateResolver = new ServletContextTemplateResolver(webApplicationContext.getServletContext());
templateResolver.setPrefix("/WEB-INF/templates/");
templateResolver.setSuffix(".html");
templateResolver.setCharacterEncoding("UTF-8");
templateResolver.setTemplateMode(TemplateMode.HTML);
return templateResolver;
}
//生成模板引擎并为模板注入模板解析器
@Bean
public SpringTemplateEngine templateEngine(ITemplateResolver templateResolver){
SpringTemplateEngine templateEngine = new SpringTemplateEngine();
templateEngine.setTemplateResolver(templateResolver);
return templateEngine;
}
//生成视图解析器并为解析器注入模板引擎
@Bean
public ViewResolver viewResolver(SpringTemplateEngine templateEngine){
ThymeleafViewResolver viewResolver = new ThymeleafViewResolver();
viewResolver.setCharacterEncoding("UTF-8");
viewResolver.setTemplateEngine(templateEngine);
return viewResolver;
}
//default-servlet-handle
@Override
public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) {
configurer.enable();
}
//拦截器
@Override
public void addInterceptors(InterceptorRegistry registry) {
TestInterceptor testInterceptor = new TestInterceptor();
registry.addInterceptor(testInterceptor).addPathPatterns("/**");
}
//view-controller
@Override
public void addViewControllers(ViewControllerRegistry registry) {
registry.addViewController("/hello").setViewName("hello");
}
//异常处理
@Override
public void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> resolvers) {
SimpleMappingExceptionResolver exceptionResolver = new SimpleMappingExceptionResolver();
Properties prop = new Properties();
prop.setProperty("java.lang.ArithmeticException","error");
exceptionResolver.setExceptionMappings(prop);
exceptionResolver.setExceptionAttribute("exception");
resolvers.add(exceptionResolver);
}
//文件处理
// @Bean
// public MultipartResolver multipartResolver(){
// CommonsMultipartResolver commonsMultipartResolver = new CommonsMultipartResolver();
// return commonsMultipartResolver;
// }
}
十四、springmvc常用组件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E8LiYqKm-1649760328410)(C:/Users/Jsm/AppData/Roaming/Typora/typora-user-images/image-20220406110444026.png)]
十五、
1.Spring框架的优点都有什么
Spring是分层的架构,你可以选择使用你需要的层而不用管不需要的部分,Spring是POJO编程,POJO编程使得可持续构建和可测试能力提高,依赖注入和IoC使得JDBC操作简单化,Spring是开源的免费的,Spring使得对象管理集中化和简单化
2.什么是Spring?
Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发。
Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。
Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入(dependency injection,DI)和面向切面编程(aspect-oriented programming,AOP)。
3.什么是IoC?
控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
4.什么是AOP?
面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,OOP面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。实际上也就是说,让不同的类设计不同的方法。这样代码就分散到一个个的类中去了。这样做的好处是降低了代码的复杂程度,使类可重用。
免费的,Spring使得对象管理集中化和简单化
2.什么是Spring?
Spring是一个轻量级Java开发框架,最早有Rod Johnson创建,目的是为了解决企业级应用开发的业务逻辑层和其他各层的耦合问题。它是一个分层的JavaSE/JavaEE full-stack(一站式)轻量级开源框架,为开发Java应用程序提供全面的基础架构支持。Spring负责基础架构,因此Java开发者可以专注于应用程序的开发。
Spring最根本的使命是解决企业级应用开发的复杂性,即简化Java开发。
Spring可以做很多事情,它为企业级开发提供给了丰富的功能,但是这些功能的底层都依赖于它的两个核心特性,也就是依赖注入(dependency injection,DI)和面向切面编程(aspect-oriented programming,AOP)。
3.什么是IoC?
控制反转即IoC (Inversion of Control),它把传统上由程序代码直接操控的对象的调用权交给容器,通过容器来实现对象组件的装配和管理。所谓的“控制反转”概念就是对组件对象控制权的转移,从程序代码本身转移到了外部容器。
Spring IOC 负责创建对象,管理对象(通过依赖注入(DI),装配对象,配置对象,并且管理这些对象的整个生命周期。
4.什么是AOP?
面向切面编程(AOP是Aspect Oriented Program的首字母缩写) ,OOP面向对象的特点是继承、多态和封装。而封装就要求将功能分散到不同的对象中去,这在软件设计中往往称为职责分配。实际上也就是说,让不同的类设计不同的方法。这样代码就分散到一个个的类中去了。这样做的好处是降低了代码的复杂程度,使类可重用。