2828import org .slf4j .LoggerFactory ;
2929
3030import java .io .IOException ;
31+ import java .util .concurrent .locks .Lock ;
3132
3233public class WxMpServiceImpl implements WxMpService {
3334
3435 private static final JsonParser JSON_PARSER = new JsonParser ();
3536
3637 protected final Logger log = LoggerFactory .getLogger (this .getClass ());
3738
38- /**
39- * 全局的是否正在刷新access token的锁
40- */
41- private final Object globalAccessTokenRefreshLock = new Object ();
42-
43- /**
44- * 全局的是否正在刷新jsapi_ticket的锁
45- */
46- private final Object globalJsapiTicketRefreshLock = new Object ();
47-
4839 private WxMpConfigStorage configStorage ;
4940
5041 private WxMpKefuService kefuService = new WxMpKefuServiceImpl (this );
@@ -98,39 +89,42 @@ public String getAccessToken() throws WxErrorException {
9889
9990 @ Override
10091 public String getAccessToken (boolean forceRefresh ) throws WxErrorException {
101- if ( forceRefresh ) {
102- this . configStorage . expireAccessToken ();
103- }
92+ Lock lock = configStorage . getAccessTokenLock ();
93+ try {
94+ lock . lock ();
10495
105- if (this .configStorage .isAccessTokenExpired ()) {
106- synchronized (this .globalAccessTokenRefreshLock ) {
107- if (this .configStorage .isAccessTokenExpired ()) {
108- String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
109- "&appid=" + this .configStorage .getAppId () + "&secret="
110- + this .configStorage .getSecret ();
111- try {
112- HttpGet httpGet = new HttpGet (url );
113- if (this .httpProxy != null ) {
114- RequestConfig config = RequestConfig .custom ().setProxy (this .httpProxy ).build ();
115- httpGet .setConfig (config );
116- }
117- try (CloseableHttpResponse response = getHttpclient ().execute (httpGet )) {
118- String resultContent = new BasicResponseHandler ().handleResponse (response );
119- WxError error = WxError .fromJson (resultContent );
120- if (error .getErrorCode () != 0 ) {
121- throw new WxErrorException (error );
122- }
123- WxAccessToken accessToken = WxAccessToken .fromJson (resultContent );
124- this .configStorage .updateAccessToken (accessToken .getAccessToken (),
125- accessToken .getExpiresIn ());
126- }finally {
127- httpGet .releaseConnection ();
96+ if (forceRefresh ) {
97+ this .configStorage .expireAccessToken ();
98+ }
99+
100+ if (this .configStorage .isAccessTokenExpired ()) {
101+ String url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential" +
102+ "&appid=" + this .configStorage .getAppId () + "&secret="
103+ + this .configStorage .getSecret ();
104+ try {
105+ HttpGet httpGet = new HttpGet (url );
106+ if (this .httpProxy != null ) {
107+ RequestConfig config = RequestConfig .custom ().setProxy (this .httpProxy ).build ();
108+ httpGet .setConfig (config );
109+ }
110+ try (CloseableHttpResponse response = getHttpclient ().execute (httpGet )) {
111+ String resultContent = new BasicResponseHandler ().handleResponse (response );
112+ WxError error = WxError .fromJson (resultContent );
113+ if (error .getErrorCode () != 0 ) {
114+ throw new WxErrorException (error );
128115 }
129- } catch (IOException e ) {
130- throw new RuntimeException (e );
116+ WxAccessToken accessToken = WxAccessToken .fromJson (resultContent );
117+ this .configStorage .updateAccessToken (accessToken .getAccessToken (),
118+ accessToken .getExpiresIn ());
119+ }finally {
120+ httpGet .releaseConnection ();
131121 }
122+ } catch (IOException e ) {
123+ throw new RuntimeException (e );
132124 }
133125 }
126+ } finally {
127+ lock .unlock ();
134128 }
135129 return this .configStorage .getAccessToken ();
136130 }
@@ -142,22 +136,25 @@ public String getJsapiTicket() throws WxErrorException {
142136
143137 @ Override
144138 public String getJsapiTicket (boolean forceRefresh ) throws WxErrorException {
145- if ( forceRefresh ) {
146- this . configStorage . expireJsapiTicket ();
147- }
139+ Lock lock = configStorage . getJsapiTicketLock ();
140+ try {
141+ lock . lock ();
148142
149- if (this .configStorage .isJsapiTicketExpired ()) {
150- synchronized (this .globalJsapiTicketRefreshLock ) {
151- if (this .configStorage .isJsapiTicketExpired ()) {
152- String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi" ;
153- String responseContent = execute (new SimpleGetRequestExecutor (), url , null );
154- JsonElement tmpJsonElement = JSON_PARSER .parse (responseContent );
155- JsonObject tmpJsonObject = tmpJsonElement .getAsJsonObject ();
156- String jsapiTicket = tmpJsonObject .get ("ticket" ).getAsString ();
157- int expiresInSeconds = tmpJsonObject .get ("expires_in" ).getAsInt ();
158- this .configStorage .updateJsapiTicket (jsapiTicket , expiresInSeconds );
159- }
143+ if (forceRefresh ) {
144+ this .configStorage .expireJsapiTicket ();
145+ }
146+
147+ if (this .configStorage .isJsapiTicketExpired ()) {
148+ String url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?type=jsapi" ;
149+ String responseContent = execute (new SimpleGetRequestExecutor (), url , null );
150+ JsonElement tmpJsonElement = JSON_PARSER .parse (responseContent );
151+ JsonObject tmpJsonObject = tmpJsonElement .getAsJsonObject ();
152+ String jsapiTicket = tmpJsonObject .get ("ticket" ).getAsString ();
153+ int expiresInSeconds = tmpJsonObject .get ("expires_in" ).getAsInt ();
154+ this .configStorage .updateJsapiTicket (jsapiTicket , expiresInSeconds );
160155 }
156+ } finally {
157+ lock .unlock ();
161158 }
162159 return this .configStorage .getJsapiTicket ();
163160 }
0 commit comments