Java Listener監(jiān)聽器使用規(guī)范詳細(xì)介紹
1、什么是監(jiān)聽器以及監(jiān)聽器作用
①監(jiān)聽器是Servlet規(guī)范中的一員。就像Filter一樣。Filter也是Servlet規(guī)范中的一員。
②在Servlet中,所有的監(jiān)聽器接口都是以“Listener”結(jié)尾。
③監(jiān)聽器實(shí)際上是Servlet規(guī)范留給我們javaweb程序員的特殊時(shí)機(jī)。
④特殊的時(shí)刻如果想執(zhí)行這段代碼,你需要想到使用對(duì)應(yīng)的監(jiān)聽器。
2、Servlet規(guī)范中提供了哪些監(jiān)聽器
javax.servlet包下:
①ServletContextListener
②ServletContextAttributeListener
③ServletRequestListener
④ServletRequestAttributeListener
jakarta.servlet.http包下:
①HttpSessionListener
②HttpSessionAttributeListener
③HttpSessionBindingListener
④HttpSessionIdListener
⑤HttpSessionActivationListener
3、實(shí)現(xiàn)一個(gè)監(jiān)聽器的步驟
這里主要先講解熟悉的關(guān)于三個(gè)域?qū)ο蟮谋O(jiān)聽器:
ServletContext、ServletRequest、HttpSession
(1)以ServletContextListener為例
①第一步:編寫一個(gè)類實(shí)現(xiàn)ServletContextListener接口。并且實(shí)現(xiàn)里面的方法。
監(jiān)聽器中的方法不需要程序員手動(dòng)調(diào)用。是發(fā)生某個(gè)特殊事件之后被服務(wù)器調(diào)用。
// ServletContext對(duì)象被創(chuàng)建的時(shí)候調(diào)用。 void contextInitialized(ServletContextEvent event) // ServletContext對(duì)象被銷毀的時(shí)候調(diào)用 void contextDestroyed(ServletContextEvent event)
②第二步:在web.xml文件中對(duì)ServletContextListener進(jìn)行配置,如下:
當(dāng)然,第二步也可以不使用配置文件,也可以用注解,例如:@WebListener 即可。
<listener> <listener-class>com.bjpowernode.javaweb.servlet.MyServletContextListener</listener-class> </listener>
注意:所有監(jiān)聽器中的方法都是不需要javaweb程序員調(diào)用的,由服務(wù)器來(lái)負(fù)責(zé)調(diào)用。
什么時(shí)候被調(diào)用呢?當(dāng)某個(gè)特殊的事件發(fā)生(特殊的事件發(fā)生其實(shí)就是某個(gè)時(shí)機(jī)到了)之后,被web服務(wù)器自動(dòng)調(diào)用。
③服務(wù)器啟動(dòng)時(shí),ServletContext對(duì)象創(chuàng)建,contextInitialized方法執(zhí)行
服務(wù)器關(guān)閉時(shí),ServletContext對(duì)象銷毀,contextDestroyed方法執(zhí)行
package com.bjpowernode.javaweb.servlet; import javax.servlet.ServletContextEvent; import javax.servlet.ServletContextListener; /** * @Package:com.bjpowernode.javaweb.servlet * @Project:JavaWeb * @name:MyServletContextListener */ // ServletContextListener監(jiān)聽器主要監(jiān)聽的是:ServletContext對(duì)象的狀態(tài)。 public class MyServletContextListener implements ServletContextListener { // 服務(wù)器啟動(dòng)時(shí)間點(diǎn) /** * 監(jiān)聽器中的方法不需要程序員手動(dòng)調(diào)用。是發(fā)生某個(gè)特殊事件之后被服務(wù)器調(diào)用。 * @param sce */ @Override public void contextInitialized(ServletContextEvent sce) { // 服務(wù)器關(guān)閉時(shí)間點(diǎn) // 現(xiàn)在這個(gè)特殊的時(shí)刻寫代碼,你寫就是了。它會(huì)被服務(wù)器自動(dòng)調(diào)用。 // 這個(gè)方法是在ServletContext對(duì)象被創(chuàng)建的時(shí)候調(diào)用。 System.out.println("ServletContext對(duì)象創(chuàng)建了。"); } @Override public void contextDestroyed(ServletContextEvent sce) { // 現(xiàn)在這個(gè)特殊的時(shí)刻寫代碼,你寫就是了。它會(huì)被服務(wù)器自動(dòng)調(diào)用。 // 這個(gè)方法是在ServletContext對(duì)象被銷毀的時(shí)候調(diào)用。 System.out.println("ServletContext對(duì)象被銷毀了。"); } }
(2)以ServletRequestListener為例
④ServletRequest對(duì)象是一次請(qǐng)求創(chuàng)建一個(gè)request對(duì)象,所以服務(wù)器啟動(dòng)后:
只要發(fā)送一次請(qǐng)求就會(huì)調(diào)用requestInitialized方法,請(qǐng)求結(jié)束立刻會(huì)調(diào)用requestDestroyed
注:我們直接訪問(wèn)http://localhost:8080/servlet15/會(huì)報(bào)404錯(cuò)誤,因?yàn)槟J(rèn)會(huì)訪問(wèn)index.html,但是我們并沒(méi)有寫;就算如此也會(huì)發(fā)送出請(qǐng)求,執(zhí)行這個(gè)監(jiān)聽器。
package com.bjpowernode.javaweb.servlet; import javax.servlet.ServletContextEvent; import javax.servlet.ServletRequestEvent; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; /** * @Package:com.bjpowernode.javaweb.servlet * @Project:JavaWeb * @name:MyServletRequestListener */ @WebListener public class MyServletRequestListener implements ServletRequestListener { // request對(duì)象銷毀時(shí)間點(diǎn) @Override public void requestDestroyed(ServletRequestEvent sre) { System.out.println("request對(duì)象銷毀了"); } // request對(duì)象創(chuàng)建時(shí)間點(diǎn) @Override public void requestInitialized(ServletRequestEvent sre) { System.out.println("request對(duì)象初始化了"); } }
(3)以HttpSessionListener為例
⑤我們都知道在訪問(wèn)jsp時(shí),默認(rèn)會(huì)創(chuàng)建session對(duì)象(九大內(nèi)置對(duì)象);先編寫一個(gè)my.jsp;在訪問(wèn)my.jsp時(shí),會(huì)創(chuàng)建session對(duì)象,調(diào)用 sessionCreated方法;
當(dāng)退出系統(tǒng)時(shí),我們編寫銷毀session對(duì)象的方法,會(huì)調(diào)用sessionDestroyed方法。
<%@ page contentType="text/html;charset=UTF-8" %> <html> <head> <title>Title</title> </head> <body> my jsp page <a href="${pageContext.request.contextPath}/exit" rel="external nofollow" >退出系統(tǒng)</a> </body> </html>
根據(jù)/exit請(qǐng)求,編寫銷毀session對(duì)象的類
package com.bjpowernode.javaweb; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @Package:com.bjpowernode.javaweb * @Project:JavaWeb * @name:ExitServlet */ @WebServlet("/exit") public class ExitServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 獲取session對(duì)象 HttpSession session = request.getSession(false); if (session != null) { // 銷毀session session.invalidate(); } } }
(4)AttributeListener的使用
①我們知道對(duì)于域?qū)ο蠖加衧etAttribute、getAttribute、removeAttribute方法,分別可以向域中存數(shù)據(jù)、取數(shù)據(jù)、清除數(shù)據(jù);所以對(duì)于AttributeListener肯定是和這些處理域中數(shù)據(jù)有關(guān)。
②實(shí)際上對(duì)于ServletContextAttributeListener、ServletRequestAttributeListener 、HttpSessionAttributeListener這三個(gè)對(duì)象都有attributeAdded、attributeRemoved、attributeReplaced方法;表示:向域當(dāng)中存儲(chǔ)數(shù)據(jù)的時(shí)候調(diào)用、向域當(dāng)中刪除數(shù)據(jù)的時(shí)候調(diào)用、向域當(dāng)中替換數(shù)據(jù)的時(shí)候調(diào)用。
③這里以HttpSessionAttributeListener對(duì)象為例:
編寫HttpSessionAttributeListener監(jiān)聽器
package com.bjpowernode.javaweb.servlet; import javax.servlet.ServletContextAttributeListener; import javax.servlet.ServletRequestAttributeListener; import javax.servlet.ServletRequestListener; import javax.servlet.annotation.WebListener; import javax.servlet.http.HttpSessionActivationListener; import javax.servlet.http.HttpSessionAttributeListener; import javax.servlet.http.HttpSessionBindingEvent; /** * @Package:com.bjpowernode.javaweb.servlet * @Project:JavaWeb * @name:MyHttpSessionAttributeListener */ @WebListener public class MyHttpSessionAttributeListener implements HttpSessionAttributeListener { // 向session域當(dāng)中存儲(chǔ)數(shù)據(jù)的時(shí)候,以下方法被WEB服務(wù)器調(diào)用。 @Override public void attributeAdded(HttpSessionBindingEvent se) { System.out.println("session data add"); } // 將session域當(dāng)中存儲(chǔ)的數(shù)據(jù)刪除的時(shí)候,以下方法被WEB服務(wù)器調(diào)用。 @Override public void attributeRemoved(HttpSessionBindingEvent se) { System.out.println("session data remove"); } // session域當(dāng)中的某個(gè)數(shù)據(jù)被替換的時(shí)候,以下方法被WEB服務(wù)器調(diào)用。 @Override public void attributeReplaced(HttpSessionBindingEvent se) { System.out.println("session data replace"); } }
編寫Servlet類用來(lái)處理域中的數(shù)據(jù)
當(dāng)發(fā)送http://localhost:8080/servlet15/session/attribute/test就能觸發(fā)上面的監(jiān)聽器;
注意:調(diào)用getAttribute方法不會(huì)觸發(fā),只有setAttribute方法和removeAttribute方法才會(huì)觸發(fā)
package com.bjpowernode.javaweb; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; /** * @Package:com.bjpowernode.javaweb * @Project:JavaWeb * @name:HttpSessionAttributeServlet */ @WebServlet("/session/attribute/test") public class HttpSessionAttributeServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 獲取session對(duì)象 HttpSession session = request.getSession(); // 向session域中存儲(chǔ)數(shù)據(jù) session.setAttribute("user", "zhangsan"); // 替換,覆蓋上面的數(shù)據(jù) session.setAttribute("user", "lisi"); // 刪除 session.removeAttribute("user"); } }
4、HttpSessionBindingListener
(1)前面我們已經(jīng)講解了關(guān)于域?qū)ο蟮谋O(jiān)聽器,九個(gè)監(jiān)聽器中就已經(jīng)學(xué)習(xí)了6個(gè);接下來(lái)就先分析一下HttpSessionBindingListener;顧名思義就是關(guān)于數(shù)據(jù)綁定的!
(2)下面就通過(guò)一個(gè)例子來(lái)學(xué)習(xí)一下HttpSessionBindingListener監(jiān)聽器:
創(chuàng)建一個(gè)user1類實(shí)現(xiàn)監(jiān)聽器(不需要@WebListener注解),并重寫方法
創(chuàng)建一個(gè)user2類不實(shí)現(xiàn)監(jiān)聽器
對(duì)比當(dāng)數(shù)據(jù)放入放入域當(dāng)中,兩者會(huì)有什么區(qū)別:
①普通的user1類實(shí)現(xiàn)監(jiān)聽器,并重寫監(jiān)聽器中兩個(gè)方法
package com.bjpowernode.javaweb.bean; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; /** * 普通的java類。但是它實(shí)現(xiàn)了:HttpSessionBindingListener */ public class User1 implements HttpSessionBindingListener { @Override public void valueBound(HttpSessionBindingEvent event) { System.out.println("綁定數(shù)據(jù)"); } @Override public void valueUnbound(HttpSessionBindingEvent event) { System.out.println("解綁數(shù)據(jù)"); } private String usercode; private String username; private String password; public User1(String usercode, String username, String password) { this.usercode = usercode; this.username = username; this.password = password; } public User1() { } public String getUsercode() { return usercode; } public void setUsercode(String usercode) { this.usercode = usercode; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
②普通的user2類不實(shí)現(xiàn)監(jiān)聽器
package com.bjpowernode.javaweb.bean; /** * 普通的java類。 */ public class User2 { private String usercode; private String username; private String password; public User2() { } public User2(String usercode, String username, String password) { this.usercode = usercode; this.username = username; this.password = password; } public String getUsercode() { return usercode; } public void setUsercode(String usercode) { this.usercode = usercode; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
③編寫一個(gè)servlet類,把這兩種數(shù)據(jù)都存進(jìn)去
發(fā)現(xiàn)實(shí)現(xiàn)監(jiān)聽器的user1類會(huì)觸發(fā)綁定事件!
package com.bjpowernode.javaweb.servlet; import com.bjpowernode.javaweb.bean.User1; import com.bjpowernode.javaweb.bean.User2; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.io.IOException; @WebServlet("/session/bind") public class HttpSessionBindingListenerServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 獲取session對(duì)象 HttpSession session = request.getSession(); // 準(zhǔn)備兩個(gè)對(duì)象:User1 User2 User1 user1 = new User1("111", "zhangsan", "123"); User2 user2 = new User2("111", "zhangsan", "123"); // 將user1存儲(chǔ)到session域 session.setAttribute("user1", user1); // 將user2存儲(chǔ)到session域 session.setAttribute("user2", user2); } }
(3)區(qū)分:HttpSessionAttributeListener 和HttpSessionBindingListener
??HttpSessionAttributeListener監(jiān)聽器
①該監(jiān)聽器是需要使用@WebListener注解進(jìn)行標(biāo)注的(或者使用web.xml文件進(jìn)行配置)
②該監(jiān)聽器監(jiān)聽的是session域中數(shù)據(jù)的變化。只要數(shù)據(jù)變化,則執(zhí)行相應(yīng)的方法;主要監(jiān)測(cè)點(diǎn)在session域?qū)ο笊稀?/p>
③監(jiān)聽的是session域,只要把數(shù)據(jù)放入session域就進(jìn)行監(jiān)聽!
??HttpSessionBindingListener監(jiān)聽器
①該監(jiān)聽器是不需要使用@WebListener進(jìn)行標(biāo)注,類直接實(shí)現(xiàn)即可。
②假設(shè)User類實(shí)現(xiàn)了該監(jiān)聽器,那么User對(duì)象在被放入session的時(shí)候觸發(fā)bind事件,User對(duì)象從session中刪除的時(shí)候,觸發(fā)unbind事件。
③假設(shè)Customer類沒(méi)有實(shí)現(xiàn)該監(jiān)聽器,那么Customer對(duì)象放入session或者從session刪除的時(shí)候,不會(huì)觸發(fā)bind和unbind事件。
④監(jiān)聽的是普通的java對(duì)象,那個(gè)類實(shí)現(xiàn)了這個(gè)監(jiān)聽器,就監(jiān)聽那個(gè)類!
??總結(jié):
①對(duì)于HttpSessionAttributeListener監(jiān)聽的是任何種類的對(duì)象,只要放入session域當(dāng)中就可以;上述user1和user2都可以觸發(fā)!
②對(duì)于HttpSessionBindingListener監(jiān)聽的是特殊的對(duì)象,只有實(shí)現(xiàn)HttpSessionBindingListener接口的才可以;上述只有user1才能觸發(fā)!
(4)那么這兩個(gè)監(jiān)聽器有什么用呢?
我們通過(guò)一個(gè)簡(jiǎn)單的業(yè)務(wù)需求了解一下:
業(yè)務(wù)1:編寫一個(gè)功能,記錄該網(wǎng)站實(shí)時(shí)的在線用戶的個(gè)數(shù)
我們可以通過(guò)服務(wù)器端有沒(méi)有分配session對(duì)象,因?yàn)橐粋€(gè)session代表了一個(gè)用戶。有一個(gè)session就代表有一個(gè)用戶。如果你采用這種邏輯去實(shí)現(xiàn)的話,session有多少個(gè),在線用戶就有多少個(gè)。這種方式的話:HttpSessionListener夠用了。session對(duì)象只要新建,則count++,然后將count存儲(chǔ)到ServletContext域當(dāng)中,在頁(yè)面展示在線人數(shù)即可!
業(yè)務(wù)2:只統(tǒng)計(jì)登錄的用戶的在線數(shù)量
用戶登錄的標(biāo)志是什么?session中曾經(jīng)存儲(chǔ)過(guò)User類型的對(duì)象。那么這個(gè)時(shí)候可以讓User類型的對(duì)象實(shí)現(xiàn)HttpSessionBindingListener監(jiān)聽器,只要User類型對(duì)象存儲(chǔ)到session域中,則count++,然后將count++存儲(chǔ)到ServletContext對(duì)象中。頁(yè)面展示在線人數(shù)即可。
5、HttpSessionIdListener&HttpSessionActivationListener
這兩個(gè)監(jiān)聽器不常用,這里只簡(jiǎn)單了解即可:
(1)HttpSessionIdListener:session的id發(fā)生改變的時(shí)候,監(jiān)聽器中的唯一一個(gè)方法就會(huì)被調(diào)用。
(2)HttpSessionActivationListener:監(jiān)聽session對(duì)象的鈍化和活化的。
①鈍化:session對(duì)象從內(nèi)存存儲(chǔ)到硬盤文件。
②活化:從硬盤文件把session恢復(fù)到內(nèi)存。
6、使用監(jiān)聽器統(tǒng)計(jì)網(wǎng)站在線人數(shù)
實(shí)現(xiàn)oa項(xiàng)目中當(dāng)前登錄在線的人數(shù)!
(1)什么代表著用戶登錄了?
??session.setAttribute("user", userObj); User類型的對(duì)象只要往session中存儲(chǔ)過(guò),表示有新用戶登錄。
(2)什么代表著用戶退出了?
??session.removeAttribute("user"); User類型的對(duì)象從session域中移除了。
??或者有可能是session銷毀了。(session超時(shí)) 。
(3)思考:我們要先思考一下尋訪到什么域里面?
統(tǒng)計(jì)這個(gè)項(xiàng)目當(dāng)匯總的登錄在線人數(shù),一個(gè)人一個(gè)的(session)以下的域肯定都不行,所以只能使用application域(ServletContext)。
①編寫User類實(shí)現(xiàn)監(jiān)聽器的接口;然后修改關(guān)于所有session.getAttribute的代碼
package com.bjpowernode.oa.bean; import javax.servlet.ServletContext; import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; /** * @Package:com.bjpowernode.oa.bean * @Project:JavaWeb * @name:User */ public class User implements HttpSessionBindingListener { // 重寫兩個(gè)方法 @Override public void valueBound(HttpSessionBindingEvent event) { // 用戶登錄了 // 相當(dāng)于User類型的對(duì)象向session域當(dāng)中存放 // 獲取application域?qū)ο? // event.getSession()獲取到session;在調(diào)用getServletContext()獲取到域?qū)ο? ServletContext application = event.getSession().getServletContext(); // 獲取到在線人數(shù) Object onlioncount = application.getAttribute("onlioncount"); // 第一個(gè)用戶登錄,里面什么都沒(méi)有,返回的是一個(gè)null if (onlioncount == null) { application.setAttribute("onlioncount",1); }else { // 直接 onlioncount++有問(wèn)題,前面是Object類型,強(qiáng)轉(zhuǎn) Integer count = (Integer)onlioncount; count++; // 在存入域當(dāng)中 application.setAttribute("onlioncount",count); } } @Override public void valueUnbound(HttpSessionBindingEvent event) { // 用戶退出了 // 相當(dāng)于User類型的對(duì)象向session域當(dāng)中刪除 // 獲取application域?qū)ο? ServletContext application = event.getSession().getServletContext(); // 獲取域當(dāng)中的數(shù)據(jù),肯定不是空 Integer onlioncount = (Integer) application.getAttribute("onlioncount"); onlioncount--; // 在存入域當(dāng)中 application.setAttribute("onlioncount",onlioncount); } // 定義屬性 private String username; private String password; // 構(gòu)造方法 public User() { } public User(String username, String password) { this.username = username; this.password = password; } // setter and getter public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } }
②修改UserServlet類和WelcomeServlet
// 把用戶名放進(jìn)session session.setAttribute("username",username); // 改為這樣存 User user = new User(username, password); session.setAttribute("user",user);
③修改過(guò)濾器LoginFilter
if("/index.jsp".equals(servletPath) || "/welcome".equals(servletPath) || "/dept/login".equals(servletPath) || "/dept/exit".equals(servletPath) || (session != null && session.getAttribute("username") != null)){ // username改為user,因?yàn)榍懊娲鎯?chǔ)的名字變了 if("/index.jsp".equals(servletPath) || "/welcome".equals(servletPath) || "/dept/login".equals(servletPath) || "/dept/exit".equals(servletPath) || (session != null && session.getAttribute("user") != null)){
④修改list.jsp頁(yè)面
<h3>歡迎${username}登錄</h3> <!--修改為--> <h3>歡迎${user.username}登錄,在線人數(shù)${onlioncount}人</h3>
⑤最終達(dá)到的效果
假如開了兩個(gè)瀏覽器,登錄了兩次
點(diǎn)擊退出登錄,刷新另一個(gè)瀏覽器的頁(yè)面
到此這篇關(guān)于Java Listener監(jiān)聽器使用規(guī)范詳細(xì)介紹的文章就介紹到這了,更多相關(guān)Java Listener監(jiān)聽器內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
java?LockSupport實(shí)現(xiàn)原理示例解析
這篇文章主要為大家介紹了java?LockSupport實(shí)現(xiàn)原理示例解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-01-01SpringBoot 如何根據(jù)不同profile選擇不同配置
這篇文章主要介紹了SpringBoot 如何根據(jù)不同profile選擇不同配置的操作方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08Spring?Boot?+?EasyExcel實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入導(dǎo)出
這篇文章主要介紹了Spring?Boot+EasyExcel實(shí)現(xiàn)數(shù)據(jù)導(dǎo)入導(dǎo)出,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的朋友可以參考一下2022-08-08教你在?Java?中實(shí)現(xiàn)?Dijkstra?最短路算法的方法
這篇文章主要教你在?Java?中實(shí)現(xiàn)?Dijkstra?最短路算法的方法,在實(shí)現(xiàn)最短路算法之前需要先實(shí)現(xiàn)帶權(quán)有向圖,文章中給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-04-04詳解SSM框架下結(jié)合log4j、slf4j打印日志
本篇文章主要介紹了詳解SSM框架下結(jié)合log4j、slf4j打印日志,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-11-11一文詳解Redisson分布式鎖底層實(shí)現(xiàn)原理
這篇文章主要詳細(xì)介紹了Redisson分布式鎖底層實(shí)現(xiàn)原理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-07-07Struts2中ognl遍歷數(shù)組,list和map方法詳解
這篇文章主要介紹了Struts2中ognl遍歷數(shù)組,list和map方法詳解,需要的朋友可以參考下。2017-09-09Mybatis-Plus使用updateById()、update()將字段更新為null
本文主要介紹了Mybatis-Plus使用updateById()、update()將字段更新為null,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08