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;
}
}