采用java单例模式实现微信AccessToken和Jsapi_ticket缓存支持
2016-02-22 09:58
661 查看
一、单例模式介绍
java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、登记式单例。
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer
Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
二、实现
public
class JSSDKTicket {
public static Logger logger=LogManager.getLogger(JSSDKTicket.class);
private String ticket;
private int expires_in;
private long timeStamp=System.currentTimeMillis()/1000;
//单例模式实现
private static JSSDKTicket JSAPI_TICKET;
public static String getTicket(){
if (JSAPI_TICKET==null) {
try {
JSAPI_TICKET=getJsTicket();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
if(JSAPI_TICKET.isExpire()){
try {
JSAPI_TICKET=getJsTicket();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return getTicket();
}else{
return JSAPI_TICKET.ticket;
}
}
private JSSDKTicket(){
super();
}
public int getExpires_in() {
return expires_in;
}
public void setExpires_in(int expires_in) {
this.expires_in = expires_in;
}
public long getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(long timeStamp) {
this.timeStamp = timeStamp;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public boolean isExpire(){
return System.currentTimeMillis()/1000<(timeStamp+expires_in)?false:true;
}
private static JSSDKTicket getJsTicket() throws Exception{
try(AsyncHttpClient client=new AsyncHttpClient()){
Response response=client.prepareGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket")
.addQueryParam("access_token", WeChatAccessToken.getAccessToken()).addQueryParam("type", "jsapi").execute().get();
Map<String,Object> result=JSONUtils.readJsonValue(response.getResponseBodyAsStream(), new TypeReference<Map<String,Object>>() {});
logger.debug(result);
if((int)result.get("errcode")==0){
JSSDKTicket t=new JSSDKTicket();
t.setTicket((String) result.get("ticket"));
t.setExpires_in((int) result.get("expires_in"));
return t;
}else{
throw new Exception(result.get("access_token missing").toString());
}
}
}
}
accessToken单例模式实现
public
class WeChatAccessToken {
private String access_token;
private int expires_in;
private Date time = new Date();
public boolean isExpires() {
long secends = System.currentTimeMillis() - this.time.getTime();
return secends > this.expires_in * 1000 ? true : false;
}
//类静态对象
private static WeChatAccessToken accessToken;
//单例模式实现
public static String getAccessToken() throws Exception {
if (accessToken == null) {
try {
getWeChatAccessToken();
} catch (IOException e) {
e.printStackTrace();
}
} else if (accessToken.isExpires()) {
try {
getWeChatAccessToken();
} catch (IOException e) {
e.printStackTrace();
}
}
return accessToken.getAccess_token();
}
@Override
public String toString() {
return "WeChatAccessToken [access_token=" + access_token
+ ", expires_in=" + expires_in + ", time=" + time
+ ", isExpires()=" + isExpires() + "]";
}
private
static void getWeChatAccessToken() throws Exception {
ObjectMapper mapper = new ObjectMapper();
try(AsyncHttpClient client=new AsyncHttpClient()){
Response response=client.prepareGet(WeChatConfiguration.URL_GET_ACCESS_TOKEN)
.addQueryParam("grant_type", "client_credential")
.addQueryParam("appid", WeChatConfiguration.getInstance().getAppId())
.addQueryParam("secret", WeChatConfiguration.getInstance().getAppKey())
.execute().get();
Map<String,Object> result=JSONUtils.readJsonValue(response.getResponseBodyAsStream(), new TypeReference<Map<String,Object>>() {});
if(result.containsKey("access_token")){
String value = mapper.writeValueAsString(result);
accessToken = mapper.readValue(value, WeChatAccessToken.class);
}else{
throw new Exception(result.get("errcode").toString());
}
}
}
public String getAccess_token() {
return access_token;
}
public
void setAccess_token(String access_token) {
this.access_token = access_token;
}
public
int getExpires_in() {
return expires_in;
}
public
void setExpires_in(int expires_in) {
this.expires_in = expires_in;
}
}
三、存在问题
这种实现对单个应用系统实用,如果是分布式部署的多个系统就不在实用,而是应用缓存系统实现更为妥当,例如memcached
java中单例模式是一种常见的设计模式,单例模式的写法有好几种,这里主要介绍三种:懒汉式单例、饿汉式单例、登记式单例。
单例模式有以下特点:
1、单例类只能有一个实例。
2、单例类必须自己创建自己的唯一实例。
3、单例类必须给所有其他对象提供这一实例。
单例模式确保某个类只有一个实例,而且自行实例化并向整个系统提供这个实例。在计算机系统中,线程池、缓存、日志对象、对话框、打印机、显卡的驱动程序对象常被设计成单例。这些应用都或多或少具有资源管理器的功能。每台计算机可以有若干个打印机,但只能有一个Printer
Spooler,以避免两个打印作业同时输出到打印机中。每台计算机可以有若干通信端口,系统应当集中管理这些通信端口,以避免一个通信端口同时被两个请求同时调用。总之,选择单例模式就是为了避免不一致状态,避免政出多头。
二、实现
public
class JSSDKTicket {
public static Logger logger=LogManager.getLogger(JSSDKTicket.class);
private String ticket;
private int expires_in;
private long timeStamp=System.currentTimeMillis()/1000;
//单例模式实现
private static JSSDKTicket JSAPI_TICKET;
public static String getTicket(){
if (JSAPI_TICKET==null) {
try {
JSAPI_TICKET=getJsTicket();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
if(JSAPI_TICKET.isExpire()){
try {
JSAPI_TICKET=getJsTicket();
} catch (Exception e) {
e.printStackTrace();
return null;
}
return getTicket();
}else{
return JSAPI_TICKET.ticket;
}
}
private JSSDKTicket(){
super();
}
public int getExpires_in() {
return expires_in;
}
public void setExpires_in(int expires_in) {
this.expires_in = expires_in;
}
public long getTimeStamp() {
return timeStamp;
}
public void setTimeStamp(long timeStamp) {
this.timeStamp = timeStamp;
}
public void setTicket(String ticket) {
this.ticket = ticket;
}
public boolean isExpire(){
return System.currentTimeMillis()/1000<(timeStamp+expires_in)?false:true;
}
private static JSSDKTicket getJsTicket() throws Exception{
try(AsyncHttpClient client=new AsyncHttpClient()){
Response response=client.prepareGet("https://api.weixin.qq.com/cgi-bin/ticket/getticket")
.addQueryParam("access_token", WeChatAccessToken.getAccessToken()).addQueryParam("type", "jsapi").execute().get();
Map<String,Object> result=JSONUtils.readJsonValue(response.getResponseBodyAsStream(), new TypeReference<Map<String,Object>>() {});
logger.debug(result);
if((int)result.get("errcode")==0){
JSSDKTicket t=new JSSDKTicket();
t.setTicket((String) result.get("ticket"));
t.setExpires_in((int) result.get("expires_in"));
return t;
}else{
throw new Exception(result.get("access_token missing").toString());
}
}
}
}
accessToken单例模式实现
public
class WeChatAccessToken {
private String access_token;
private int expires_in;
private Date time = new Date();
public boolean isExpires() {
long secends = System.currentTimeMillis() - this.time.getTime();
return secends > this.expires_in * 1000 ? true : false;
}
//类静态对象
private static WeChatAccessToken accessToken;
//单例模式实现
public static String getAccessToken() throws Exception {
if (accessToken == null) {
try {
getWeChatAccessToken();
} catch (IOException e) {
e.printStackTrace();
}
} else if (accessToken.isExpires()) {
try {
getWeChatAccessToken();
} catch (IOException e) {
e.printStackTrace();
}
}
return accessToken.getAccess_token();
}
@Override
public String toString() {
return "WeChatAccessToken [access_token=" + access_token
+ ", expires_in=" + expires_in + ", time=" + time
+ ", isExpires()=" + isExpires() + "]";
}
private
static void getWeChatAccessToken() throws Exception {
ObjectMapper mapper = new ObjectMapper();
try(AsyncHttpClient client=new AsyncHttpClient()){
Response response=client.prepareGet(WeChatConfiguration.URL_GET_ACCESS_TOKEN)
.addQueryParam("grant_type", "client_credential")
.addQueryParam("appid", WeChatConfiguration.getInstance().getAppId())
.addQueryParam("secret", WeChatConfiguration.getInstance().getAppKey())
.execute().get();
Map<String,Object> result=JSONUtils.readJsonValue(response.getResponseBodyAsStream(), new TypeReference<Map<String,Object>>() {});
if(result.containsKey("access_token")){
String value = mapper.writeValueAsString(result);
accessToken = mapper.readValue(value, WeChatAccessToken.class);
}else{
throw new Exception(result.get("errcode").toString());
}
}
}
public String getAccess_token() {
return access_token;
}
public
void setAccess_token(String access_token) {
this.access_token = access_token;
}
public
int getExpires_in() {
return expires_in;
}
public
void setExpires_in(int expires_in) {
this.expires_in = expires_in;
}
}
三、存在问题
这种实现对单个应用系统实用,如果是分布式部署的多个系统就不在实用,而是应用缓存系统实现更为妥当,例如memcached
相关文章推荐
- 浅析SQL Server中的执行计划缓存(上)
- Enterprise Library for .NET Framework 2.0缓存使用实例
- PowerShell中编程清空IE缓存方法
- PowerShell中使用.NET将程序集加入全局程序集缓存
- C#中缓存的基本用法总结
- 举例讲解C#编程中对设计模式中的单例模式的运用
- Android实现图片异步加载并缓存到本地
- wap开发中如何有效的利用缓存减少消息的传送量
- php设计模式之单例模式实例分析
- PHP基于单例模式实现的数据库操作基类
- PHP基于文件存储实现缓存的方法
- smarty缓存用法分析
- 引用全局程序集缓存内的程序集的方法
- asp Response.flush 实时显示进度
- C#实现清除IE浏览器缓存的方法
- JavaScript编程的单例设计模讲解
- ASP.NET缓存管理的几种方法
- PHP文件缓存类实现代码
- 清除aspx页面缓存的程序实现方法
- C#缓存之SqlCacheDependency用法实例总结