Java 代理(Proxy)的原理及應(yīng)用
一、代理的概念
動態(tài)代理技術(shù)是整個java技術(shù)中最重要的一個技術(shù),它是學(xué)習(xí)java框架的基礎(chǔ),不會動態(tài)代理技術(shù),那么在學(xué)習(xí)Spring這些框架時是學(xué)不明白的。
動態(tài)代理技術(shù)就是用來產(chǎn)生一個對象的代理對象的。在開發(fā)中為什么需要為一個對象產(chǎn)生代理對象呢?
舉一個現(xiàn)實生活中的例子:歌星或者明星都有一個自己的經(jīng)紀(jì)人,這個經(jīng)紀(jì)人就是他們的代理人,當(dāng)我們需要找明星表演時,不能直接找到該明星,只能是找明星的代理人。比如劉德華在現(xiàn)實生活中非常有名,會唱歌,會跳舞,會拍戲,劉德華在沒有出名之前,我們可以直接找他唱歌,跳舞,拍戲,劉德華出名之后,他干的第一件事就是找一個經(jīng)紀(jì)人,這個經(jīng)紀(jì)人就是劉德華的代理人(代理),當(dāng)我們需要找劉德華表演時,不能直接找到劉德華了(劉德華說,你找我代理人商談具體事宜吧!),只能是找劉德華的代理人,因此劉德華這個代理人存在的價值就是攔截我們對劉德華的直接訪問!
這個現(xiàn)實中的例子和我們在開發(fā)中是一樣的,我們在開發(fā)中之所以要產(chǎn)生一個對象的代理對象,主要用于攔截對真實業(yè)務(wù)對象的訪問。那么代理對象應(yīng)該具有什么方法呢?代理對象應(yīng)該具有和目標(biāo)對象相同的方法
所以在這里明確代理對象的兩個概念:
1、代理對象存在的價值主要用于攔截對真實業(yè)務(wù)對象的訪問。
2、代理對象應(yīng)該具有和目標(biāo)對象(真實業(yè)務(wù)對象)相同的方法。劉德華(真實業(yè)務(wù)對象)會唱歌,會跳舞,會拍戲,我們現(xiàn)在不能直接找他唱歌,跳舞,拍戲了,只能找他的代理人(代理對象)唱歌,跳舞,拍戲,一個人要想成為劉德華的代理人,那么他必須具有和劉德華一樣的行為(會唱歌,會跳舞,會拍戲),劉德華有什么方法,他(代理人)就要有什么方法,我們找劉德華的代理人唱歌,跳舞,拍戲,但是代理人不是真的懂得唱歌,跳舞,拍戲的,真正懂得唱歌,跳舞,拍戲的是劉德華,在現(xiàn)實中的例子就是我們要找劉德華唱歌,跳舞,拍戲,那么只能先找他的經(jīng)紀(jì)人,交錢給他的經(jīng)紀(jì)人,然后經(jīng)紀(jì)人再讓劉德華去唱歌,跳舞,拍戲。
二、java中的代理
2.1、"java.lang.reflect.Proxy"類介紹
現(xiàn)在要生成某一個對象的代理對象,這個代理對象通常也要編寫一個類來生成,所以首先要編寫用于生成代理對象的類。在java中如何用程序去生成一個對象的代理對象呢,java在JDK1.5之后提供了一個"java.lang.reflect.Proxy"類,通過"Proxy"類提供的一個newProxyInstance方法用來創(chuàng)建一個對象的代理對象,如下所示:
static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
newProxyInstance方法用來返回一個代理對象,這個方法總共有3個參數(shù),ClassLoader loader用來指明生成代理對象使用哪個類裝載器,Class<?>[] interfaces用來指明生成哪個對象的代理對象,通過接口指定,InvocationHandler h用來指明產(chǎn)生的這個代理對象要做什么事情。所以我們只需要調(diào)用newProxyInstance方法就可以得到某一個對象的代理對象了。
2.2、編寫生成代理對象的類
在java中規(guī)定,要想產(chǎn)生一個對象的代理對象,那么這個對象必須要有一個接口,所以我們第一步就是設(shè)計這個對象的接口,在接口中定義這個對象所具有的行為(方法)
1、定義對象的行為接口
package cn.gacl.proxy;
/**
* @ClassName: Person
* @Description: 定義對象的行為
* @author: 孤傲蒼狼
* @date: 2014-9-14 下午9:44:22
*
*/
public interface Person {
/**
* @Method: sing
* @Description: 唱歌
* @Anthor:孤傲蒼狼
*
* @param name
* @return
*/
String sing(String name);
/**
* @Method: sing
* @Description: 跳舞
* @Anthor:孤傲蒼狼
*
* @param name
* @return
*/
String dance(String name);
}
2、定義目標(biāo)業(yè)務(wù)對象類
package cn.gacl.proxy;
/**
* @ClassName: LiuDeHua
* @Description: 劉德華實現(xiàn)Person接口,那么劉德華會唱歌和跳舞了
* @author: 孤傲蒼狼
* @date: 2014-9-14 下午9:22:24
*
*/
public class LiuDeHua implements Person {
public String sing(String name){
System.out.println("劉德華唱"+name+"歌!!");
return "歌唱完了,謝謝大家!";
}
public String dance(String name){
System.out.println("劉德華跳"+name+"舞?。?);
return "舞跳完了,多謝各位觀眾!";
}
}
3、創(chuàng)建生成代理對象的代理類
package cn.gacl.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* @ClassName: LiuDeHuaProxy
* @Description: 這個代理類負(fù)責(zé)生成劉德華的代理人
* @author: 孤傲蒼狼
* @date: 2014-9-14 下午9:50:02
*
*/
public class LiuDeHuaProxy {
//設(shè)計一個類變量記住代理類要代理的目標(biāo)對象
private Person ldh = new LiuDeHua();
/**
* 設(shè)計一個方法生成代理對象
* @Method: getProxy
* @Description: 這個方法返回劉德華的代理對象:Person person = LiuDeHuaProxy.getProxy();//得到一個代理對象
* @Anthor:孤傲蒼狼
*
* @return 某個對象的代理對象
*/
public Person getProxy() {
//使用Proxy.newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)返回某個對象的代理對象
return (Person) Proxy.newProxyInstance(LiuDeHuaProxy.class
.getClassLoader(), ldh.getClass().getInterfaces(),
new InvocationHandler() {
/**
* InvocationHandler接口只定義了一個invoke方法,因此對于這樣的接口,我們不用單獨去定義一個類來實現(xiàn)該接口,
* 而是直接使用一個匿名內(nèi)部類來實現(xiàn)該接口,new InvocationHandler() {}就是針對InvocationHandler接口的匿名實現(xiàn)類
*/
/**
* 在invoke方法編碼指定返回的代理對象干的工作
* proxy : 把代理對象自己傳遞進來
* method:把代理對象當(dāng)前調(diào)用的方法傳遞進來
* args:把方法參數(shù)傳遞進來
*
* 當(dāng)調(diào)用代理對象的person.sing("冰雨");或者 person.dance("江南style");方法時,
* 實際上執(zhí)行的都是invoke方法里面的代碼,
* 因此我們可以在invoke方法中使用method.getName()就可以知道當(dāng)前調(diào)用的是代理對象的哪個方法
*/
@Override
public Object invoke(Object proxy, Method method,
Object[] args) throws Throwable {
//如果調(diào)用的是代理對象的sing方法
if (method.getName().equals("sing")) {
System.out.println("我是他的經(jīng)紀(jì)人,要找他唱歌得先給十萬塊錢??!");
//已經(jīng)給錢了,經(jīng)紀(jì)人自己不會唱歌,就只能找劉德華去唱歌!
return method.invoke(ldh, args); //代理對象調(diào)用真實目標(biāo)對象的sing方法去處理用戶請求
}
//如果調(diào)用的是代理對象的dance方法
if (method.getName().equals("dance")) {
System.out.println("我是他的經(jīng)紀(jì)人,要找他跳舞得先給二十萬塊錢!!");
//已經(jīng)給錢了,經(jīng)紀(jì)人自己不會唱歌,就只能找劉德華去跳舞!
return method.invoke(ldh, args);//代理對象調(diào)用真實目標(biāo)對象的dance方法去處理用戶請求
}
return null;
}
});
}
}
測試代碼:
package cn.gacl.proxy;
public class ProxyTest {
public static void main(String[] args) {
LiuDeHuaProxy proxy = new LiuDeHuaProxy();
//獲得代理對象
Person p = proxy.getProxy();
//調(diào)用代理對象的sing方法
String retValue = p.sing("冰雨");
System.out.println(retValue);
//調(diào)用代理對象的dance方法
String value = p.dance("江南style");
System.out.println(value);
}
}
運行結(jié)果如下:

Proxy類負(fù)責(zé)創(chuàng)建代理對象時,如果指定了handler(處理器),那么不管用戶調(diào)用代理對象的什么方法,該方法都是調(diào)用處理器的invoke方法。
由于invoke方法被調(diào)用需要三個參數(shù):代理對象、方法、方法的參數(shù),因此不管代理對象哪個方法調(diào)用處理器的invoke方法,都必須把自己所在的對象、自己(調(diào)用invoke方法的方法)、方法的參數(shù)傳遞進來。
三、動態(tài)代理應(yīng)用
在動態(tài)代理技術(shù)里,由于不管用戶調(diào)用代理對象的什么方法,都是調(diào)用開發(fā)人員編寫的處理器的invoke方法(這相當(dāng)于invoke方法攔截到了代理對象的方法調(diào)用)。并且,開發(fā)人員通過invoke方法的參數(shù),還可以在攔截的同時,知道用戶調(diào)用的是什么方法,因此利用這兩個特性,就可以實現(xiàn)一些特殊需求,例如:攔截用戶的訪問請求,以檢查用戶是否有訪問權(quán)限、動態(tài)為某個對象添加額外的功能。
3.1、在字符過濾器中使用動態(tài)代理解決中文亂碼
在平時的JavaWeb項目開發(fā)中,我們一般會寫一個CharacterEncodingFilter(字符過濾器)來解決整個JavaWeb應(yīng)用的中文亂碼問題,如下所示:
package me.gacl.web.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
/**
* @ClassName: CharacterEncodingFilter
* @Description: 解決中文亂碼的字符過濾器
* @author: 孤傲蒼狼
* @date: 2014-9-14 下午10:38:12
*
*/
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
//解決以Post方式提交的中文亂碼問題
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
chain.doFilter(request, response);
}
@Override
public void destroy() {
}
}
但是這種寫法是沒有辦法解決以get方式提交中文參數(shù)時的亂碼問題的,我們可以用如下的代碼來證明上述的解決中文亂碼過濾器只對以post方式提交中文參數(shù)時有效,而對于以get方式提交中文參數(shù)時無效
jsp測試頁面如下:
<%@ page language="java" pageEncoding="UTF-8"%>
<%--引入jstl標(biāo)簽庫 --%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<!DOCTYPE HTML>
<html>
<head>
<title>使用字符過濾器解決解決get、post請求方式下的中文亂碼問題</title>
</head>
<body>
<%--使用c:url標(biāo)簽構(gòu)建url,構(gòu)建好的url存儲在servletDemo1變量中--%>
<c:url value="/servlet/ServletDemo1" scope="page" var="servletDemo1">
<%--構(gòu)建的url的附帶的中文參數(shù) ,參數(shù)名是:username,值是:孤傲蒼狼--%>
<c:param name="username" value="孤傲蒼狼"></c:param>
</c:url>
<%--使用get的方式訪問 --%>
<a href="${servletDemo1}" rel="external nofollow" >超鏈接(get方式請求)</a>
<hr/>
<%--使用post方式提交表單 --%>
<form action="${pageContext.request.contextPath}/servlet/ServletDemo1" method="post">
用戶名:<input type="text" name="username" value="孤傲蒼狼" />
<input type="submit" value="post方式提交">
</form>
</body>
</html>
處理請求的ServletDemo1代碼如下:
package me.gacl.web.controller;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class ServletDemo1 extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// 接收參數(shù)
String username = request.getParameter("username");
// 獲取請求方式
String method = request.getMethod();
// 獲取輸出流
PrintWriter out = response.getWriter();
out.write("請求的方式:" + method);
out.write("<br/>");
out.write("接收到的參數(shù):" + username);
}
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
在web.xml中注冊上述的CharacterEncodingFilter和ServletDemo1
<filter>
<filter-name>CharacterEncodingFilter</filter-name>
<filter-class>me.gacl.web.filter.CharacterEncodingFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>CharacterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<servlet>
<servlet-name>ServletDemo1</servlet-name>
<servlet-class>me.gacl.web.controller.ServletDemo1</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ServletDemo1</servlet-name>
<url-pattern>/servlet/ServletDemo1</url-pattern>
</servlet-mapping>
測試結(jié)果如下所示:

