場(chǎng)景:
在類中注入DAO接口,如Mapper蜕企,實(shí)際是一個(gè)代理接口碧注,單元測(cè)試的時(shí)候模擬SQL語(yǔ)句返回結(jié)果。
上一篇文章使用Setter方法改變代理接口為Mock類
但是會(huì)對(duì)代碼有所改變糖赔,侵入性太強(qiáng)萍丐,不合理,所以此次使用反射機(jī)制來(lái)改變類的屬性
/**
* 改變目標(biāo)類的屬性
* @param candidate? ? 目標(biāo)類
* @param fieldName? ? 屬性名
* @param fieldObject? 屬性類
*/
public void changeTargetField(Object candidate, String fieldName, Object fieldObject) {
? ? if (candidate instanceof Advised) {
? ? ? ? TargetSource targetSource =((Advised) candidate).getTargetSource();
? ? ? ? if (targetSource instanceof SingletonTargetSource) {
? ? ? ? ? ? Object target = ((SingletonTargetSource) targetSource).getTarget();
? ? ? ? ? ? try {
? ? ? ? ? ? ? ? Field field = candidate.getClass().getSuperclass().getDeclaredField(fieldName);
? ? ? ? ? ? ? ? field.setAccessible(true);
? ? ? ? ? ? ? ? field.set(target, fieldObject);
????????????????return;
? ? ? ? ? ? } catch (NoSuchFieldException | IllegalAccessException e) {
? ? ? ? ? ? ? ? throw new RuntimeException("代理類設(shè)置屬性失敗");
? ? ? ? ? ? }
????????}
? ? ? ? throw new RuntimeException("未找到代理類");
? ? ? } else {
? ? ? ? ? try {
? ? ? ? ? ? ????Field field = candidate.getClass().getDeclaredField(fieldName);
? ? ? ? ? ????? field.setAccessible(true);
? ? ? ? ? ????? field.set(candidate, fieldObject);
? ? ? ? ? } catch (NoSuchFieldException | IllegalAccessException e) {
? ? ? ? ? ? ????throw new RuntimeException("目標(biāo)類設(shè)置屬性失敗");
? ? ? ? ? }
????}
}