2019独角兽企业重金招聘Python工程师标准>>>

1:OSIV模式 - Open Session In View

2:让项目中的所有代码成为单例。

1:在项目中一个Service调用多个Dao的情况下

解决方案1:

将所有代码:

1:传递同一个Connection给每一个Dao。

2:在Serice里面控制事务。即try..catch..fnally。

上面的问题:

1:让Connection这个连接对象暴露在了Service层。

2:在项目中,有N个Service,在每一个Service中都写try..catch..finally代码量太大,重复太多。

3:给每一个dao需要多传递一个参数。即Connection参数。

解决方案2:

在Java中有一个类ThreadLocal - 维护线程局部的变量。

此类看上去像是线程,但是本质是容器即是一个HashMap。它的结构是:Map<Thead,Object>即,以线程为key,以任意的对象为value保存值。

1:思想

修改DSUtils类,维护一个唯一的线程局部的对象。

// 声明ThreadLocal

private static ThreadLocal<Connection> tl;

static {

tl = new ThreadLocal<>();

dataSource = new ComboPooledDataSource();

}

public static DataSource getDataSource() {

return dataSource;

}

public static Connection getConnection() {

Connection con = tl.get();// 先从tl获取连接,查看当前线程是否保存过连接

if (con == null) {

try {

con = dataSource.getConnection();

// 放到tl

tl.set(con);

} catch (Exception e) {

throw new RuntimeException(e);

}

}

return con;

}

2:添加过虑器 /stud

package cn.filter;

import java.io.IOException;

import java.sql.Connection;

import java.sql.SQLException;

import javax.servlet.Filter;

import javax.servlet.FilterChain;

import javax.servlet.FilterConfig;

import javax.servlet.ServletException;

import javax.servlet.ServletRequest;

import javax.servlet.ServletResponse;

import javax.servlet.annotation.WebFilter;

import cn.meeting.utils.DSUtils;

@WebFilter(urlPatterns = "/stud")

public class TxFilter implements Filter {

@Override

public void init(FilterConfig filterConfig) throws ServletException {

}

@Override

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)

throws IOException, ServletException {

// 1:获取

Connection con = DSUtils.getConnection();

try {

con.setAutoCommit(false);

chain.doFilter(request, response);

con.commit();

} catch (Exception e) {

try {

con.rollback();

} catch (SQLException e1) {

e1.printStackTrace();

}

throw new RuntimeException(e);

} finally {

try {

con.close();

} catch (SQLException e) {

e.printStackTrace();

}

DSUtils.remove();

}

}

@Override

public void destroy() {

// TODO Auto-generated method stub

}

}

OSIV模式,将事务的控制做为Filter层。

上面的问题是:

事务太靠前了。在过虑器层。

如果在调用servlet时,事务已经开始。但是在servlet中出错了,即还没有service/dao呢。

转发时,如果不是SQL异常也回滚。

可以通过catch只对sql异常进行rollback;

解决方案3:

可以使用代理代理所有Service。

package cn.utils;

import java.lang.reflect.InvocationHandler;

import java.lang.reflect.Method;

import java.lang.reflect.Proxy;

import java.sql.Connection;

import cn.meeting.utils.DSUtils;

public class TxProxy {

public static Object newProxy(final Object src) {

Object proxyObj = Proxy.newProxyInstance(TxProxy.class.getClassLoader(), src.getClass().getInterfaces(),

new InvocationHandler() {

@Override

public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

Connection con = DSUtils.getConnection();

System.err.println("获取连接.." + con);

Object returnValue = null;

try {

System.err.println("开始事务");

con.setAutoCommit(false);

returnValue = method.invoke(src, args);// 放行

System.err.println("提交");

con.commit();

} catch (Exception e) {

System.err.println("出错了回滚");

con.rollback();

throw e;

} finally {

con.close();

DSUtils.remove();

}

return returnValue;

}

});

return proxyObj;

}

}

@WebServlet("/stud")

public class StudServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

private IStudService service = (IStudService) TxProxy.newProxy(new StudServlet());

