Blog: bugstack.cn

Precipitation, share, grow, let yourself and others can gain something! 😄

One, foreword

Why do we build wheels?

The core purpose of building wheels is to condense and reuse common problems.

Although there are a large number of mature and stable wheels for supporting system construction in the market, namely services, frameworks, components, tools, etc., for some larger companies, these wheels may not be able to support the service volume that the system needs to bear, so they need to build some wheels by themselves.

And the advocated not to repeat the wheel, the new wheel can not guarantee stability. It is generally suitable for core wheels launched on the official website, such as SpringBoot, Netty, HBase, etc. But for some special scenarios of solution tool-like components, there is usually no fully compliant wheel, like SpringBoot scaffolding.

In fact, every large company has many components of similar technical services, such as RPC, database routing, registry, distributed tasks, MQ queue messages, etc., and scaffolding development needs to adapt these components to build a system architecture that meets the needs of the implementation of the company’s technology stack. This is different from some smaller Internet companies that can use the full suite of solutions provided by SpringBoot

In addition, the wheel is a precipitation of personal technology, but also the accumulation of salary! Don’t say you can’t build a plane, you just didn’t provide a venue!

What kind of scene could make a wheel?

All modules used in an architectural infrastructure can be wheels, and we are usually in these scenarios: load balancing, service gateway, service governance, framework language, service components, data hosting, framework architecture, deployment mode, tool plug-ins, the wheels needed to build.

In fact, a more mature Internet company, most of the scene under the wheel, has been basically built. The rest are generally generic components that address non-business logic in business scenarios, such as cache hot keys under high concurrency, Redis layer routing, non-unique short code generation for event invitations, and the like. However, the wheel construction of such scenarios is also very valuable. After stable use at the company level, it can also be promoted to the market to gain certain recognition, and better will be included in the Apache project.

What is scaffolding?

What is scaffolding? Is it a term for a particular platform?

Scaffolding is a meta-programming method of building database-backed software applications. It is a technique supported by some model-view-controller frameworks, in which the programmer may write a specification that describes how the application database may be used. The compiler uses this specification to generate code that the application can use to create, read, update and delete database entries, effectively treating the template as a “scaffold” on which to build a more powerful application.

  • Stackoverflow.com/questions/2…

Scaffolding, combined with answers on StackOverflow, is a metaprogramming approach for building data-based applications. The programmer who creates the system architecture writes a specification that describes how to use the database. Scaffolding can generate framework code from this specification. We turn this model into a scaffold and build powerful applications more efficiently on the scaffold!

In other words, it simplifies the simple work of repeating common operations, eliminating the need for programmers to paste and copy a little bit and clone an existing architecture. An application development framework can be created by passing in the necessary parameters to the interface or common interface.

Who provides the scaffolding?

1. Spring official website scaffolding

  • Recommendation: ⭐ ⭐ ⭐ ⭐
  • Link: start. Spring. IO
  • Source: github.com/spring-io/s…
  • Spring Initializr is essentially a Web application, which can build a basic Spring Boot project structure through the Web interface, Spring Tool Suite, IntelliJ IDEA, etc.You can also use its source code for local deployment

Ali Cloud scaffolding

  • Recommendation: ⭐ ⭐ ⭐ ⭐
  • Link: start. Spring. IO
  • Description: Aliyun Java Initializr and Spring Initializr are the same kind of Web services, is a code framework generator, one click to generate your code framework, has a complete tool chain, free IDEA plug-in, easy to generate directly in IDE. At the same time, it is also very suitable for the network environment of domestic users.

In fact, both scaffolds are very good at generating a project structure that allows programmers to quickly enter the development environment under uniform standards. Just choose a different framework depending on the support services you choose.

Four, hand lift a scaffold!

There's scaffolding, so why do it yourself?

The purpose of scaffolding is to quickly build a system framework under a unified standard, and introduce the configuration, components, services and tests needed in the process of system development into the system development through configuration.

But sometimes the scaffolding common to Internet companies is not appropriate because it does not incorporate some of the proprietary components of the company and does not blend well. If you have to copy in a large number of specific components after scaffolding has been generated, you destroy the scaffolding itself, and you break the rules and specifications.

Therefore, it is necessary to combine the development capabilities of scaffolding to package various specific components, services, and configurations to achieve a unified scaffolding that fits the company’s domain.

So, this chapter takes you through a scaffolding, how to develop the implementation. It’s not too complicated, we can use Freemarker’s power to build the system framework.

1. Engineering framework

