微信开发如何优雅的注入token

众所周知微信公众号开发时,请求微信服务器需要携带token,如何在业务更好的使用token呢,引出下文(呵呵呵)。

这里介绍的token是使用readWrite锁的方式获取和释放,没有用这种方法的业务处理本次不做讨论(感觉没有读写锁,token的使用是不可靠的,详情请阅读我的博客‘微信开发-定时获取token,保证线程安全,高可用’),即处理业务前获取token并加锁,处理完毕后又要释放token并解锁,非常不方便那么如何让人更懒一些(懒惰推动科技进步),程序员只实现业务处理而不去管token的获取和释放问题呢?我想到的方法有2种。1:通过代理在方法前后做手脚,2:通过重写spring相关的参数处理类做手脚。此次先介绍第一种方法,第二种待续。。


首先使用切面是代理的最好选择,先配置好切面类在,在方法前注入token,方法完毕后释放token(包括异常情况),先配置一个切面类

@Aspect
@Order(1)
@Component
public class WeChatAspect {

    //声明切面,使用方法同spring
    @Pointcut("execution(* com.ccx.*.controller..*Controller.*(..))")

    //需要加上
    public void WeChatAspect() { }

    //spring容器工具栏(上篇有介绍到)
    @Autowired
    private SpringContextsUtil springContextsUtil;

    //前置方法
    @Before("WeChatAspect()")
    public void SetTokenBefore(JoinPoint point) {
        Object[] args = point.getArgs();

        if (null != args) {
            for (Object arg : args) {
                //实现思路同controler的参数注入
                //用户写什么参数我们尽可能的为他注入,这里注入我们的Token类
                if (arg.getClass().toString().equals(Token.class.toString())) {
                    //如果参数列表声明的Token类,那么我们为他注入
                    arg = springContextsUtil.getBean("token");
                }
            }
            }
    }

    //后置方法
    @AfterReturning("WeChatAspect()")
    public void relaseTokenAfterReturn()  {
        //通过容器获取Token类
        Token token = springContextsUtil.getBean("token", Token.class);
        token.releaseTokenAndUnlock();
    }

    //异常也要释放
    @AfterThrowing("WeChatAspect()")
    public void relaseTokenAfterThrowing()  {
        //通过容器获取Token类
        Token token = springContextsUtil.getBean("token", Token.class);
        token.releaseTokenAndUnlock();
    }
}

切面写好了再看看Token类,这里并不是真正的工具类,只是为了模拟效果写的,需要其他的东西自己搞定

@Component("token")
public class Token {
    private static String token = "XXXXXXXXXXXXXXXXXXXXXXXX";

    private static  ReentrantReadWriteLock lock = new ReentrantReadWriteLock();

    /*
    * @Description:  获取token的同时加读锁
    * @Author:       hendiaome
    * @CreateDate:   ${DATE} ${TIME}
    * @Param:        v1.0
    * @Return        token
    */
    public String getTokenAndLock() {
        lock.readLock().lock();
        return token;
    }

    /*
    * @Description:  释放token的同时关闭读锁
    * @Author:       hendiaome
    * @CreateDate:   ${DATE} ${TIME}
    * @Param:        v1.0
    * @Return        token
    */
    public void releaseTokenAndUnlock() {
        lock.readLock().unlock();
    }

    public void writeLock() {
        lock.writeLock().lock();;
    }

    public void writeUnLock() {
        lock.writeLock().unlock();;
    }
}

最简单的就是这样,最后是controller,也是demo级别的,莫怪。

@Controller
@RequestMapping("/wechat")
public class WeChatController {

    @RequestMapping("/test")
    @ResponseBody
    public Object Test(Token token) {
        String tokenAcess = token.getTokenAndLock();
        //拿着token去做自己的业务处理去吧
        return "OK";
    }

}

好了以上就是简单的实现了token的自动注入和释放,应该注意的是在释放token的时候,应该判读此方法是否注入了token,,如果没有声明token,而后置方法一味的去释放,是我们不想要的结果,所以应该加入判断,推荐使用threadlocal,仅当方法声明注入的时候,再释放。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章