通过反射获取spring中aop代理的target对象

2020-04-09  本文已影响0人  人才辈出玫瑰班

最近项目需要获取从spring创建的aop代理中获取它的target对象,其实可以通过反射来获取,代码如下

public class ProxyUtil {

    // CglibAopProxy
    public static Object getCglibProxyTargetObject(Object proxy) throws Exception {
        Field h = proxy.getClass().getDeclaredField("CGLIB$CALLBACK_0");
        h.setAccessible(true);
        Object dynamicAdvisedInterceptor = h.get(proxy);

        Field advised = dynamicAdvisedInterceptor.getClass().getDeclaredField("advised");
        advised.setAccessible(true);

        return ((AdvisedSupport) advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget();
    }

    // JdkDynamicAopProxy
    public static Object getJdkDynamicProxyTargetObject(Object proxy) throws Exception {
        Field h = proxy.getClass().getSuperclass().getDeclaredField("h");
        h.setAccessible(true);
        AopProxy aopProxy = (AopProxy) h.get(proxy);
        Field advised = aopProxy.getClass().getDeclaredField("advised");
        advised.setAccessible(true);

        return ((AdvisedSupport) advised.get(aopProxy)).getTargetSource().getTarget();
    }

}

aop的实现一般分为cglib代理和jdk代理,所以在获取spring中某个aop代理的target时,需要先判断是属于那个实现,进而选用对应的获取方式

通过这一步,我们解决了上一篇《当springsecurity的remember-me功能遇上用户名修改》无法通过 RememberMeServices 转化为 PersistentTokenBasedRememberMeServices 进而在创建新的token之前删除旧的token的问题

@Autowired 
@Lazy
private RememberMeServices rememberMeService;

private volatile PersistentTokenBasedRememberMeServices persistentRememberMeServices;

// 刷新authentication和cookie
private void refreshAuthentication(HttpServletRequest request, HttpServletResponse response, Authentication oldAuthentication) {
    if(checkCookie(request)){
            // 先删除就的token然后创建新的token
        getPersistentTokenBasedRememberMeServices().logout(request,response,oldAuthentication);
        rememberMeService.loginSuccess(request, response, getAuthentication());
    }
}

// 单例-加锁
private PersistentTokenBasedRememberMeServices getPersistentTokenBasedRememberMeServices() {
     if(persistentTokenBasedRememberMeServices == null){
        synchronized (this){            
            if(persistentTokenBasedRememberMeServices == null) {
                 try {
                        persistentTokenBasedRememberMeServices =
                                (PersistentTokenBasedRememberMeServices) ProxyUtil.getJdkDynamicProxyTargetObject(rememberMeService);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    return persistentTokenBasedRememberMeServices;
}

上一篇下一篇

猜你喜欢

热点阅读