如何獲得spring代理對(duì)象的原對(duì)象
獲得spring代理對(duì)象的原對(duì)象
看代碼吧:
@SuppressWarnings({"unchecked"}) protected <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception { if (AopUtils.isJdkDynamicProxy(proxy)) { return (T) ((Advised)proxy).getTargetSource().getTarget(); } else { return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class } }
public class AopTargetUtils { /** * 獲取 目標(biāo)對(duì)象 * @param proxy 代理對(duì)象 * @return * @throws Exception */ public static Object getTarget(Object proxy) throws Exception { if(!AopUtils.isAopProxy(proxy)) { return proxy;//不是代理對(duì)象 } if(AopUtils.isJdkDynamicProxy(proxy)) { return getJdkDynamicProxyTargetObject(proxy); } else { //cglib return getCglibProxyTargetObject(proxy); } } private 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); Object target = ((AdvisedSupport)advised.get(dynamicAdvisedInterceptor)).getTargetSource().getTarget(); return target; } private 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); Object target = ((AdvisedSupport)advised.get(aopProxy)).getTargetSource().getTarget(); return target; } @SuppressWarnings({"unchecked"}) protected <T> T getTargetObject(Object proxy, Class<T> targetClass) throws Exception { if (AopUtils.isJdkDynamicProxy(proxy)) { return (T) ((Advised)proxy).getTargetSource().getTarget(); } else { return (T) proxy; // expected to be cglib proxy then, which is simply a specialized class } } }
從Aop代理的對(duì)象中獲取源對(duì)象
/** * 從AOP代理對(duì)象中獲得原對(duì)象的類(lèi)型 * @param proxyObject * @return */ @SuppressWarnings("unchecked") public static final <T> T getBeanFromProxy(T proxyObject) { Class<?> clazz = proxyObject.getClass(); if(clazz.getName().startsWith("$Proxy")) { try { clazz = clazz.getSuperclass(); Field hField = clazz.getDeclaredField("h"); hField.setAccessible(true); Object hObject = hField.get(proxyObject); Class<?> dynamicProxyClass = hObject.getClass(); Field advisedField = dynamicProxyClass.getDeclaredField("advised"); advisedField.setAccessible(true); Object advisedObject = advisedField.get(hObject); Class<?> advisedSupportClass = advisedObject.getClass().getSuperclass().getSuperclass(); Field targetField = advisedSupportClass.getDeclaredField("targetSource"); targetField.setAccessible(true); Object targetObject = targetField.get(advisedObject); Class<?> targetSourceClass = targetObject.getClass(); Field targetClassField = targetSourceClass.getDeclaredField("target"); targetClassField.setAccessible(true); return (T) targetClassField.get(targetObject); } catch (SecurityException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } return null; }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
一文掌握Spring中循環(huán)依賴(lài)與三級(jí)緩存
這篇文章主要介紹了Spring中循環(huán)依賴(lài)與三級(jí)緩存,Spring通過(guò)三級(jí)緩存解決了循環(huán)依賴(lài),其中一級(jí)緩存為單例池,二級(jí)緩存為早期曝光對(duì)象earlySingletonObjects,三級(jí)緩存為早期曝光對(duì)象工廠(singletonFactories),本文結(jié)合實(shí)例代碼介紹的非常詳細(xì),需要的朋友參考下吧2023-09-09詳解如何將JAR包發(fā)布到Maven中央倉(cāng)庫(kù)
這篇文章主要介紹了詳解如何將JAR包發(fā)布到Maven中央倉(cāng)庫(kù),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-01-01springboot如何通過(guò)不同的策略動(dòng)態(tài)調(diào)用不同的實(shí)現(xiàn)類(lèi)
這篇文章主要介紹了springboot如何通過(guò)不同的策略動(dòng)態(tài)調(diào)用不同的實(shí)現(xiàn)類(lèi),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02springmvc無(wú)法訪問(wèn)/WEB-INF/views下的jsp的解決方法
本篇文章主要介紹了springmvc無(wú)法訪問(wèn)/WEB-INF/views下的jsp的解決方法,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2017-10-10Java中Stream流對(duì)多個(gè)字段進(jìn)行排序的方法
我們?cè)谔幚頂?shù)據(jù)的時(shí)候經(jīng)常會(huì)需要進(jìn)行排序后再返回給前端調(diào)用,比如按照時(shí)間升序排序,前端展示數(shù)據(jù)就是按時(shí)間先后進(jìn)行排序,下面這篇文章主要給大家介紹了關(guān)于Java中Stream流對(duì)多個(gè)字段進(jìn)行排序的相關(guān)資料,需要的朋友可以參考下2023-10-10初學(xué)者易上手的SSH-struts2 01環(huán)境搭建(圖文教程)
下面小編就為大家?guī)?lái)一篇初學(xué)者易上手的SSH-struts2 01環(huán)境搭建(圖文教程)。小編覺(jué)得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-10-10slf4j與jul、log4j1、log4j2、logback的集成原理
這篇文章主要介紹了slf4j與jul、log4j1、log4j2、logback的集成原理,以及通用日志框架與具體日志實(shí)現(xiàn)系統(tǒng)的機(jī)制機(jī)制介紹,包括依賴(lài)的jar包,jar沖突處理等2022-03-03以Spring Boot的方式顯示圖片或下載文件到瀏覽器的示例代碼
這篇文章主要介紹了以Spring Boot的方式顯示圖片或下載文件到瀏覽器的示例代碼,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01