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

posted on 2019-03-18 15:16  sidesky  阅读(219)  评论(0编辑  收藏  举报