This componentized solution is open source on Github, welcome to reprint and star. Github.com/beyondxia/m…

Problem of traditional componentization scheme

In the previous part, we briefly introduced the implementation principle of the traditional componentization scheme, and analyzed its advantages and disadvantages. The scheme of interface communication mechanism has the following disadvantages: a. A public directory or public module needs to be provided as the service layer, and all interface files and intermediate shared files need to be manually copied to the service layer. B. If a component needs to provide services, it needs to provide one or more intermediate interface files in addition to its own implementation class, which increases the amount of development, complexity of component integration and maintenance cost. C. Since the service implementation class is dependent on the service interface, the business side needs to implement the exposed interface and realize the specific business functions to be exposed. D. All component services need to be registered manually, which increases the amount of development and risks. E. Some intermediate classes associated with the interface (especially Model) also need to be synchronously sunk to the public directory.

Optimization scheme

1. APT generates interface files

If the interface file can be automatically generated and copied, then the problem is solved. How to do that? As we know, APT(Annotation Processing Tool for short) can parse annotations during code compilation and generate new Java files, which can reduce manual code input. This framework uses APT to automatically generate interface files. All the user needs to do is to add annotations (@exportMethod) to the services that need to be exposed and the methods in the services that need to be exposed. APT will automatically generate interfaces based on the annotations. As shown in the figure below, Message is the service class provided by the component, and IMessage is the generated interface.

2. Javassist modiates the bytecode

APT can generate external exposed interface, then what we need to do is to let the business side to implement the interface, and complete the real function realization, then how to do? In fact, from the code level, we only need the Message class to implement IMessage. Since Message is implemented internally before the IMessage interface is generated, the best way to modify Message is to modify message.class bytecode at compile time. Javassist is a library that performs bytecode operations. It can add new methods, members, implement an interface, inherit a parent class, and so on to an already compiled class. Javassist meets our needs. Message implements IMessage by modifying the bytecode during compilation. In this way, the relationship between the Message service class and IMessage service interface class is realized.

This has another advantage: if the version of the service class is upgraded, the framework can achieve silent automatic synchronization of the service interface through APT and Gradle Transform technology, completely unaware of the component developers, developers only need to focus on developing their own component business.

3. APT completes collection and registration of components

For shortcomings d: the framework collects service classes marked by ExportService annotations through APT technology, and automatically registers them when the framework is initialized. Developers do not need to participate in registration work at all. In addition, we provide different instantiation opportunities according to service usage scenarios and frequency, which can be configured on annotations according to component usage scenarios.

4. Customize BCDictionary instead of traditional Model

In view of shortcomings e: We do not advocate the data transmission between components by self-defined model, but it is inevitable to transmit data types of complex types. Of course, existing serialization methods can be selected for transmission, such as JSON, but the developers need to do a lot of tedious operations in serialization and deserialization. To this end, the framework provides an easy-to-use way to transfer complex types of data, greatly simplifying serialization and deserialization operations.

Other questions:

If complex data structures need to be shared between components for business purposes, for example:

Through the scheme introduced above, the framework basically solves the shortcomings of interface communication. Most of the work has already been done by the framework at the compile stage, which greatly reduces the cost of business access, minimizes the code intrusion, and allows developers to focus on component functionality.

The problem of traditional componentization scheme for a Low – intrusive componentization Scheme