Register Business Configuration - hiforce/lattice GitHub Wiki
Background
In the previous Business Overlay Product, we enabled the simple mode. And in starting Lattice, we have the following code:
public static void main(String[] args) {
Lattice.getInstance().setSimpleMode(true);
.......
}
The function of this line of code is to automatically generate and load the business configuration into memory when Lattice starts. The code location of the automatic build configuration: org.hiforce.lattice.runtime.Lattice#autoBuildBusinessConfig, see below:
private void autoBuildBusinessConfig() {
List<ProductConfig> productConfigs = getAllRegisteredProducts().stream()
.map(this::buildProductConfig)
.collect(Collectors.toList());
for (BusinessSpec businessSpec : getAllRegisteredBusinesses()) {
if (businessConfigs.stream()
.anyMatch(p -> StringUtils.equals(p.getBizCode(), businessSpec.getCode()))) {
continue;
}
List<ExtPriorityConfig> priorityConfigs = businessSpec.getRealizations().stream()
.flatMap(p -> autoBuildPriorityConfig(businessSpec, p).stream())
.filter(Objects::nonNull)
.collect(Collectors.toList());
BusinessConfig businessConfig = BusinessConfigBuilder.builder()
.priority(businessSpec.getPriority())
.bizCode(businessSpec.getCode())
.install(productConfigs)
.extension(priorityConfigs)
.build();
businessConfigs.add(businessConfig);
}
}
Generally speaking, it is more convenient to use simple mode during development, but there are some hidden dangers:
- Because in the AppStore, hundreds of product plug-ins will eventually be deposited, and not every product plug-in needs to be installed for business. Automatic configuration is the default business needs to install all product plug-ins. This will lead to a business call, it is necessary to traverse all products and determine whether the product is effective, which will be very time-consuming;
- In the extension point call, if there are multiple custom logic implementations, under the Reduce strategy of FIRST, the product priority will be very sensitive. The auto-assembled products are sorted in ascending order according to their own priorities (500 by default) (the smaller the number, the higher the priority). In the case of the same priority, the final sorting result will be related to the class loading order of the JVM. If the product is not designed with sufficient exclusivity, there will be major hidden dangers for the certainty of business execution;
- If the product plugin in the AppStore is provided by the same team, it is relatively easy to solve it by explicitly declaring the priority in the @Product annotation. However, when multiple teams and ecological cooperation can participate in contributing product plug-ins, priority conflicts are more likely to occur.
- Even if the product has an explicit priority declaration, in the actual complex business operation, it will be found that the priority requirements of business A and business B for the two installed products will be diametrically opposite, so this automatic configuration method is not applicable.
Therefore, in the production environment, for the certainty of the business, we can use the code method or read the configuration method from the database to load the business configuration. This business configuration can be visualized in the future. Everyone can clearly see how the business is defined and which product plug-ins are installed in this business. At what points will the installed products conflict, and what is the priority of this conflict? This will be of great help to the transfer of business knowledge, troubleshooting, and ecological construction.
Step 1: Build a calling process without business configuration
public class LoadBusinessConfigSample {
public static void main(String[] args) {
Lattice.getInstance().start();
System.out.println("---------------------------------------");
LatticeOverlayProductSample.doBusiness("groupBy");
System.out.println("---------------------------------------");
}
}
Because simple mode is not enabled, the result of calling the above code is as follows:
---------------------------------------
Lattice extension invoke error. Due to the business config is null. bizCode: [business.b]
---------------------------------------
Step 2: Build the configuration for "business.b"
private static BusinessConfig buildBusinessBConfig() {
return BusinessConfigBuilder.builder()
.bizCode(BusinessB.CODE)
.build();
}
Through the Builder constructor of BusinessConfig, we can create a configuration for the business whose business identity is "business.b".
Step 3: Install "GroupByProduct" for "business.b"
We continue to modify the above code and install product plugins for the business through ProductConfigBuilder, as follows:
private static BusinessConfig buildBusinessBConfig() {
return BusinessConfigBuilder.builder()
.bizCode(BusinessB.CODE)
.install(GroupBuyProduct.CODE)
.build();
}
Step 4: Assign priority (i.e. call order) to conflicting extension points
In our example, the "custom item unit price" extension point is implemented by multiple business customizations, which are conflicting. Here, we can specify the priority to make the product a higher priority. In this way, but the product is in the effective state, the custom logic of the product will be called first. as follows:
public class LoadBusinessConfigSample {
public static void main(String[] args) {
Lattice.getInstance().start();
Lattice.getInstance().addBusinessConfig(buildBusinessBConfig());//register business configuration.
System.out.println("---------------------------------------");
LatticeOverlayProductSample.doBusiness("groupBy");
System.out.println("---------------------------------------");
}
private static BusinessConfig buildBusinessBConfig() {
return BusinessConfigBuilder.builder()
.bizCode(BusinessB.CODE)
.install(GroupBuyProduct.CODE)
.extension(
PriorityConfigBuilder.builder()
.extCode(EXT_ORDER_LINE_CUSTOM_UNIT_PRICE)
.priority(GroupBuyProduct.CODE, PRODUCT)
.priority(BusinessB.CODE, BUSINESS)
.build())
.build();
}
}
At this point, a sample of self-registered business configuration can be executed, and the execution result can be found to be product priority. The results are as follows:
---------------------------------------
GroupBuyProduct effect status:true
[Business B] overlay product unit price: 700
---------------------------------------
Of course, readers can also change the order of the above priority registration places to the priority of the business before the priority of the product, as follows:
private static BusinessConfig buildBusinessBConfig() {
//Adjust the priority to see the effect!
return BusinessConfigBuilder.builder()
.bizCode(BusinessB.CODE)
.install(GroupBuyProduct.CODE)
.extension(
PriorityConfigBuilder.builder()
.extCode(EXT_ORDER_LINE_CUSTOM_UNIT_PRICE)
.priority(BusinessB.CODE, BUSINESS)
.priority(GroupBuyProduct.CODE, PRODUCT)
.build())
.build();
}
Execute this example again, the execution result will become:
---------------------------------------
GroupBuyProduct effect status:true
[Business B] overlay product unit price: 1000
---------------------------------------
The sample code can be obtained by visiting: https://github.com/hiforce/lattice-sample/tree/main/lattice-business-config