{"id":28412707,"url":"https://github.com/vbauer/caesar","last_synced_at":"2025-06-30T21:34:49.860Z","repository":{"id":27925547,"uuid":"31417833","full_name":"vbauer/caesar","owner":"vbauer","description":"Library that allows to create async beans from sync beans","archived":false,"fork":false,"pushed_at":"2018-11-12T17:49:25.000Z","size":675,"stargazers_count":113,"open_issues_count":0,"forks_count":14,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-06-09T19:48:34.895Z","etag":null,"topics":["asynchronous-executions","java","proxy"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vbauer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-02-27T12:13:18.000Z","updated_at":"2025-05-15T22:45:04.000Z","dependencies_parsed_at":"2022-08-20T06:20:43.076Z","dependency_job_id":null,"html_url":"https://github.com/vbauer/caesar","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/vbauer/caesar","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fcaesar","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fcaesar/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fcaesar/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fcaesar/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vbauer","download_url":"https://codeload.github.com/vbauer/caesar/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vbauer%2Fcaesar/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261685298,"owners_count":23194083,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["asynchronous-executions","java","proxy"],"created_at":"2025-06-02T23:44:49.782Z","updated_at":"2025-06-24T13:30:53.784Z","avatar_url":"https://github.com/vbauer.png","language":"Java","readme":"\n# Caesar\n\n[![Android Arsenal](https://img.shields.io/badge/Android%20Arsenal-Caesar-brightgreen.svg?style=flat)](http://android-arsenal.com/details/1/1598)\n[![Build Status](https://travis-ci.org/vbauer/caesar.svg)](https://travis-ci.org/vbauer/caesar)\n[![Coverage Status](https://coveralls.io/repos/vbauer/caesar/badge.svg?branch=master)](https://coveralls.io/r/vbauer/caesar?branch=master)\n[![Maven](https://img.shields.io/github/tag/vbauer/caesar.svg?label=maven)](https://jitpack.io/#vbauer/caesar)\n[![Codacy Badge](https://api.codacy.com/project/badge/grade/defb1d30427c4220aa8cf8fc9fa7830c)](https://www.codacy.com/app/bauer-vlad/caesar)\n\n\u003cimg align=\"right\" style=\"margin-left: 15px\" width=\"250\" height=\"268\" src=\"misc/caesar.png\"\u003e\n\n\u003e I came, I saw, I conquered. - Julius Caesar\n\n**Caesar** is a tiny Java library that allows to create an asynchronous proxy-version of some synchronous bean. It means\nthat you can still think in terms of your service/bean/object and use its methods instead of writing concurrency code.\n\n**Use cases:**\n\n* You have already got some 3-rd party library that works synchronously, but it is necessary to use it asynchronously.\n* You need to use both ways (sync \u0026 async) in different parts of your applications.\n\nCaesar will help you to solve these problems.\n\n**Online documentation:**\n\n* [Maven site](https://vbauer.github.io/caesar)\n* [Javadoc](https://vbauer.github.io/caesar/apidocs)\n\n\n## Main features:\n\n* Flexible describing of method signatures:\n    * using standard Java [Future](http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html)\n    * or using [RxJava](https://github.com/ReactiveX/RxJava) ([Observable](https://github.com/ReactiveX/RxJava/wiki/Observable))\n    * or using [Guava](https://github.com/google/guava) ([ListenableFuture](https://github.com/google/guava/blob/master/guava/src/com/google/common/util/concurrent/ListenableFuture.java), [FutureCallback](https://github.com/google/guava/blob/master/guava/src/com/google/common/util/concurrent/FutureCallback.java), [FutureCallbackAdapter](src/main/java/com/github/vbauer/caesar/callback/FutureCallbackAdapter.java))\n    * or using custom callbacks ([AsyncCallback](src/main/java/com/github/vbauer/caesar/callback/AsyncCallback.java), [AsyncCallbackAdapter](src/main/java/com/github/vbauer/caesar/callback/AsyncCallbackAdapter.java))\n* Small library size with zero dependencies\n* Compact and very simple API\n* Configurable timeouts\n* Compatibility:\n    * Java 8+\n    * Android\n\n## Setup\n\nMaven:\n```xml\n\u003crepository\u003e\n    \u003cid\u003ejitpack.io\u003c/id\u003e\n    \u003curl\u003ehttps://jitpack.io\u003c/url\u003e\n\u003c/repository\u003e\n\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.github.vbauer\u003c/groupId\u003e\n    \u003cartifactId\u003ecaesar\u003c/artifactId\u003e\n    \u003cversion\u003e1.7.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\nGradle:\n```groovy\nrepositories {\n    maven {\n        url \"https://jitpack.io\"\n    }\n}\n\ndependencies {\n    compile 'com.github.vbauer:caesar:1.7.0'\n}\n```\n\n\n## Async-proxy creation\n\nTo make async-proxy for some bean, you need to use `AsyncProxyCreator`:\n\n```java\npublic static \u003cSYNC, ASYNC\u003e ASYNC create(\n    final SYNC bean,\n    final Class\u003cASYNC\u003e asyncInterface,\n    final ExecutorService executor,\n    final boolean validate\n)\n```\n\n**Parameters:**\n\n\u003cdl\u003e\n    \u003cdt\u003ebean\u003c/dt\u003e\n    \u003cdd\u003eNot-null object which will be wrapped by async-proxy.\u003c/dd\u003e\n    \u003cdt\u003easyncInterface\u003c/dt\u003e\n    \u003cdd\u003eClass which represents async-proxy. See an example section for more details.\u003c/dd\u003e\n    \u003cdt\u003eexecutor\u003c/dt\u003e\n    \u003cdd\u003eExecutor service for running background operations. The usual choice is `ThreadPoolExecutor`.\u003c/dd\u003e\n    \u003cdt\u003evalidate\u003c/dt\u003e\n    \u003cdd\u003eValidate mapping between bean and asyncInterface during proxy creation (otherwise it will be checked in runtime). It is an optional parameter (default value is true).\u003c/dd\u003e\n\u003c/dl\u003e\n\n\n## Mapping, Naming conventions\n\nTo make correct mapping between object and async-proxy, it is necessary to perform some conventions.\nAsynchronous proxy method signature must match the signature of the object method, except several points:\n\n* To use **Future** as result value, return class must be `Future\u003cT\u003e`\n* To use **Guava**:\n    * return class should be `ListenableFuture\u003cT\u003e`\n    * or add new parameter `FutureCallback\u003cT\u003e` at the first place of the method signature and change result type to `void`\n* To use **RxJava**, return class must be `Observable\u003cT\u003e`\n* To use **AsyncCallback**, you need to:\n    * add new parameter `AsyncCallback\u003cT\u003e` at the first place of the method signature\n    * change result type to `void`\n\nIf this conventions are not complied, than the corresponding sync-method with the same signature should be invoked.\nIt will be still invoked in the separate thread to allow to use `@Timeout` annotation.\n\n\n## Example\n\nLets make an async-proxy for the following bean:\n```java\npublic class Sync {\n\n    public String hello(final String name) {\n        // Just a simple code for an example.\n        return String.format(\"Hello, %s\", name);\n    }\n\n}\n```\n\nFirst of all, we need to create an async-interface for this bean:\n```java\n// IMPORTANT: It is just an example. Choose the most appropriate way for you.\n// All methods could not be presented at the same time in the real code.\npublic interface Async {\n\n    // Future\u003cT\u003e will be the new return type.\n    Future\u003cString\u003e hello(String name);\n\n    // Future\u003cT\u003e will be the new return type.\n    ListenableFuture\u003cString\u003e hello(String name);\n\n    // Observable\u003cT\u003e will be also the new return type.\n    Observable\u003cString\u003e hello(String name);\n\n    // AsyncCallback\u003cT\u003e should be added as the first parameter.\n    void hello(AsyncCallback\u003cString\u003e callback, String name);\n\n    // FutureCallback\u003cT\u003e should be also added as the first parameter.\n    void hello(FutureCallback\u003cString\u003e callback, String name);\n\n}\n```\n\nAfter that we can create an async-proxy using `AsyncProxyCreator`:\n```java\nfinal AsyncBean asyncBean = AsyncProxyCreator.create(\n    new Sync(), Async.class, Executors.newFixedThreadPool(5));\n```\n\nThat's all. Now you can use your bean asynchronously. All methods will be invoked in threads from thread pool.\n\n```java\n// Retrieve result using Future:\nfinal Future future = asyncBean.hello(\"John\");\nfinal String text = future.get(); // text is \"Hello, John\"\n\n// Retrieve result using ListenableFuture:\nfinal ListenableFuture listenableFuture = asyncBean.hello(\"George\");\nfinal String text = listenableFuture.get(); // text is \"Hello, George\"\n\n// Retrieve result using RxJava and Observable:\nfinal Observable\u003cString\u003e observable = asyncBean.hello(\"Paul\");\nfinal String text = observable.toBlocking().first(); // text is \"Hello, Paul\"\n\n// Retrieve result using custom callback:\nasyncBean.hello(new AsyncCallbackAdapter\u003cString\u003e() {\n     @Override\n     public void onSuccess(final String text) {\n         // text is \"Hello, Ringo\"\n     }\n}, \"Ringo\");\n\n// Retrieve result using FutureCallback:\nasyncBean.hello(new FutureCallback\u003cString\u003e() {\n    @Override\n    public void onSuccess(final String text) {\n        // text is \"Hello, guys\"\n    }\n    @Override\n    public void onFailure(final Throwable t) {\n        // it will not be executed\n    }\n}, \"guys\");\n```\n\n\n## @Timeout\n\nSometimes it is useful to setup timeout value to cancel operation (ex: REST API call which takes a lot of time).\nYou can use `@Timeout` annotation to do it (cancel operation after 3 seconds):\n\n```java\npublic interface Async {\n\n    @Timeout(value = 3, unit = TimeUnit.SECONDS)\n    Future\u003cString\u003e hello(String name);\n\n```\n\nIt is also possible to configure timeouts for all methods of async-proxy putting annotation on class:\n\n```java\n@Timeout(5000)\npublic interface Async {\n    Future\u003cLong\u003e foo1();\n    Future\u003cLong\u003e foo2();\n}\n```\n\n**IMPORTANT:** `ScheduledExecutorService` should be used to switch on this feature.\n\n## Development\n\nTo build project in strict mode with tests, you can use your local Maven:\n\n```bash\nmvn -P strict clean package\n```\n\n\n## Might also like\n\n* [jconditions](https://github.com/vbauer/jconditions) - Extra conditional annotations for JUnit.\n* [jackdaw](https://github.com/vbauer/jackdaw) - Java Annotation Processor which allows to simplify development.\n* [houdini](https://github.com/vbauer/houdini) - Type conversion system for Spring framework.\n* [herald](https://github.com/vbauer/herald) - Logging annotation for Spring framework.\n* [commons-vfs2-cifs](https://github.com/vbauer/commons-vfs2-cifs) - SMB/CIFS provider for Commons VFS.\n* [avconv4java](https://github.com/vbauer/avconv4java) - Java interface to avconv tool.\n\n\n## License\n\nCopyright 2015 Vladislav Bauer\n\nLicensed under the Apache License, Version 2.0 (the \"License\");\nyou may not use this file except in compliance with the License.\nYou may obtain a copy of the License at\n\n    http://www.apache.org/licenses/LICENSE-2.0\n\nUnless required by applicable law or agreed to in writing, software\ndistributed under the License is distributed on an \"AS IS\" BASIS,\nWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\nSee the License for the specific language governing permissions and\nlimitations under the License.\n\nSee [LICENSE](LICENSE) file for details.\n","funding_links":[],"categories":["并发编程"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvbauer%2Fcaesar","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvbauer%2Fcaesar","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvbauer%2Fcaesar/lists"}