2:ThreadLocal

java.lang
类 ThreadLocal<T>

java.lang.Object

java.lang.ThreadLocal<T>

直接已知子类:

InheritableThreadLocal

public class ThreadLocal<T>

extends Object

该类提供了线程局部 (thread-local) 变量

变量:

三种: 1:局部,2:成员, 3:线程局部。

1:用ThreadLocal保存数据

@Test

public void test1() {

// 1:实例化容器Map<Thread,T>

ThreadLocal<Object> tl = new ThreadLocal<>();

tl.set("Jack");

// 获取里面的值

Object val = tl.get();

System.err.println(val);

}

// 1:实例化容器Map<Thread,T>

ThreadLocal<Object> tl = new ThreadLocal<>();//Map<Thread,T>

tl.set("Jack");//map.put(Thread.currentThread(),"Jack");

tl.set("Mary");//map.put(Thread.currentThread(),"Mary"); //后面覆盖前面的值

// 获取里面的值

Object val = tl.get();//Mary

System.err.println(val);

2:单例化ThreadLocal

保存当前某个线程的局部的变量-线程局部的变量。

在一个项目中,只要有一个TL对象,就可以为所有线程提供服务。

@Test

public void teest1() throws Exception{

Object obj1 = TLUtils.random();

System.err.println("1:"+obj1);

abc();

new Thread(){

public void run() {

Object obj1 = TLUtils.random();

System.err.println("3:"+obj1);

abc();

};

}.start();

System.in.read();

}

public void abc(){

Object obj1 = TLUtils.random();

System.err.println(Thread.currentThread().getName()+" 2:"+obj1);

}

}

3:自己开发ThreadLocal对象

思想:

自己开发一个集合Map<Thred,Object>

public class TLUtils2 {

private static Map<Thread, Object> tl;

static {

tl = new HashMap<Thread, Object>();

}

public static Object get() {

Object obj = tl.get(Thread.currentThread());

if (obj == null) {

obj = new Random().nextInt(100);

tl.put(Thread.currentThread(), obj);

}

return obj;

}

}

上面的类的问题:

1:做为HashMap,即集合类,只看到了不断的获取数据,和不断的保存数据

没有看到从map中删除数据。

则Map的中的值越来越多。最后总是会造成对象太多而崩溃。

2:所以,当某个对象不在被使用以后,应该及时清理掉。

在ThreadLocal中是如何清理的:

void

remove() 
          移除此线程局部变量当前线程的值。

3:所以,上面的自己开发的线程局部,也必须要提供一个方法,用于删除

public class TLUtils2 {

private static Map<Thread, Object> tl;

static {

tl = new HashMap<Thread, Object>();

}

public static Object get() {

Object obj = tl.get(Thread.currentThread());

if (obj == null) {

obj = new Random().nextInt(100);

tl.put(Thread.currentThread(), obj);

}

return obj;

}

public static void remove(){

tl.remove(Thread.currentThread());

}

}

 

上面的问题是:

   用户必须要显式的调用remove才可以。

 

 

2.2、对象的引用

对象的引用为分为四种:

强引用

Person p = new Person();

此时p变量,new Person()叫对象,此时 new Peson这个对象被 p这个变量强引用。

在Java代码中, 如果内存不够了则 GC会回收内存。但是如果对象有强引用。但是内存又不够用了,JVM直接崩溃也不会回收强引用的内存。

如果内存不够了,则会回收这个内存。

如果内存不够了,则会回收这个内存。放到回收队列。

内存无论是否足够,则直接回收这个内存。

java.lang.ref
类 WeakReference<T>

java.lang.Object

java.lang.ref.Reference<T>

java.lang.ref.WeakReference<T>

public class WeakReference<T>

extends Reference<T>

弱引用对象,它们并不禁止其指示对象变得可终结,并被终结,然后被回收。弱引用最常用于实现规范化的映射。

