美文网首页
通过反射获取spring中aop代理的target对象

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

作者: 人才辈出玫瑰班 | 来源:发表于2020-04-09 09:37 被阅读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;
    }
    
    

    相关文章

      网友评论

          本文标题:通过反射获取spring中aop代理的target对象

          本文链接:https://www.haomeiwen.com/subject/kdrqmhtx.html