[Open Source] A Powerful and Easy-to-Use Data Population Framework That Handles Property Mapping Requirements with Just a Few Annotations

Open SourceProcess Management
2026-06-28 04:29 3 次浏览 • 0 次下载 0KB
[Open Source] A Powerful and Easy-to-Use Data Population Framework That Handles Property Mapping Requirements with Just a Few Annotations

1. Project Overview

Crane4j

A simple and easy-to-use data mapping framework that quickly populates related fields based on foreign keys or code values through simple annotation-based configuration. Supports multiple data sources, including dictionaries, enums, and methods.

A powerful and easy-to-use data population framework that handles all your needs involving "retrieving B using the key value of A, then mapping B's properties to A" with just a few annotations.

2. Open Source License

Licensed under Apache-2.0

3. Screenshots

4. Feature Overview

What Is It?

In our daily development work, we often face tedious data assembly tasks:Retrieving related data based on the value of a specific property of an object and mapping it to another object's properties. These requirements often involve dictionary entries, configuration items, enum constants, and even database table queries. Such data population tasks are often time-consuming and labor-intensive, and they tend to generate repetitive boilerplate code that can be frustrating to maintain.

crane4j was created to solve these frustrations. It is an annotation-driven data population framework. With simple annotation-based configuration, crane4j can elegantly and efficiently handle field population across different data sources, types, and naming conventions, allowing you to focus on core business logic without being distracted by tedious data assembly tasks.

What Features Does It Offer?

  • Support for Multiple Data Sources: Supports enums, key-value caches, and methods as data sources. Additional data source types can be supported through simple custom extensions. Caching is also available for all data sources;
  • Powerful Field Mapping Capabilities: Automatically maps and converts fields of different types through annotations. It also supports features such as templates, sorting, grouping, and nested object population;
  • Highly Extensible: Users can freely replace all major components. Combined with Spring's dependency injection, this enables easy and elegant custom extensions;
  • Rich Optional Features: Provides optional features such as automatic population of method return values and method parameters, multithreaded population, custom annotations and expressions, and database framework plugins;
  • Plug and Play: Easily integrates with spring/springboot through simple configuration and can also be used in non-spring environments;

5. Tech Stack

Quick Start

Add the Dependency


<dependency>
    <groupId>cn.crane4j</groupId>
    <artifactId>crane4j-spring-boot-starter</artifactId>
    <version>${last-version}</version>
</dependency>

Enabling the Framework

Add @EnableCrane4j to your main application class or configuration class to enable auto-configuration. You can also configure the scanning paths for enum and constant classes here:


@EnableCrane4j(
    constantPackages = "com.example.demo", // Scan constant classes
    enumPackages = "com.example.demo"  // Scan enum classes
)
@SpringBootApplicationpublic 
public class Application {   
    public static void main(String[] args) {  
        SpringApplication.run(Application.class, args); 
    }
}

Configuring Data Sources

crane4j can usemethods, enums, constants, expressions, various ORM frameworks, and even the objects being populated themselves as data sources. Here, we use methods, enums, and constants as examples:


@Component
public void OperationDataSource {
    
    // 1. Use an instance method directly as the "method" data source
    @ContainerMethod(namespace = "method", resultType = Foo.class)
    public List<Foo> getFooList(Set<Integer>ids) {
        return ids.stream()
            .map(id -> new Foo(id).setName("foo" + id))
            .collect(Collectors.toList());
    }

    // 2. Use a scanned enum class as the "enum" data source
    @ContainerEnum(namespace = "enum", key = "code")
    @Getter
    @RequiredArgsConstructor
    public enum Gender {
        MALE(1, "Male"),
        FEMALE(0, "Female");
        private final Integer code;
        private final String name;
    }

    // 3. Use a scanned constant class as the "constant" data source
    @ContainerConstant(namespace = "constant", reverse = true)
    public static final class Constant {
        public static final String A = "1";
        public static final String B = "2";
        public static final String C = "3";
    }
}

Declaring Population Operations

Simply add annotations to fields to declare population operations based on the data sources configured above. Supports one-to-one, one-to-many, and even many-to-many property mappings:


@Data
@Accessors(chain = true)
@RequiredArgsConstructor
public static class Foo {

    // 1. Retrieve the corresponding object from the method based on the id, then map its name to the current name field
    @Assemble(container = "method", props = @Mapping("name"))
    private final Integer id;
    private String name;

    // 2. Map its own name property to fooName
    @Assemble(props = @Mapping(src = "name", ref = "fooName"))
    private String fooName;

    // 3. Retrieve the corresponding enum object based on gender, then map its name property to the current genderName field
    @Assemble(
        container = "enum", props = @Mapping(src = "name", ref = "genderName")
    )
    private Integer gender;
    private String genderName;

    // 4. Retrieve corresponding values from constants in batches based on the set of keys, then map them in batches to the current values field
    @Assemble(
        container = "constant", props = @Mapping(ref = "values"),
        handlerType = ManyToManyAssembleOperationHandler.class
    )
    private Set<String> keys;
    private List<String> values;
}

Executing Data Population

Use OperateTemplate to quickly complete data population. You can also add @AutoOperate to a method to automatically populate its return value. Here, we use manual population as an example:


@Autowired
public OperateTemplate operateTemplate; // Inject the utility class for quick data population

public void doOperate() {
    List<Foo> targets = IntStream.rangeClosed(1, 2)
        .mapToObj(id -> new Foo(id)
      .setGender(id & 1)
      .setKeys(CollectionUtils.newCollection(LinkedHashSet::new, "1", "2", "3"))
        ).collect(Collectors.toList());
    // Populate objects
    operateTemplate.execute(targets);
}

Result:


[
    {
        "id": 1,
        "name": "foo1",
        "fooName": "foo1",
        "gender": 1,
        "genderName": "Male",
        "keys": ["1", "2", "3"],
        "values": ["A", "B", "C"]
    },
    {
        "id": 2,
        "name": "foo2",
        "fooName": "foo2",
        "gender": 0,
        "genderName": "Female",
        "keys": ["1", "2", "3"],
        "values": ["A", "B", "C"]
    }
]

These are the simplest steps for using crane4j in a Spring Boot environment. For more usage examples, please refer to the official documentation.


[Free Book Giveaway]

Win a Book in Our Giveaway, with Free Shipping to Your Door!

Thank you for being with us throughout this journey!

Please visit the [Yifei Open Source] official WeChat account for details.




#1
资源直链https://gitee.com/opengoofy/crane4j
去下载
星河码客

发现和分享优质开源项目,传承互联网精神,为开发者服务。

关于本站

联系我们

微信/广告合作:ITcloub (备注星河码客)

免责声明:本站资源版权归原作者所有,仅供学习与交流。如有侵权,请通过「关于我们 - 侵权投诉」联系删除。

Powered by Nuxt · Deployed on Cloudflare