EasyRiggerInitializr └ ─ ─ the SRC ├ ─ ─ the main │ ├ ─ ─ Java │ │ └ ─ ─ cn. Bugstack. Initializr. The rigger │ │ ├ ─ ─ application │ │ │ └ ─ ─ IProjectGenerator. Java │ │ ├ ─ ─ domain │ │ │ ├ ─ ─ model │ │ │ │ └ ─ ─ ApplicationInfo. Java │ │ │ │ └ ─ ─ ProjectInfo. Java │ │ │ ├─ ├─ │ ├─module│ │ │ │ ├ ─ ─ impl │ │ │ │ │ ├ ─ ─ GenerationApplication. Java │ │ │ │ │ ├ ─ ─ GenerationIgnore. Java │ │ │ │ │ ├ ─ ─ GenerationPackageInfo. Java │ │ │ │ │ ├ ─ ─ GenerationPom. Java │ │ │ │ │ ├ ─ ─ GenerationTest. Java │ │ │ │ │ └ ─ ─ GenerationYml. Java │ │ │ │ └ ─ ─ BaseModule. Java │ │ │ └ ─ ─ ProjectGeneratorImpl. Java │ │ └ ─ ─ RiggerApplication. Java │ └ ─ ─ Resources │ ├── Generator │ ├─ Application. FTL │ ├─ ignorepackage- info. FTL │ │ ├ ─ ─ pom. The FTL │ │ ├ ─ ─ test. The FTL │ │ └ ─ ─ yml, FTL │ └ ─ ─ application. Yml └ ─ ─ the test └ ─ ─ Java └ ─ ─ Cn. Bugstack. Initializr. Rigger. Test └ ─ ─ ApiTest. JavaCopy the code

The entire scaffolding project is not complicated, and the main thing is to generate the corresponding system framework from FTL template files defined by Freemarker. This includes: project main body, framework structure, startup class, configuration file, test class, etc., can also be combined with their own requirements to generate the corresponding ORM class and mapping relationship.

The entire project structure is partial to the DDD hierarchy, the domain domain has all the generation methods built, resources/ Generator defines the generation templates, and there is not much difference elsewhere.

Next, a brief introduction to the code of this project, so that we can understand how to develop such a project, but also through this project to continue to improve the structure of their own needs.

2. The application layer defines the generated class interface

cn.bugstack.initializr.rigger.application.IProjectGenerator.java

public interface IProjectGenerator {

    void generator(ProjectInfo projectInfo) throws Exception;

}
Copy the code
  • The DDD hierarchy usually defines the interface in the application layer, which is relatively thin, and then implements the corresponding domain layer.
  • This interface is defined primarily to allow external callers to create engineering frameworks through this interface.

3. FTL template definition

What is a FreeMarker?

FreeMarker is a template engine: a generic tool for generating output text (HTML web pages, emails, profiles, source code, etc.) based on templates and data to change. It is not intended for the end user, but is a Java class library, a component that programmers can embed in the product they are developing.

The Template is written as FreeMarker Template Language (FTL). It is a simple, dedicated language, not a mature programming language like PHP. That means preparing data to be displayed in a real programming language, such as database queries and business operations, and then templates to display the prepared data. In the template, you can focus on how to present the data, and outside the template you can focus on what data to present.

  • FreeMarker online handbook: freemarker.foofun.cn

3.1 application. FTL

package ${packageName};

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class ${className} {

    public static void main(String[] args) { SpringApplication.run(${className}.class, args); }}Copy the code

3.2 the pom. FTL

<? xml version="1.0" encoding="UTF-8"? > <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0. 0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId>  <version>2.16..RELEASE</version> <relativePath/> <! -- lookup parent from repository --> </parent> <groupId>${groupId}</groupId> <artifactId>${artifactId}</artifactId> <version>${version}</version> <name>${name}</name> <description>${description}</description> </project>Copy the code

3.3 yml. FTL

server:
  port: 8081
Copy the code

The above is just the basic FTL file used to generate framework files. If you need some special judgment and logic, you can refer to FreeMarker’s online manual to write your own FTL files.

4. FTL generated file

cn.bugstack.initializr.rigger.domain.service.module.impl.GenerationApplication.java

@Service
public class GenerationApplication extends BaseModule {

    private Logger logger = LoggerFactory.getLogger(GenerationApplication.class);

    public void doGeneration(ProjectInfo projectInfo, String projectsRoot, String lastPackageName, StringBuffer applicationJavaName) throws Exception {

        ApplicationInfo applicationInfo = new ApplicationInfo(
                projectInfo.getGroupId() + "." + lastPackageName,
                applicationJavaName.toString()
        );

        String packagePath = applicationInfo.getPackageName().replace("."."/") + "/";

        File file = new File(projectsRoot + projectInfo.getArtifactId() + "/src/main/java/" + packagePath,
                applicationInfo.getClassName() + ".java");

        // Write to the file
        super.writeFile(file, "application.ftl", applicationInfo);

        logger.info("Create main entry class application.java {}", file.getPath()); }}Copy the code
  • The use of FTL files is basically universal, regardless of the layer used to generate the file. This is just about the creation of application.java.
  • It basically includes the definition of input parametersApplicationInfo, define the file location/src/main/java/, and write to a filesuper.writeFileThese three aspects.

