Solon APT
Solon APT,是专门为 Graalvm Native 打包提供友好支持的工程(它意图与 Spring AOT 相似)。目前有部分已完工,有部分处于预览状态。
插件 | 说明 | 状态 |
---|---|---|
solon.proxy.apt | 为 Solon 动态代理,提供 APT 实现方案 | |
solon.graalvm.apt | 为 Solon 在 Graalvm Native 打包时,自动生成元信息配置 | preview |
1、概述
容器型的框架,要支持 Graalvm Native 打包。主要有三方面的麻烦:
- 不能有动态编译或者字节码构建
- 不能有反射,或者通过配置申明反射相关信息
- 所有资源要配置申明
想要 Ioc/Aop,对类的动态代理就逃不了;对反射的需求也逃不了;还有 Spi 配置,应用自身的资源等。幸好 Solon 是一个提倡“克制”的容器型框架。像动态代理组件只能是 @ProxyComponent 注解的类,像切面开发只能基于注解而非表达式。
这种“克制”为 Solon 通过Java APT 技术解决麻烦的基础。
2、solon.proxy.apt 插件
这个插件是基于 Java APT 技术,为 @ProxyComponent 注解的类直接生成代理实现类。就像使用 lombok。它是解决 “不能有动态编译或者字节码构建” 的麻烦。看看效果:
原始类
@ProxyComponent
public class UserService extends UserServiceBase<String>{
private String userName;
public UserService(){
this.userName = "demo";
}
@Override
public String getUserName(){
return userName;
}
protected void setUserName(String name) throws RuntimeException{
userName = name;
}
}
由 solon.proxy.apt 生成的动态代理类
public final class UserService$$SolonAptProxy extends UserService {
private static Method method0;
private static Method method1;
static {
try {
Class<?> clazz = UserService.class;
method0=clazz.getMethod("getUserName");
method1=clazz.getMethod("getInfo");
} catch (Throwable e) {
throw new IllegalStateException(e);
}
}
private InvocationHandler handler;
public UserService$$SolonAptProxy(InvocationHandler handler) {
this.handler = handler;
}
@Override
public String getUserName() {
try {
return (java.lang.String)handler.invoke(this, method0, new Object[]{});
} catch (RuntimeException _ex) {
throw _ex;
} catch (Throwable _ex) {
throw new RuntimeException(_ex);
}
}
@Override
public String getInfo() {
try {
return (java.lang.String)handler.invoke(this, method1, new Object[]{});
} catch (RuntimeException _ex) {
throw _ex;
} catch (Throwable _ex) {
throw new RuntimeException(_ex);
}
}
}
3、solon.graalvm.apt 插件
这个插件是基于 @SolonMain 注解,自动生成 “native-image” 元信息配置的。包括 spi 配置,应用资源,反射类与函数等。
比如生成的 "META-INF/native-image/reflect-config.json" 部分信息:
[
{
"name": "org.noear.solon.extend.impl.PropsLoaderExt",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name": "org.noear.solon.extend.impl.PropsConverterExt",
"methods":[{"name":"<init>","parameterTypes":[] }]
},
{
"name": "org.noear.solon.boot.jlhttp.XPluginImp",
"methods":[{"name":"<init>","parameterTypes":[] }]
}
]
“@SolonMain” 注解没有别的用处,仅做为 Java APT 机制的解发条件。