https://github.com/askmeagain/lazygen
Java Code Generator to add Lazy/Caching methods to any class/interface. Also compatible with MapStruct!
https://github.com/askmeagain/lazygen
codegeneration java
Last synced: 5 months ago
JSON representation
Java Code Generator to add Lazy/Caching methods to any class/interface. Also compatible with MapStruct!
- Host: GitHub
- URL: https://github.com/askmeagain/lazygen
- Owner: AskMeAgain
- License: mit
- Created: 2022-03-13T20:48:27.000Z (almost 4 years ago)
- Default Branch: master
- Last Pushed: 2022-03-27T13:46:00.000Z (almost 4 years ago)
- Last Synced: 2025-06-04T12:46:46.147Z (7 months ago)
- Topics: codegeneration, java
- Language: Java
- Homepage:
- Size: 262 KB
- Stars: 0
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# LazyGen
This annotation processor adds a lazy/cacheable method to any non-final method annotated with `@LazyGen` via code
generation.
Note: A Lazy/Cacheable method is a method which only executes its body once and keeps a copy of the result in memory.
## Gradle
annotationProcessor 'io.github.askmeagain:lazygenprocessor:1.2.1'
implementation 'io.github.askmeagain:lazygenprocessor:1.2.1'
## Getting Started
1. Add LazyGen package and annotation processor to your project
2. Add `@GenerateLazyClass(ResultType.XXX)` to a class (or interface in case
of [MapStruct mapper](https://github.com/mapstruct/mapstruct))
3. Specify how your result should look like:
1. `ResultType.CLASS`: Creates a normal class which extends the original class
2. `ResultType.ABSTRACT_CLASS`: Creates an abstract class which extends/implements the interface
3. `ResultType.MAPSTRUCT_COMPATIBLE`: Creates an abstract class, prepared correctly for usage with
[MapStruct](https://github.com/mapstruct/mapstruct)
4. `ResultType.MAPSTRUCT_COMPATIBLE_WITHOUT_ANNOTATIN` is the same as step 3, but the @Mapper annotation is not added
4. Add `@LazyGen` to any method on this class and any childs (class or interface doesnt matter)
5. Hit build
6. A class is generated which inherits the original class, with Lazy as suffix
## OneTimeUsage vs MultiUsage
You can also specify how the caching should be implemented:
* `ONE_TIME_USE`: returns always the same (cached) value, ignoring the input parameters
* `MULTI_USE`: will cache the result of the method in a map based on a key. The key is calculated via
`hashCode()` of the input parameters
* `PARENT`: default on `@LazyGen` methods, use what the `@GenerateLazyClass` specified (by default `ONE_TIME_USE`)
You can configure a general usage, via `@GenerateLazyClass(usage = ONE_TIME_USE)`, but each `@LazyGen` method can
override this behaviour by themselves.
## Making MapStruct lazy
1. Add `@GenerateLazyClass(ResultType.MAPSTRUCT_COMPATIBLE)` to your mapstruct mapper
2. Remove `@Mapper` annotation from your mapper
3. Add `@LazyGen` to any method
4. Get your MapStruct mapper via `Mappers.getMapper(XXXXXXLazy.class);`
Note: Methods which are touched by the MapStruct annotation processor can only be made lazy if they are
implemented/referenced via `@Named` annotation or else MapStruct cannot find the correct method since the `@Named`
annotation is not inheritable.
## Examples
### Simple Example
Before
@GenerateLazyClass
public class NormalClass {
@LazyGen
String abc(){
return "Test";
}
}
After
public class LazyNormalClass extends NormalClass {
private java.lang.String _abc;
@Override
public java.lang.String abc() {
if (_abc != null) {
return _abc;
}
_abc = super.abc();
return _abc;
}
}
### MapStruct Example
Before
@GenerateLazyClass(ResultType.MAPSTRUCT_COMPATIBLE)
public interface TestMapper {
@Mapping(target = ".", source = "input", qualifiedByName = "a")
String mapSummations(String input);
@LazyGen
@Named("a")
default String a(TestMapper calculator) {
System.out.println("a");
return "a";
}
}
After
@Mapper
public abstract class LazyTestMapper implements TestMapper {
@Named("a")
@Override
public java.lang.String a(io.github.askmeagain.lazygen.calculator.simple.MapstructAbstractClass _TestMapper0) {
if (_a != null) {
return _a;
}
_a = TestMapper.super.a(_TestMapper0);
return _a;
}
private java.lang.String _a;
}