public class Demo02_Weak {

@Test

public void test1(){

WeakReference<Dog> weak = new WeakReference<Dog>(new Dog());

//从引用里面获取这个对象

System.gc();

Dog dog = weak.get();

System.err.println("程序执行完成了:"+dog);

}

}

class Dog {

protected void finalize() {

System.err.println("被回收了 :"+this);

}

}

3:ajax

Asynchronized Javascrpt And XML - 异步的JS与XML/JSON文件。

功能:

异步的请求数据。浏览器开线程向后台发送请求。

页面的局部刷新。

组成部分:

1:XMLHttpRequest对象 脚本对象 核心对象,用于发送get/post请求。

2:XML文件,向服务器发送XML数据。

3:CSS 控制显示的样式。

4:JS 用于控制XHR对象发送请求。

1:如何创建XHR对象

<html>

<script type="text/javascript">

//1:声明xhr对象

var xhr = null;

//2:判断是否可以通过new的方式来创建xhr对象

//IE9以下的版本使用new ActiveXObject的方式来创建

//其他的浏览器都是通过new XMLHttpRequest的方式来创建

if(window.XMLHttpRequest){//IE10,FF,Chome,

xhr  = new XMLHttpRequest();

console.log("IE10,ff,chrome");

}else{

xhr = new ActiveXObject("Microsoft.XMLHttp");

console.log("<IE9");

}

alert(xhr);

</script>

</html>

2:发送请示到后台,获取返回的字符串数据

readyState

0 (未初始化)

对象已建立,但是尚未初始化(尚未调用open方法)

1 (初始化)

对象已建立,尚未调用send方法

2 (发送数据)

send方法已调用,但是当前的状态及http头未知

3 (数据传送中)

已接收部分数据,因为响应及http头不全,这时通过responseBody和responseText获取部分数据会出现错误,

4 (完成)

数据接收完毕,此时可以通过通过responseBody和responseText获取完整的回应数据

function _get() {

//1:声明访问的地址

var url = "/20160515/random";

//2:设置如何访问这个url

xhr.open("GET", url, true);//默认值就是异步

//3:注册服务器成功以后的回调函数

//

xhr.onreadystatechange = function() {

if(xhr.readyState==4){//判断是否接收到了数据

//判断服务器的状态

if(xhr.status==200){

//如果数据成功,就返回

var txt = xhr.responseText;

document.getElementsByName("name")[0].value=txt;

}else{

alert("失败:"+xhr.status);

}

}

};

//4:开始请求数据

xhr.send();

@WebServlet("/random")

public class RandomServlet extends HttpServlet {

private static final long serialVersionUID = 1L;

protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

System.err.println("请示过来的");

Random r = new Random();

int a = r.nextInt(100);

//输出文本

response.setContentType("text/plain;charset=UTF-8");

response.getWriter().print(a);

}

}

转载于:https://my.oschina.net/dtz/blog/679195

