J2EE中主要讲了Spring , Spring MVC , Mybatis,即SSM框架。
Spring
spring框架的优点
1、非侵入式设计
Spring是一种非侵入式(non-invasive)框架,它可以使应用程序代码对框架的依赖最小化
2、方便解耦、简化开发
Spring就是一个大工厂,可以将所有对象的创建和依赖关系的维护工作都交给Spring容器的管理,大大的降低了组件之间的耦合性
3、支持AOP(面向切面编程)
Spring提供了对AOP的支持,它允许将一些通用任务,如安全、事物、日志等进行集中式处理,从而提高了程序的复用性
4、支持声明式事务处理
只需要通过配置就可以完成对事物的管理,而无须手动编程
5、方便程序的测试
Spring提供了对Junit4的支持,可以通过注解方便的测试Spring程序
6、方便集成各种优秀框架
Spring不排斥各种优秀的开源框架,其内部提供了对各种优秀框架(如Struts、Hibernate、MyBatis、Quartz等)的直接支持
7、降低Jave EE API的使用难度
Spring对Java EE开发中非常难用的一些API(如JDBC、JavaMail等),都提供了封装,使这些API应用难度大大降低
Spring 中的 IOC和DI
传统创建和IOC
传统创建
IOC(Inversion of Control),中文释义为 控制反转 ,是一种设计思想。
在以往的JAVA程序中,我们使用 new 来创建一个新的对象。
如:
User user = new ZhangSan();
很显然,user 是一个 ZhangSan 对象。如果说使用该业务逻辑的地方从始至终都不变,那么使用这种写法没有什么问题,但是如果说有一天因为某种关系,此处的 user 需要变成一个 LiSi 对象,那么我们需要大量的更改代码。
很显然,该写法 耦合度较高。
IOC
使用Spring之后,创建对象由容器接管,Spring容器负责控制程序间的关系。
控制权从应用代码转移到了 Spring 容器,控制权反转,这就是Spring的 控制反转
DI
DI(Dependency Injection) , 中文释义 依赖注入
从Spring 容器的角度来看,Spring 容器负责将被依赖对象(LiSi)赋值给调用者的成员变量(user),
相当于调用者注入了它依赖的实例,这就是Spring的 依赖注入
当然,一般的小型项目中直接使用 new 创建对象即可,如果在工作中自己不习惯 IOC 而领导又非得让使用的IOC的时候,那就换个领导吧。
IOC和DI的关系
IOC 和 DI 的含义相同,是从不同角度描述的同一个概念。
AOP
如果你想详细了解面向切面编程,可以参考这篇文章:细说Spring——AOP详解
下面内容,考试相关。
AOP相关术语
- Aspect(切面):在实际应用中,切面通常是指封装的,用于横向插入系统功能的类。
- Joinpoint(连接点):Spring AOP中,连接点就是方法的调用。
- Pointcut(切入点):通常在程序中,切入点指的是类或方法名。
- Advice(通知/增强处理): 在切入点要执行的代码,是切面的具体实现。
- Target Object(目标对象):即增强对象。如果AOP框架采用动态的AOP实现,那么该对象就是一个被代理的对象。
- Proxy(代理): 将通知应用到目标对象之后,被动态创建的对象。
- Weaving(织入):将切面代码插入到目标对象上,生成代理对象的过程。
以下为个人理解:
结合现在很多网页的业务逻辑,对会对用户的登录状态做出一定的判断。
例如贴吧的一个逻辑,如图所示:
public boolean fun(HttpSession session){
if(session.getAttribute("loginUser")!= null){
return true;
}
return false;
}
在我们回复问题的时候就要对用户的状态进行判断,如果用户没有登录的话是不允许进行回复的。这个时候就可以引入切面。
板块C即为切面,☆即为连接点,fun即为切入点,fun方法为Advice。
我个人觉得可以用 intercepter 来帮助理解,如果使用 HandlerInterceptor 接口中的preHandle()方法,即可视为每次页面打开时自动增强。
动态代理
JDK动态代理通过 java.lang.reflect.Proxy实现:
jdkProxy.createProxy(你的对象); //没有对象建议先找个对象,之后才能动态代理
动态代理的对象必须实现一个或多个接口
CGLIB代理
可以用来处理没有实现接口的对象
cglibProxy.createProxy(你的对象); //仍然需要对象,不过对象不需要实现接口
Spring MVC
springmvc工作流程
结合图片,可总结如下:
- Spring MVC的前端控制器(DS)拦截用户向服务器发送的请求
- DS 调用处理器映射器(HM)
- HM 根据请求的 URL 找到对应的处理器,生成处理器对象和处理器拦截器(如果定义的有)并返回给 DS
- DS 通过返回的信息选择 处理器适配器(HA)
- HA 调用并执行 处理器(H),H即为 Controller 类( Controller 可以执行用户的请求,如添加购物车)
- Controller执行完毕后,返回一个 ModelAndView 对象(翻译即可知道内部结构)
- HA 把 ModelAndView 提交给 DS
- DS 根据 ModelAndView 选择合适的视图解析器(VR)
- VR 解析后,向 DS 返回具体的 View
- DS 将 View 渲染
- 浏览器页面显示
如果把整个过程比作一个笨笨的购物过程:
- 用户下单
- 客服询问中心各地是否有货
- 中心给出答复
- 客服根据答复前往仓库中心(选择距用户最近的仓库 A )
- 通知仓库A 发货
- 仓库 A 通知 仓库中心发货失败(因为某种原因)
- 仓库中心通知客服发货失败
- 客服向太极高手询问如何委婉告诉用户没货
- 太极高手给出答复
- 客服将发送短信(下单成功,365天内发货)
- 用户接受到短信
数据绑定
简单数据绑定
默认绑定
JAVA WEB中最常用的:
String id = request.getParameter("id");
绑定简单数据类型
通过 @RequestParam 注解实现
public Integer selectId(@RequestParam(value = "id " Integer id)){
return id;
}
绑定POJO类型
设置信息接收者
public class UserDTO{
User sender;
User receiver;
Message message;
/**
相关setter/getter;
**/
}
public void setreceiveUser(User receiver){
UserDTO userDTO = new UserDTO();
userDTO.setReceiver(receiver);
}
如出现中文乱码问题,在web.xml中添加编码内容即可。
绑定自定义
详情参考 J2EE企业级应用开发教程 201页。
复杂绑定
数组绑定
将表单中的复选框按钮如下操作:
<input name="ids" value="1" type="checkbox"> //value按需赋值即可
@PostMapping("/你的路径")
public String payOrders(Integer[] ids){
if(ids != null)
for(Integer id : ids){
//付款操作
}
else
//相关处理
return "success";
}
集合绑定
与数组绑定差不多,区别在于集合处理更复杂的数据类型
public class questionDTO{
private List<question> questions;
/**
相关setter/getter;
**/
}
@PostMapping("/你的路径")
public String modefyQuestions(List<question> questions){
if(questions != null)
for(questions q : questions){
//更改操作,设计q内部的id,content等内容
}
else
//相关处理
return "success";
}
SpringMVC中@Controller的作用及用法
用法:
@Controller
public class UserController{
@GetMapping("/path")
public void function(){
//相关操作
}
}
@Controller 标志了该类是一个控制器,使用注解就不用实现Controller接口
Spring 通过注解扫描可以识别控制器
如果扫描不到,配置相关扫描路径即可
Mybatis
如果使用Spring Boot,可以参考这篇文章 :Spring Boot 结合 Mybatis 对 MySQL 数据库操作
Mybaties框架的工作流程
- 读取MyBatis的配置文件 ——mybatis-config.xml
- 加载映射文件(userMapper.xml)
- 构造会话工厂(sqlSessionFactory)
- 构造会话对象(sqlSession)
- Executor执行器
- MappedStatement对象,与数据库交互
- 输入映射到 6(Map , List , String ,Integer , POJO类型)
- 从 6 输出映射(Map , List , String ,Integer , POJO类型)
动态SQL中有哪些元素及其用法
动态 sql 是什么? 看了下面的内容,你或许可以找到答案:
<if>
if 最好理解,比如搜索,如果搜索的内容不为空,那么就让其进行匹配
select * from question
<where> //可换为 where 1 = 1
<if test="keyValue!=null">
and title regexp #{keyValue}
</if>
</where>
order by view_count desc limit #{offSet},#{size}
如上搜索,在 首先对 keyValue 进行判断,如果 if 判定为真,那么就可以加入 if 中的判定条件对问题进行检索。
个人看法:如果使用这个sql进行判断的话,效率较低,空内容也发送到后台进行了检索,应在前段判断。