1. 程式人生 > >執行接口默認方法

執行接口默認方法

save rfi fin 修改 argument default ble this dto

public class YafBeanManager implements ApplicationContextAware {

private ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
this.applicationContext = applicationContext;
}

public Object invokeMethod(YafMethod yafMethod, Object[] args, Method method) throws Throwable {

if (yafMethod != null) {
Object bean = applicationContext.getBean(yafMethod.getClazz());
Method yafM = yafMethod.getMethod();
Object returnObj = yafM.invoke(bean, args);
return returnObj;
}

// 沒有提供擴展, 執行擴展點的默認實現
if (method.isDefault()) {

Object bean = applicationContext.getBean("save");
Class<?> interfaceCls = method.getDeclaringClass();
Object target = Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
new Class[]{interfaceCls},
(proxy, m, arguments) -> {
m.setAccessible(true);
return m.invoke(bean, arguments);
}
);


MethodHandles.Lookup lookup = MethodHandles.lookup().in(target.getClass());

// 修改 lookup 實例中的 allowedModes, 否則會拋異常導致調不了 default 方法
Field field = lookup.getClass().getDeclaredField("allowedModes");
field.setAccessible(true);

// 改掉這個字段的 final
Field modifierField = Field.class.getDeclaredField("modifiers");
modifierField.setAccessible(true);
modifierField.set(field, field.getModifiers() ^ Modifier.FINAL);

// 設置allowedModes
field.set(lookup, -1);

return lookup.unreflectSpecial(method, interfaceCls)
.bindTo(target)
.invokeWithArguments(args);
}

return null;
}
}

執行接口默認方法