ThreadLocal_OSIV模式_FIlter_Web ajax相关推荐

  1. Asp.net中的AJAX学习记录之一 AJAX技术的崛起与Asp.net AJAX的诞生

      最近开始学习Asp.net中的AJAX,可能我的高手朋友们会说:"走还不稳呢!怎么就想学跑了?"呵呵!主要是我在做项目中体会到AJAX真的是很好的一门技术,应该好好的学习一下, ...

  2. ASP.NET Ajax编程技术学习

    前言:从现在开始我们学习ASP.NET AJAX,Ajax技术现在应用非常广泛,只要我们上的一些大型网站,都用到了这个技术,AJAX最终解释的意思是:实现网页的无刷新效果,使网页显示出更美好的页面,使 ...

  3. java多线程系列13 设计模式 Future 模式

    Future 模式 类似于ajax请求  页面异步的进行后台请求 用户无需等待请求的结果 就可以继续浏览或者操作 核心就是:去除了主函数的等待时间,并使得原本需要等待的时间段可以用于处理其他业务逻辑 ...

  4. AJAX入门——工作原理

    理解同步交互和异步交互 举个例子:普通B/S模式(同步)       AJAX技术(异步)        *  同步: 提交请求->等待服务器处理->处理完毕返回  这个期间客户端浏览器不 ...

  5. Java基础——Ajax(一)

    学习之前举一个简单的小栗子,让我们简单了解一下Ajax的应用与好处.一般网站都会有自己的数据库,用来单独存储用户的个人信息,平时我们在注册账号的时候会遇到信息输入的页面,假设第一个输入信息是用户名的填 ...

  6. ajax技术的实质是什么意思,什么是Ajax?Ajax的原理是什么?Ajax的核心技术是什么?Ajax的优缺点是什么?...

    Ajax是一种无需重新加载整个网页,能够更新部分网页的技术.Asynchronous JavaScript and XML的缩写,是JavaScript.XML.CSS.DOM等多个技术的组合. Aj ...

  7. seo如何和ajax和睦相处

    在当今电子商务形式下,SEO(搜索引擎优化)为网站之间的竞争提供了可观的前景,而替代传统的Web交 互模式的Ajax技术,以无刷新页面的高效率交互方式同样为网站的营运带来了效益,但是SEO与Ajax技 ...

  8. ajax对于seo的影响

    在当今电子商务形式下,SEO(搜索引擎优化)为网站之间的竞争提供了可观的前景,而替代传统的Web交 互模式的Ajax技术,以无刷新页面的高效率交互方式同样为网站的营运带来了效益,但是SEO与Ajax技 ...

  9. AJAX技术对于SEO的影响

    李斌  高春燕 (陕西青年职业学院 计算机科学系,陕西 西安 710068)   摘  要  在当今电子商务形式下,SEO(搜索引擎优化)为网站之间的竞争提供了可观的前景,而替代传统的Web交互模式的 ...

最新文章

  1. 视频会议已成为武汉新趋势,在未来,线上会议有机会成为「主流」会议模式吗?
  2. 画五角星中间没有填充_一日一禅(十二)——趣味禅绕画之器物篇
  3. 转:中国学生为什么学不好计算机 谭浩强
  4. java final 变量 回收_在Java中将final用于变量会改善垃圾回收吗?
  5. (转)使用vsphere client 克隆虚拟机
  6. c语言两种加法,两个超长正整数的加法
  7. hibernate by example 排除某些列
  8. Android魔法(第四弹)—— 一步步实现百叶窗效果
  9. 网络虚拟化技术为双11提供灵动网络
  10. Silverlight智能表单(3)之XML存储
  11. android动画能超过父容器吗,Android中你不得不知道的动画知识 (一)
  12. Kernel panic - not syncing:Attempted to kill...
  13. 奇安信代码安全实验室帮助微软修复多个高危漏洞,获官方致谢
  14. EDUCoder编程练习题解(一维数组和二维数组)
  15. 【原】GitHub使用教程
  16. Hive里的分区、分桶、视图和索引再谈
  17. jni回调android子线程,如何在android的jni线程中实现回调
  18. S7-PLCSIM Advance ,解决 Error Code: -30,LicenseNotFound问题解决和期限21天限制的问题,对版本V1.0 V2.0 V3.0有效
  19. 飞冰 前端开发的一些坑
  20. 自媒体怎么赚钱?新手小白日入600+

热门文章

  1. 数据结构与算法笔记(九)—— 希尔排序
  2. Android监听后台状态,退出即杀死并显示退出提示框
  3. python网络编程案例_Python 网络编程_python网络编程基础_python高级编程
  4. ROS知识[14]:安装ubuntu 18.04和eclipse+CDT(installer)
  5. win10安装ensp启动40_acer e5-475g笔记本如何安装win10系统【图文教程】
  6. linux数据库都备份什么,Linux运维学习之数据库备份与恢复
  7. CEDD(Color and Edge Directivity Descriptor)学习篇
  8. 第四天2017/03/31(下午1:结构体、数组)
  9. 【自动驾驶】33.【图像坐标系】 到 【像素坐标系】 的度量单位变换、【英寸】、【感光芯片】
  10. 学习鸟哥的Linux私房菜笔记(2)——基础指令