日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ThreadLocal_OSIV模式_FIlter_Web ajax

發布時間:2025/3/21 编程问答 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ThreadLocal_OSIV模式_FIlter_Web ajax 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

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的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。