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的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JavaScript权威设计--事件冒泡
- 下一篇: shiro自定义Realm