三层架构:
在java开发中基本上都是B/S架构,即浏览器/服务器。系统标准的三层架构包括:表现层、业务层、持久层。
-
表现层 :
也就是我们常说的web 层。它负责接收客户端请求,向客户端响应结果,通常客户端使⽤http 协议请求web 层,web 需要接收 http 请求,完成 http 响应。
表现层包括展示层和控制层:控制层负责接收请求对应controller,展示层负责结果的展示对应页面。表现层依赖业务层,接收到客户端请求⼀般会调⽤业务层进⾏业务处理,并将处理结果响应给客户端。表现层的设计⼀般都使⽤ MVC 模型。(MVC 是表现层的设计模型,和其他层没有关系)
-
业务层 :
也就是我们常说的 service 层。它负责业务逻辑处理,和我们开发项⽬的需求息息相关。web 层依赖业务层,但是业务层不依赖 web 层。
业务层在业务处理时可能会依赖持久层,如果要对数据持久化需要保证事务⼀致性所以事务应该放到业务层
-
持久层 :
也就是我们是常说的 dao 层。负责数据持久化,包括数据层即数据库和数据访问层,数据库是对数据进⾏持久化的载体,数据访问层是业务层和持久层交互的接⼝,业务层需要通过数据访问层将数据持久化到数据库中。通俗的讲,持久层就是和数据库交互,对数据库表进⾏增删改查的。
MVC设计模式
MVC 全名是 Model View Controller,是 模型(model)-视图(view)-控制器(controller) 的缩写, 是⼀种⽤于设计创建 Web 应⽤程序表现层的模式。MVC 中每个部分各司其职:
-
Model(模型):模型包含业务模型和数据模型,数据模型⽤于封装数据,业务模型⽤于处理业务。
-
View(视图): 通常指的就是我们的 jsp 或者 html。作⽤⼀般就是展示数据的。通常视图是依据模型数据创建的。
-
Controller(控制器): 是应⽤程序中处理⽤户交互的部分。作⽤⼀般就是处理用户请求的。
MVC提倡:每⼀层只编写⾃⼰的东⻄,不编写任何其他的代码;分层是为了解耦,解耦是为了维护⽅便和分⼯协作。
Spring MVC 是什么?
SpringMVC 全名叫 Spring Web MVC,是⼀种基于 Java 的实现 MVC 设计模型的请求驱动类型的轻量级Web 框架,属于 SpringframeWork 的后续产品。
它通过⼀套注解,让⼀个简单的 Java 类成为处理请求的控制器,⽽⽆须实现任何接⼝。同时它还⽀持RESTful 编程⻛格的请求。
Spring MVC和Struts2⼀样,都是 为了解决表现层问题 的web框架,它们都是基于 MVC 设计模式的。⽽这些表现层框架的主要职责就是处理前端HTTP请求。
Spring MVC 本质可以认为是对servlet的封装,简化了我们serlvet的开发其作用是接收请求和返回响应,跳转⻚⾯
使用springmvc1.引入spring webmvc的依赖
org.springframework spring-webmvc5.1.12.RELEASE javax.servlet javax.servlet-api3.1.0 provided
2.在web.xml中配置servlet
springmvc org.springframework.web.servlet.DispatcherServlet contextConfigLocation classpath:springmvc.xml springmvc /
url-pattern是指要拦截的请求有三种方式
-
方式一:带后缀,比如*.action *.do *.aaa该种方式比较精确、方便,在以前和现在企业中都有很大的使用比例
-
方式二:/ 不会拦截 .jsp,但是会拦截.html等静态资源(静态资源:除了servlet和jsp之外的js、css、png等)
- 拦截静态资源是因为tomcat容器中的web.xml(父),项目中也有一个web.xml(子),是一个继承关系。父web.xml中有一个DefaultServlet, url-pattern 是一个 / 此时我们自己的web.xml中也配置了一个 / ,覆写了父web.xml的配置
- 不拦截.jsp是因为父web.xml中有一个JspServlet,这个servlet拦截.jsp文件,而我们并没有覆写这个配置,所以springmvc此时不拦截jsp,jsp的处理交给了tomcat
-
方式三: public abstract class Interview { private final void register() { System.out.println("⾯试登记"); } protected abstract void communicate(); private final void notifyResult() { System.out.println("HR⼩姐姐通知⾯试结果"); } protected final void process() { this.register(); this.communicate(); this.notifyResult(); } }
Java岗位⾯试者
public class Interviewee1 extends Interview{ public void communicate() { System.out.println("我是⾯试⼈员1,来⾯试Java⼯程师,我们聊的是Java相关内容"); } }前端岗位⾯试者
public class Interviewee2 extends Interview{ public void communicate() { System.out.println("我是⾯试⼈员2,来⾯试前端⼯程师,我们聊的是前端相关内容"); } }客户端测试类
public class InterviewTest { public static void main(String[] args) { // ⾯试Java⼯程师 Interview interviewee1 = new Interviewee1(); interviewee1.process(); // ⾯试前端⼯程师 Interview interviewee2 = new Interviewee2(); interviewee2.process(); } }打印结果
适配器模式面试登记
我是⾯试⼈员1,来⾯试Java⼯程师,我们聊的是Java相关内容
HR⼩姐姐通知⾯试结果
面试登记
我是⾯试⼈员2,来⾯试前端⼯程师,我们聊的是前端相关内容
HR⼩姐姐通知⾯试结果
使得原本由于接⼝不兼容⽽不能⼀起⼯作、不能统⼀管理的那些类可以⼀起⼯作、可以进⾏统⼀管理
- 解决接⼝不兼容⽽不能⼀起⼯作问题,看下⾯⼀个⾮常经典的案例
在中国,⺠⽤电都是220v交流电,但是⼿机锂电池⽤的都是5v直流电。因此,我们给⼿机充电时就需要使⽤电源适配器来进⾏转换。使⽤代码还原这个⽣活场景创建AC220类,表示220v交流电
public class AC220 { public int outputAC220V() { int output = 220; System.out.println("输出交流电" + output + "V"); return output; } }创建DC5接⼝,表示5V直流电:
public interface DC5 { int outputDC5V(); }创建电源适配器类 PowerAdapter
public class PowerAdapter implements DC5 { private AC220 ac220; public PowerAdapter(AC220 ac220) { this.ac220 = ac220; } public int outputDC5V() { int adapterInput = ac220.outputAC220V(); // 变压器... int adapterOutput = adapterInput/44; System.out.println("使⽤ PowerAdapter 输⼊AC:" + adapterInput + "V 输出DC:" + adapterOutput + "V"); return adapterOutput; } }客户端测试代码
public class AdapterTest { public static void main(String[] args) { DC5 dc5 = new PowerAdapter(new AC220()); dc5.outputDC5V(); } }在上⾯的案例中,通过增加电源适配器类PowerAdapter实现了⼆者的兼容
- 解决不能统⼀管理的问题
SpringMVC中处理器适配器(HandlerAdapter)机制就是解决类统⼀管理问题⾮常经典的场景
其中 HandlerAdapter接⼝是处理器适配器的顶级接⼝,它有多个⼦类,包括AbstractHandlerMethodAdapter、SimpleServletHandlerAdapter、SimpleControllerHandlerAdapter、HttpRequestHandlerAdapter、RequestMappingHandlerAdapter
其适配器调⽤的关键代码也在DispatcherServlet的doDispatch()
在 doDispatch() ⽅法中调⽤了 getHandlerAdapter() ⽅法
在 getHandlerAdapter() ⽅法中循环调⽤了 supports() ⽅法判断是否兼容,循环迭代集合中的“Adapter” 在初始化时已经赋值。