5. Create a frame entry

cn.bugstack.initializr.rigger.domain.service.ProjectGeneratorImpl.java

@Service
public class ProjectGeneratorImpl implements IProjectGenerator {

    private Logger logger = LoggerFactory.getLogger(ProjectGeneratorImpl.class);

    @Resource
    private GenerationApplication generationApplication;
    @Resource
    private GenerationYml generationYml;
    @Resource
    private GenerationPom generationPom;
    @Resource
    private GenerationTest generationTest;
    @Resource
    private GenerationIgnore generationIgnore;
    @Resource
    private GenerationPackageInfo generationPackageInfo;

    @Override
    public void generator(ProjectInfo projectInfo) throws Exception {

        URL resource = this.getClass().getResource("/");
        String projectsRoot = resource.getFile() + "/projects/";

        String lastPackageName = projectInfo.getArtifactId().replaceAll("-"."").toLowerCase();
        // Startup class name
        String[] split = projectInfo.getArtifactId().split("-");
        StringBuffer applicationJavaName = new StringBuffer();
        Arrays.asList(split).forEach(s -> {
            applicationJavaName.append(s.substring(0.1).toUpperCase() + s.substring(1));
        });
        applicationJavaName.append("Application");

        // 1. Create application.java
        generationApplication.doGeneration(projectInfo, projectsRoot, lastPackageName, applicationJavaName);

        // 2. Generate application.yml
        generationYml.doGeneration(projectInfo, projectsRoot);

        // 3. Generate pom.xml
        generationPom.doGeneration(projectInfo, projectsRoot);

        // 4. Create test class apitest.java
        generationTest.doGeneration(projectInfo, projectsRoot, lastPackageName, applicationJavaName);

        // 5. Generate.gitignore
        generationIgnore.doGeneration(projectInfo, projectsRoot);

        // 6. DDD 4-layer description filegenerationPackageInfo.doGeneration(projectInfo, projectsRoot, lastPackageName, applicationJavaName); }}Copy the code

The ProjectGeneratorImpl class is a domain-level implementation of the application layer interface IProjectGenerator. This includes the following:

  1. Create Application. Java
  2. Generate application. Yml
  3. Generate the pom. XML
  4. Create the test class apitest.java
  5. Generate the gitignore
  6. DDD four layer description file

In summary, this is a brief introduction to the whole scaffold generation. In fact, it is not much complicated, mainly the definition and use of FTL files, this way to create scaffolding is very convenient.

6. Test and verify

Unit testing

@Test
public void test_IProjectGenerator(a) throws Exception {
    ProjectInfo projectInfo = new ProjectInfo(
            "cn.bugstack.demo"."web-test"."1.0.0 - the SNAPSHOT"."web-test"."Demo project for Spring Boot"
    );
    iProjectGenerator.generator(projectInfo);
}
Copy the code

The test results

  • Scaffolding generates the created project to test-classes, and this path can be configured to other paths.
  • The newly generated project can be opened through IDEA, which is the same as the project we created manually.

Download the source code

  • Source code download:Bugstack wormhole stackReply:The scaffold
  • Project introduction: SpringBoot scaffolding simplifies project construction. At present, the project is relatively simple, which is very suitable for newcomers to learn and use. In the future, we will continue to improve some functions based on this version, integrating RPC, MQ, registry, gateway, and other components to facilitate selective construction and extension.

Six, summarized

  • From the perspective of the company, it is for the cost of responsibilities and resources of each department not to repeat the wheel, but for individuals, we should not give up the opportunity of in-depth learning of the knowledge stack just because we do not repeat the wheel.
  • Without this fundamental learning, there would be no understanding of technology migration, service extraction, and component refinement. Always do some API application packaging over and over again, there is no personal technical growth.
  • At the end of the day, even if the company doesn’t need you to build the wheel, you can build it yourself and share it with the Github community. On the one hand, it is the summary of their own learning, on the other hand, it is also the precipitation and contribution to the technology.

Seven, series recommendation

  • Scheme design: Based on IDEA plug-in development and bytecode staking technology, realize automatic analysis of r&d delivery quality
  • Technical literacy: Design and analysis for sustainable delivery of low-code programming
  • Have you been working for two or three years and have no idea what the architecture diagram is?
  • The evolution of the Internet architecture
  • Domain-driven design architecture builds microservices based on SpringCloud