方法动态代理
Service Keeper提供了原始方法的代理工具类用来完成对原始方法的代理,并织入服务治理的相关功能。使用时需要引入包:
<dependency>
    <groupId>io.esastack</groupId>
    <artifactId>servicekeeper-proxy-adapter</artifactId>
    <version>${servicekeeper.version}</version>
</dependency>
<dependency>
    <groupId>io.esastack</groupId>
    <artifactId>commons</artifactId>
    <version>${esa.commons.version}</version>
</dependency>
使用该方式接入Service Keeper时需要在应用启动时主动调用ServiceKeeperAsyncInvoker的init()完成对配置文件的监听,否则只有当第一调用ServiceKeeperAsyncInvoker中的方法时才会建立对配置文件的监听。
动态代理默认会拦截对象中所有能被代理到的方法,使用方式根据被代理的类是否为接口而略有不同,具体如下:
-  情形一:代理类为接口:接口定义示例: public interface DemoService { @RateLimiter(limitForPeriod = 100) void sayHello(); }实现类示例: public class DemoServiceImpl implements DemoService { @Override public void sayHello() { } }
Service Keeper治理示例:
// 使用ServiceKeeper提供的代理工厂创建接口的代理类
DemoService demoService = ServiceKeeperProxyFactory.createProxyHasInterface(new DemoServiceImpl());
// 执行方法调用
demoService.sayHello();    
该情形下服务治理注解需要加在接口方法上
-  情形二:代理类为非接口:原始类定义示例: 
public class DemoServiceImpl {
    @Override
    @RateLimiter(limitForPeriod = 100)
    public String merge(String s1, String s2) {
        return s1 + s2;
    }
}
Service Keeper代理示例:
// 使用ServiceKeeper提供的代理工厂创建非接口的代理类
DemoServiceImpl demoService = ServiceKeeperProxyFactory.createProxyNoInterface(new DemoServiceImpl());
// 执行方法调用
demoService.sayHello();
该情形下服务治理注解需要加在类方法上
工具类
Service Keeper提供了工具类,在原始方法执行前后织入服务治理的相关功能,具体方法如下:
public final class ServiceKeeperInvoker {
    private ServiceKeeperInvoker() {
    }
    
    public static Object invoke(Method method, Object delegate, Object[] args) throws Throwable {
        return Bootstrap.entry().invoke(method, delegate, args);
    }
    public static Object invoke(String aliasName, Method method, Object delegate, Object[] args) throws Throwable {
        return Bootstrap.entry().invoke(aliasName, method, delegate, args);
    }
    public static <T> T call(String name, CompositeServiceKeeperConfig immutableConfig,
                             Callable<T> callable, Object[] args) throws Throwable {
        return Bootstrap.entry().call(name, immutableConfig, callable, args);
    }
    public static <T> T call(String name, Callable<T> callable, Object[] args) throws Throwable {
        return Bootstrap.entry().call(name, callable, args);
    }
    public static <T> T call(String name, CompositeServiceKeeperConfig immutableConfig,
                             OriginalInvocation originalInvocation, Callable<T> callable,
                             Object[] args) throws Throwable {
        return Bootstrap.entry().call(name, immutableConfig, originalInvocation,
                callable, args);
    }
    
    public static <T> T call(String name, Supplier<CompositeServiceKeeperConfig> immutableConfigSupplier,
                             Supplier<OriginalInvocation> originalInvocation, Callable<T> callable,
                             Object[] args) throws Throwable {
        return Bootstrap.entry().call(name, immutableConfigSupplier, originalInvocation,
                callable, args);
    }
    public static void run(String name, Runnable runnable, Object[] args) throws Throwable {
        Bootstrap.entry().run(name, runnable, args);
    }
    public static void run(String name, CompositeServiceKeeperConfig immutableConfig,
                           Runnable runnable, Object[] args) throws Throwable {
        Bootstrap.entry().run(name, immutableConfig, runnable, args);
    }
    
    public static void init(List<AsyncResultHandler<?>> asyncResultHandlers) {
        Bootstrap.init(BootstrapContext.singleton(asyncResultHandlers));
    }
}
其中,name用于指定当前调用的名称,与配置文件中的配置的名称或管控平台的资源ID对应 Callbale、Runnable用于封装原始的执行逻辑。 OriginalInvocationInfo提供原始方法的返回值、参数列表信息,在匹配降级方法时使用(可选)。 CompositeServiceKeeperConfig提供当调用的初始配置(可选)。 举例说明: 自定义HelloService如下:
public class HelloService {
    public String sayHello(String name) {
        return "Hello " + name + "!";
    }
}
使用ServiceKeeper封装逻辑如下:
public static void main(String[] args) throws Throwable {
    final HelloService service = new HelloService();
    final Callable<String> callable = () -> service.sayHello("LiMing");
    ServiceKeeperInvoker.call("helloservice.hello", callable, new Object[]{"LiMing"});
}
如上所示,"helloservice.hello"表示当前callable的名称,通过配置文件或者管控平台配置该名称的限流、熔断等配置将对当前callbale生效;new Object[]{"LiMing"}是用来对当前callbable做参数级服务治理,如果不需该功能可以直接使传递new Object[0]。