從運行結(jié)果可以看出,上述的過濾器的確是不能解決以get方式提交中文參數(shù)的亂碼問題,下面使用動態(tài)代理技術(shù)改造上述的過濾器,使之能夠解決以get方式提交中文參數(shù)的亂碼問題,改造后的過濾器代碼如下:
package me.gacl.web.filter;
import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
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.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName: CharacterEncodingFilter
* @Description: 解決中文亂碼的字符過濾器
* @author: 孤傲蒼狼
* @date: 2014-9-14 下午10:38:12
*
*/
public class CharacterEncodingFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) resp;
//解決以Post方式提交的中文亂碼問題
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
//獲取獲取HttpServletRequest對象的代理對象
ServletRequest requestProxy = getHttpServletRequestProxy(request);
/**
* 傳入代理對象requestProxy給doFilter方法,
* 這樣用戶在使用request對象時實際上使用的是HttpServletRequest對象的代理對象requestProxy
*/
chain.doFilter(requestProxy, response);
}
/**
* @Method: getHttpServletRequestProxy
* @Description: 獲取HttpServletRequest對象的代理對象
* @Anthor:孤傲蒼狼
*
* @param request
* @return HttpServletRequest對象的代理對象
*/
private ServletRequest getHttpServletRequestProxy(final HttpServletRequest request){
ServletRequest proxy = (ServletRequest) Proxy.newProxyInstance(
CharacterEncodingFilter.class.getClassLoader(),
request.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
//如果請求方式是get并且調(diào)用的是getParameter方法
if (request.getMethod().equalsIgnoreCase("get") && method.getName().equals("getParameter")) {
//調(diào)用getParameter方法獲取參數(shù)的值
String value = (String) method.invoke(request, args);
if(value==null){
return null;
}
//解決以get方式提交的中文亂碼問題
return new String(value.getBytes("iso8859-1"),"UTF-8");
}else {
//直接調(diào)用相應(yīng)的方法進行處理
return method.invoke(request, args);
}
}
});
//返回HttpServletRequest對象的代理對象
return proxy;
}
@Override
public void destroy() {
}
}
我們在過濾器中使用動態(tài)代理技術(shù)生成一個HttpServletRequest對象的代理對象requestProxy,然后把代理對象requestProxy進行chain.doFilter(requestProxy, response)傳遞給用戶使用,這樣用戶實際上使用的就是HttpServletRequest對象的代理對象requestProxy。然而這一過程對于用戶來說是透明的,用戶是不知道自己使用的HttpServletRequest對象是一個代理對象requestProxy,由于代理對象requestProxy和目標(biāo)對象HttpServletRequest具有相同的方法,當(dāng)用戶調(diào)用getParameter方法接收中文參數(shù)時,實際上調(diào)用的就是代理對象requestProxy的invoke方法,因此我們就可以在invoke方法中就判斷當(dāng)前的請求方式以及用戶正在調(diào)用的方法,如果判斷當(dāng)前的請求方式是get方式并且用戶正在調(diào)用的是getParameter方法,那么我們就可以手動處理get方式提交中文參數(shù)的中文亂碼問題了。
測試結(jié)果如下所示:

3.2、在字符過濾器中使用動態(tài)代理壓縮服務(wù)器響應(yīng)的內(nèi)容后再輸出到客戶端
壓縮過濾器的代碼如下:
package me.gacl.web.filter;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.zip.GZIPOutputStream;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @ClassName: GzipFilter
* @Description: 壓縮過濾器,將web應(yīng)用中的文本都經(jīng)過壓縮后再輸出到瀏覽器
* @author: 孤傲蒼狼
* @date: 2014-9-15 下午9:35:36
*
*/
public class GzipFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest req, ServletResponse resp,
FilterChain chain) throws IOException, ServletException {
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse response = (HttpServletResponse) resp;
final ByteArrayOutputStream bout = new ByteArrayOutputStream();
final PrintWriter pw = new PrintWriter(new OutputStreamWriter(bout,"UTF-8"));
chain.doFilter(request, getHttpServletResponseProxy(response, bout, pw));
pw.close();
//拿到目標(biāo)資源的輸出
byte result[] = bout.toByteArray();
System.out.println("原始大小:" + result.length);
ByteArrayOutputStream bout2 = new ByteArrayOutputStream();
GZIPOutputStream gout = new GZIPOutputStream(bout2);
gout.write(result);
gout.close();
//拿到目標(biāo)資源輸出的壓縮數(shù)據(jù)
byte gzip[] = bout2.toByteArray();
System.out.println("壓縮大?。? + gzip.length);
response.setHeader("content-encoding", "gzip");
response.setContentLength(gzip.length);
response.getOutputStream().write(gzip);
}
/**
* @Method: getHttpServletResponseProxy
* @Description: 獲取HttpServletResponse對象的代理對象
* @Anthor:孤傲蒼狼
*
* @param response
* @param bout
* @param pw
* @return HttpServletResponse對象的代理對象
*/
private ServletResponse getHttpServletResponseProxy(
final HttpServletResponse response,
final ByteArrayOutputStream bout,
final PrintWriter pw) {
return (ServletResponse) Proxy.newProxyInstance(GzipFilter.class.getClassLoader(),
response.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
if(method.getName().equals("getWriter")){
return pw;
}else if(method.getName().equals("getOutputStream")){
return new MyServletOutputStream(bout);
}else{
return method.invoke(response, args);
}
}
});
}
@Override
public void destroy() {
}
class MyServletOutputStream extends ServletOutputStream{
private ByteArrayOutputStream bout = null;
public MyServletOutputStream(ByteArrayOutputStream bout){
this.bout = bout;
}
@Override
public void write(int b) throws IOException {
bout.write(b);
}
}
}
在web.xml中注冊上述的GzipFilter
<filter>
<description>配置壓縮過濾器</description>
<filter-name>GzipFilter</filter-name>
<filter-class>me.gacl.web.filter.GzipFilter</filter-class>
</filter>
<!--jsp文件的輸出的內(nèi)容都經(jīng)過壓縮過濾器壓縮后才輸出 -->
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>*.jsp</url-pattern>
<!-- 配置過濾器的攔截方式-->
<!-- 對于在Servlet中通過
request.getRequestDispatcher("jsp頁面路徑").forward(request, response)
方式訪問的Jsp頁面的要進行攔截 -->
<dispatcher>FORWARD</dispatcher>
<!--對于直接以URL方式訪問的jsp頁面進行攔截,過濾器的攔截方式默認(rèn)就是REQUEST-->
<dispatcher>REQUEST</dispatcher>
</filter-mapping>
<!--js文件的輸出的內(nèi)容都經(jīng)過壓縮過濾器壓縮后才輸出 -->
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>*.js</url-pattern>
</filter-mapping>
<!--css文件的輸出的內(nèi)容都經(jīng)過壓縮過濾器壓縮后才輸出 -->
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>*.css</url-pattern>
</filter-mapping>
<!--html文件的輸出的內(nèi)容都經(jīng)過壓縮過濾器壓縮后才輸出 -->
<filter-mapping>
<filter-name>GzipFilter</filter-name>
<url-pattern>*.html</url-pattern>
</filter-mapping>
GzipFilter過濾器會將*.jsp,*.js,*.css,*.html這些文件里面的文本內(nèi)容都經(jīng)過壓縮后再輸出到客戶端顯示。
到此這篇關(guān)于Java 代理(Proxy)的具體使用的文章就介紹到這了,更多相關(guān)Java 代理內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot和Swagger結(jié)合提高API開發(fā)效率
這篇文章主要介紹了SpringBoot和Swagger結(jié)合提高API開發(fā)效率的相關(guān)資料,需要的朋友可以參考下2017-09-09
mybatis 集合嵌套查詢和集合嵌套結(jié)果的區(qū)別說明
這篇文章主要介紹了mybatis 集合嵌套查詢和集合嵌套結(jié)果的區(qū)別說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-09-09
SpringBoot中的Spring Cloud Hystrix原理和用法詳解
在Spring Cloud中,Hystrix是一個非常重要的組件,Hystrix可以幫助我們構(gòu)建具有韌性的分布式系統(tǒng),保證系統(tǒng)的可用性和穩(wěn)定性,在本文中,我們將介紹SpringBoot中的Hystrix,包括其原理和如何使用,需要的朋友可以參考下2023-07-07
詳解Spring Boot實戰(zhàn)之Filter實現(xiàn)使用JWT進行接口認(rèn)證
本篇文章主要介紹了詳解Spring Boot實戰(zhàn)之Filter實現(xiàn)使用JWT進行接口認(rèn)證,具有一定的參考價值,有興趣的可以了解一下2017-07-07

