Introduction to LiteFlow
LiteFlow
an
Lightweight and powerful domestic rules engine frameworkIt can be used in the area of orchestration for complex componentized businesses. Helps make systems silky smooth and flexible. Utilizing
LiteFlow
You can transform the waterfall code into a component as the core concept of the code structure, the benefit of this structure is that it can be arbitrarily orchestrated, components are decoupled from each other, components can be defined by scripts, and the flow between components is driven by rules.
LiteFlow
With the simplest open source rules engine
DSL
Grammar.
LiteFlow Official Website
LiteFlow
in
2020
officially open-sourced in 2007.
2021
In 2007, it won the award for the most popular open source software of the year in Open Source China. In
2022
annual award
Gitee
Most valuable open source projects
GVP
Honors. It is an open source project that is in rapid development.
LiteFlow
is a community-driven project with a
2500
community of multiple users. Although compared to
Acitiviti
、
Flowable
as far as sth. is concerned
LiteFlow
is much less well known and not as powerful as these well known and established engines, but the
LiteFlow
There are still a number of advantages that will fulfill the vast majority of your scenarios. These advantages include:
[1] Diversification of rules: Rules Support
xml
、
json
、
yml
Three ways to write a rules file.
[2] Easy to use: pull a few
jar
package, implement a few interfaces, write a process orchestration file, and run it.
[3] Richly organized: Supports a variety of scheduling methods such as serial, parallel, selective, cyclic, exception handling, nested, and so on.
[4] Event Listening: Supports event triggering and state change listening, which makes it easy to extend and customize workflow processing logic.
[5] Asynchronous timeout: Supports asynchronous execution and timeout control, which can improve the concurrent processing capability and stability of the system.
[6] Scripting support: Support for all major scripting languages.
[7] Configuration sources are abundant: Support for putting process definitions into
ZK/DB/Etcd/Nacos/Redis/Apollo
and custom extensions, etc. Equivalently, dynamic configuration changes can be implemented.
[8] Customization: Highly customizable, users can freely expand and customize according to their needs
LiteFlow
The various components and functions of the
[9] Numerous scripting languages are supported: LiteFlow
Scripting components that support a wide range of scripting languages
Groovy/JavaScript/QLExpress/Python/Lua/Aviator/Java
The exact same thing as the
Java
Hit the pass and you can script any logic.
[10] Elegant thermal refresh mechanism: Rule changes, instantly change the rules of your application without restarting your application. High concurrency does not cause any misalignment of the rules being executed due to refreshing the rules.
[11] Support is widespread: It doesn’t matter if your project is based on
Springboot
,
Spring
Or any other
java
framework construction.
LiteFlow
It’s all swimmingly.
[12] Contextual isolation mechanisms: Reliable context isolation mechanism, you do not need to worry about data streaming in highly concurrent situations.
[13] Excellent performance: The framework itself consumes little additional performance; performance depends on how efficiently your components execute.
[14] Comes with simple monitoring: The framework comes with a command line monitor to know the running time ranking of each component.
Systems suitable for this technology
In every company’s system, there are always some systems with complex business logic, these systems carry the core business logic, almost every requirement is related to these core businesses, these core business business logic is lengthy, involving internal logic operations, caching operations, persistence operations, external resource retrieval, internal other systems.
RPC
Calls and so on. Over time, the project changes hands several times, and maintenance costs become higher and higher. A variety of hard code judgment, branching conditions more and more. Code abstraction, reuse rate is also getting lower and lower, the coupling between the various modules is very high. A small change in the logic will affect other modules, and complete regression testing is required to verify. If you want to flexibly change the order of business processes, you have to make major code changes for abstraction and rewrite the methods. It is almost difficult to realize the real-time hot change business process.
How to break the deadlock?
LiteFlow
Built for decoupling logic, built for orchestration, in the use of the
LiteFlow
After that, you’ll find that building a low-coupled, flexible system becomes a snap!
(ii) LiteFlow principle
If you’re rewriting or refactoring complex business logic, use theLiteFlow
The best fit. It is an orchestrated rules engine framework with component orchestration that helps decouple business code so that every piece of business is a component.
LiteFlow
The core of this approach is “process as code”, which means that business processes and code structures are tightly coupled.
LiteFlow
using a methodology based on
XML
The document’s process definition approach describes the entire workflow by defining process nodes and connecting lines. Each process node corresponds to the
Java
A method in the code, and the connecting line corresponds to the calling relationship between the methods. In this way, we can very intuitively see how the whole business process is handled, and it is easier and faster to modify the process.
![SpringBoot - LiteFlow Engine Framework SpringBoot - LiteFlow Engine Framework](https://imgs.developpile.com/imgs/c587319a68014152839ad5dd7f3294da.png)
assemblies
Real-time hot turnover, which can also add a component to a choreographed logic flow in real time, thus changing your business logic.
![SpringBoot - LiteFlow Engine Framework SpringBoot - LiteFlow Engine Framework](https://imgs.developpile.com/imgs/b6e3a283c5994974a92a4cba6ce815f3.png)
The orchestration syntax is powerful enough to orchestrate any logical flow you want for example:
III. Scenarios of use
LiteFlow
What scenarios are applicable: LiteFlow
Apply to have complex logic of the business, such as price engine, order process, etc., these businesses often have a lot of steps, these steps can be completely in accordance with the business granularity of the split into a separate component, assembly reuse changes. Use
LiteFlow
You’ll get a system that is highly flexible and scalable. Because the components are independent of each other, you can also avoid the risk of changing one thing and moving the whole body.
LiteFlow
Which scenarios are not applicable: LiteFlow
It is not suitable for the flow between role tasks, similar to the approval flow, after A approves it should be approved by B and then flow to C role. Affirmation here.
LiteFlow
Only do logic based flows, not role task based flows. If you want to do role task based flow, it is recommended to use the
flowable
,
activiti
These 2 frames.
IV. JDK Support
LiteFlow
Required minimum
JDK
Versions for
8
Support
JDK8~JDK17
All versions. If you are using
JDK11
above to ensure that
LiteFlow
The version of
v2.10.6
and above. Because
LiteFlow
from
v2.10.6
To begin with, for the
JDK11
and
JDK17
Detailed use case testing was performed, passing all of the
900
multiple test cases. While the
v2.10.6
The following versions, in
JDK11
The above is not secured by test cases. In particular, note that if you use
JDK11
and above, make sure that the
jvm
parameter plus the following parameters:
--add-opens java.base/sun.reflect.annotation=ALL-UNNAMED
V. Springboot integration process
LiteFlow
demanding
Springboot
The lowest version of
2.0
. The range of support is
Springboot 2.X ~ Springboot 3.X
. If you are using the latest
Springboot 3.X
The corresponding JDK version should also be switched to the
JDK17
。
LiteFlow
offers
liteflow-spring-boot-starter
Dependency packages to provide automated assembly
<dependency>
<groupId>com.yomahub</groupId>
<artifactId>liteflow-spring-boot-starter</artifactId>
<version>2.11.3</version>
</dependency>
Component Definition
After relying on the above
jar
After the package, you need to define and implement some components to ensure that the
SpringBoot
will scan for these components and register them into the context.
@Component("a")
public class ACmp extends NodeComponent {
@Override
public void process() {
//do your business
}
}
And so on before defining the b,c components separately:
@Component("b")
public class BCmp extends NodeComponent {
@Override
public void process() {
//do your business
}
}
@Component("c")
public class CCmp extends NodeComponent {
@Override
public void process() {
//do your business
}
}
SpringBoot Configuration File
Then, in your
SpringBoot
the
application.properties
or
application.yml
Add the configuration in the
yaml
As an example.
properties
It’s the same thing.)
liteflow:
# Rule file path
rule-source: config/flow.el.xml
#----------------- following non-required -----------------
Whether #liteflow is enabled or not, default is true.
enable: true
Whether #liteflow's banner printing is enabled or not, defaults to true.
print-banner: true
#zkNode's node, only works when using zk as a configuration source, defaults to /lite-flow/flow
zk-node: /lite-flow/flow
Maximum number of slots for #contexts, default value is 1024
slot-size: 1024
The number of threads in the #FlowExecutor's execute2Future, default is 64.
main-executor-works: 64
Custom thread pool Builder for #FlowExecutor's execute2Future, LiteFlow provides a default Builder
main-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultMainExecutorBuilder
#Customize the generation class for request IDs, LiteFlow provides a default generation class
request-id-generator-class: com.yomahub.liteflow.flow.id.DefaultRequestIdGenerator
Thread Pool Builder for #parallel nodes, LiteFlow provides a default Builder
thread-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultWhenExecutorBuilder
Maximum wait time for # asynchronous threads (only used for when), default value is 15000
when-max-wait-time: 15000
Maximum wait time for # asynchronous threads (only for when), defaults to MILLISECONDS, milliseconds
when-max-wait-time-unit: MILLISECONDS
Maximum number of threads in the global asynchronous thread pool for the #when node, default is 16
when-max-workers: 16
Maximum number of threads in the thread pool for #parallel loop subitems, default is 16
parallelLoop-max-workers: 16
# Parallel loop sub-item thread pool waiting queue number, default is 512
parallelLoop-queue-limit: 512
Thread Pool Builder for #Parallel Loop Subterms, LiteFlow provides default Builder
parallelLoop-executor-class: com.yomahub.liteflow.thread.LiteFlowDefaultParallelLoopExecutorBuilder
#when node global asynchronous thread pool waiting queue number, default is 512
when-queue-limit: 512
# Whether to parse rules at startup, default is true
parse-on-start: true
# global retry count, default is 0
retry-count: 0
# Whether to support mixing different types of loading methods, default is false
support-multiple-type: false
# Global default node executor
node-executor-class: com.yomahub.liteflow.flow.executor.DefaultNodeExecutor
#Whether to print the log during execution, default is true.
print-execution-log: true
# Whether to enable local file listening, the default is false.
enable-monitor-file: false
# Easy monitoring configuration options
monitor:
#Whether monitoring is enabled or not, default is not enabled
enable-log: false
# Monitor queue storage size, default value is 200
queue-limit: 200
# Monitor how much execution is delayed at the beginning, default value is 300000 milliseconds, that is 5 minutes
delay: 300000
# Monitor log prints how much time has elapsed since the execution, the default value is 300000 milliseconds, which is 5 minutes.
period: 300000
Definition of the rules document
In the meantime, you’ll have to be in
resources
lower
config/flow.el.xml
Define the rules in:
SpringBoot
The rules file is automatically loaded at startup.
<?xml version="1.0" encoding="UTF-8"?>
<flow>
<chain name="chain1">
THEN(a, b, c);
</chain>
</flow>
fulfillment
Declare the startup class:
@SpringBootApplication
// Sweep the components you defined into the Spring context
@ComponentScan({"com.xxx.xxx.cmp"})
public class LiteflowExampleApplication {
public static void main(String[] args) {
SpringApplication.run(LiteflowExampleApplication.class, args);
}
}
You will then be able to add the
Springboot
arbitrarily
Spring
Hosted class to get the
flowExecutor
, performs the execution of the link: this
DefaultContext
is the default context, and the user can use the most own arbitrary
Bean
Passed in as a context, if you need to pass in your own context, you need to pass in the user
Bean
the
Class
causality
@Component
public class YourClass{
@Resource
private FlowExecutor flowExecutor;
public void testConfig(){
LiteflowResponse response = flowExecutor.execute2Resp("chain1", "arg");
}
}
VI. Data context
A data context instance is assigned to this request when the executor executes the process. The data context instances for different requests are completely isolated. It holds all the user data for this request. No parameters are passed between different components, all data interactions are realized through this data context.
The concept of data context is used in theLiteFlow
It’s very important in the framework that all your business data is placed in a data context.To be programmable, it must eliminate the variability of each component. If every component’s outgoing and incoming parameters are inconsistent, then it can’t be orchestrated.
LiteFlow
This has a unique design concept, usually we write a waterfall program, A call B, then A must be B need to pass the parameters to B, and in the
LiteFlow
The framework system is defined in such a way that each component is not required to accept parameters and returns nothing.
Each component only needs to get the data it cares about from the data context, without caring who provides this data, and similarly, each component only needs to put the resultant data from its own execution into the data context, without caring to whom this data is actually provided. In this way, a certain degree of decoupling from the data level. Thus achieving the purpose of programmability.About this idea, also in
LiteFlow
The design principles in the brief are mentioned, and a visual example is given, so you can go back and look at it again.
Once the data is put in the data context, it is fetchable by any node in the entire link.
default context
LiteFlow
Provides an implementation of the default data context:
DefaultContext
. This default implementation actually has the main container for storing data inside is a
Map
. You can find out more about this by going to
DefaultContext
hit the nail on the head
setData
method into the data via the
getData
method to get the data.
::: warning
DefaultContext
Although it can be used, but in the actual business, with this there will be a large number of weak types, access to the data are to be strong conversion, rather inconvenient. So it is officially recommended that you implement your own data context.
:::
Custom Context
In a process, there are always some initial parameters, such as the order number, user
Id
And so on for some of the initial parameters. This time it needs to be passed in via the second parameter of the following method:
// Parameters are process IDs, no initial process entry, context type is the default DefaultContext
public LiteflowResponse execute2Resp(String chainId)
// The first parameter is the process ID and the second parameter is the process entry. The context type is the default DefaultContext
public LiteflowResponse execute2Resp(String chainId, Object param);
// The first parameter is the process ID, the second parameter is the process entry parameter, and multiple context classes can be passed in afterward.
public LiteflowResponse execute2Resp(String chainId, Object param, Class<?>... contextBeanClazzArray)
// The first parameter is the process ID, the second parameter is the process entry parameter, and you can pass in multiple contextual beans after that.
public LiteflowResponse execute2Resp(String chainId, Object param, Object... contextBeanArray)
You can use your own arbitrary
Bean
Passed in as a context.
LiteFlow
contextual
Bean
There are no requirements. A self-defined context is essentially a value object in the simplest sense of the word, and self-defined contexts are more relevant to business because they are strongly typed. You can make an incoming pass like this:
LiteflowResponse response = flowExecutor. Execute2Resp (" chain1 ", initial parameters, process CustomContext. Class);
After passing in the
LiteFlow
It will be initialized at call time to assign a unique instance of this context. You can get this context instance in the component like this:
@LiteflowComponent("yourCmpId")
public class YourCmp extends NodeComponent {
@Override
public void process() {
CustomContext context = this.getContextBean(CustomContext.class);
// Or you can use this method to get context instances, which is equivalent to the above
//CustomContext context = this.getFirstContextBean();
...
}
}
multi-context
LiteFlow
Multiple contexts are supported in the new version, initializing multiple contexts you pass in at the same time during execution. It is also possible to initialize multiple contexts in a component based on the
class
The type is easy to get. You can make passes like this:
LiteflowResponse response = flowExecutor. Execute2Resp (" chain1 ", initial parameters, process OrderContext. Class, UserContext. Class, SignContext.class);
This is how you can get the context instance in the component:
@LiteflowComponent("yourCmpId")
public class YourCmp extends NodeComponent {
@Override
public void process() {
OrderContext orderContext = this.getContextBean(OrderContext.class);
UserContext userContext = this.getContextBean(UserContext.class);
SignContext signContext = this.getContextBean(SignContext.class);
//If you only want to get the first context, and the first context is OrderContext, then you can also use this method
//OrderContext orderContext = this.getFirstContextBean();
...
}
}
Pass in the initialized context with the
LiteFlow
from
2.8.4
version onwards, allowing the user to pass in one or more already initialized
bean
as the context, instead of passing in the
class
Object. After getting the
FlowExecutor
After that, you can pass in the initialized
bean
as a context (multiple contexts are of course supported, only a single context is demonstrated here):
OrderContext orderContext = new OrderContext();
orderContext.setOrderNo("SO11223344");
LiteflowResponse response = flowExecutor.execute2Resp("chain1", null, orderContext);
::: warning
The framework does not support context
bean
and
class
Mix it up. You can either do it or you can do it.
bean
Either they all pass
class
。
:::
VII. Asynchronous Future
public Future<LiteflowResponse> execute2Future(String chainId, Object param, Class<?>... contextBeanClazzArray)
If this method is called, it is non-blocking and trying to get the
response
Please use the get
future.get()
That’s all. Also, the number of threads and the thread pool of the main executor in this mode can be customized, as configured below, the
LiteFlow
Presets have been set, or you can define your own.
liteflow.main-executor-works=64
liteflow.main-executor-class=com.yomahub.liteflow.thread.LiteFlowDefaultMainExecutorBuilder
If you define a custom thread pool, you need to create a new class and then implement the
ExecutorBuilder
Interface:
public class CustomThreadBuilder implements ExecutorBuilder {
@Override
public ExecutorService buildExecutor() {
return Executors.newCachedThreadPool();
}
}
VIII. Writing of rules
serial scheduling
If you want to execute the
a,b,c,d
With four components, you can use the THEN keyword, and it’s important to note that the
THEN
Must be capitalized.
<chain name="chain1">
THEN(a, b, c, d);
</chain>
parallel programming
If you want to execute in parallel
a,b,c
Three components that you can use
WHEN
The keyword, which needs to be noted, is
WHEN
Must be capitalized.
<chain name="chain1">
WHEN(a, b, c);
</chain>
and serial nested together: let’s use THEN and WHEN in combination to see an example:
b,c,d
The default parallels are all executed before the
e
。
<chain name="chain1">
THEN(
a,
WHEN(b, c, d),
e
);
</chain>
![SpringBoot - LiteFlow Engine Framework SpringBoot - LiteFlow Engine Framework](https://imgs.developpile.com/imgs/bc57d7a27c3b471eab7155bc4618a98e.png)
The above example should be well understood, so look at another example:
<chain name="chain1">
THEN(
a,
WHEN(b, THEN(c, d)),
e
);
</chain>
Ignore the error: WHEN
The keyword provides a subkeyword
ignoreError
(default `false“) to provide the feature of ignoring errors, used as follows:
<chain name="chain1">
THEN(
a,
WHEN(b, c, d).ignoreError(true),
e
);
</chain>
![SpringBoot - LiteFlow Engine Framework SpringBoot - LiteFlow Engine Framework](https://imgs.developpile.com/imgs/6e124de352f5454ba3c34c9f475a4689.png)
set
b,c,d
either one of the nodes has an exception, then the final
e
It will still be enforced.
Either node finishes executing first then the others are ignored: WHEN
The keyword provides a subkeyword
any
(defaults to
false
) is used to provide the property that in a parallel process, if any branch finishes first, the other branches are ignored and execution continues. It is used as follows: Assume that
e
node finishes executing first, then the node will be executed immediately, regardless of whether the other branches finish executing.
f
。
<chain name="chain1">
THEN(
a,
WHEN(b, THEN(c, d), e).any(true),
f
);
</chain>
Specifies that if any node finishes executing first, the others are ignored: LiteFlow
from
v2.11.1
Starting with the fact that the execution of a specified node in a parallel orchestration is supported ignores the other.
WHEN
Keywords add subkeywords
must
(not null), which can be used to specify any node to be waited for execution, either as a
1
or more, if all the nodes specified are completed first, then the execution continues down the list, ignoring other tasks at the same level, the usage is as follows:
must
specified
b,c
follow
b,c
is sure to be executed, if the
b,c
when all is said and done
d
has not finished executing, it is ignored and the next component is executed directly
f
。
<chain name="chain1">
THEN(
a,
WHEN(b, c, d).must(b, c),
f
);
</chain>
The above is the usage of a single node, the
must
One or more expressions can also be specified. For example:
WHEN
There is a nested
THEN
If you need to specify this expression, then you need to set a
id
,
must
You need to specify this in the
id
, it is important to note that
must
inner tube
id
, need to be enclosed in quotation marks.
<chain name="chain1">
THEN(
a,
WHEN(b, THEN(c, d).id("t1"), e).must(b, "t1"),
f
);
</chain>
Turn on WHEN thread pool isolation:
at the present time
liteflow
design aspects
when
The thread pool, if you don’t set up a custom thread pool separately, then the default thread pool is used. And this thread pool, which is the default thread pool for all
when
Common one.
LiteFlow from 2.11.1
Start by providing a
liteflow.when-thread-pool-isolate
parameter, which defaults to
false
If set to
true
The program will be turned on.
WHEN
The thread pool isolation mechanism, which means that every
when
will all have separate thread pools. This feature is useful for running complex nested
when
It is possible to increase the speed and avoid some of the locking problems.
You can configure it as follows to turn it on:
liteflow.when-thread-pool-isolate=true
Selection Arrangement
When we write business logic, we usually run into the problem of selectivity, i.e., if we return the result 1, we go to the
A
process, and if it returns result 2, it goes to the
B
process, and if it returns a result of 3, it goes to the
C
Process. It is also defined as an exclusion gateway in some process definitions. This is defined through the
LiteFLow
expressions are also very easy to implement, you can use the
SWITCH...TO
The combined keywords of the
SWITCH
Must be capitalized.
to
Both upper and lower case are acceptable.
If, depending on the component
a
to choose to execute the
b,c,d
You can declare one of them as follows:
@LiteflowComponent("a")
public class ACmp extends NodeSwitchComponent {
@Override
public String processSwitch() throws Exception {
System.out.println("Acomp executed!");
return "c";
}
}
DEFAULT keyword: LiteFlow
from
2.9.5
Starting with a new addition to the selection orchestration
DEFAULT
Keywords. Used as
SWITCH...TO...DEFAULT
. For example, the following expression:
<chain name="chain1">
SWITCH(x).TO(a, b, c).DEFAULT(y);
</chain>
as in the expression above
x
If the return is not
a,b,c
is selected by default to one of the
y
. Of course.
DEFAULT
Inside can also be an expression.
Selection of the choreographedid
Grammar: Next show a
SWITCH
middle set
THEN
and
WHEN
example. If you’ve read the chapter on selecting components, you should know that the
LiteFlow
Determine what to select by selecting the return of the component. Then if the
SWITCH
One centerfold
THEN
Then select the component if you want to select this
THEN
What should be returned?
LiteFlow
which states that each expression can have a
id
value, you can set the id value to set an expression’s
id
value. Then return this in the selection component
id
Ready to go. Usage is as follows:
<chain name="chain1">
THEN(
a,
SWITCH(b).to(
c,
THEN(d, e).id("t1")
),
f
);
</chain>
If you want to chooseTHEN
expression, then you can return thet1
:
@LiteflowComponent("b")
public class BCmp extends NodeSwitchComponent {
@Override
public String processSwitch() throws Exception {
//do your biz
return "t1";
}
}
Select the tag syntax in the orchestration: In fact, in addition to assigning values to expressions
id
In addition to the attributes, you can assign values to the expression
tag
Attributes. Usage is as follows:
<chain name="chain1">
THEN(
a,
SWITCH(b).to(
c,
THEN(d, e).tag("t1")
),
f
);
</chain>
If you want to choose
THEN
This expression, then you can return: in the selection node.
@LiteflowComponent("b")
public class BCmp extends NodeSwitchComponent {
@Override
public String processSwitch() throws Exception {
return "tag:t1";
//The following is also possible
return ":t1";
}
}
condition scheduling
Conditional scheduling is a variant of selective scheduling, where selective scheduling logically selects one of several subitems. Conditional scheduling has only two subitems, true and false, which is very useful in dealing with certain business processes. In fact, to put it simply, conditional scheduling is the programming language of
if else
. Only in
LiteFlow EL
There are some different uses in the grammar. The following
IF
and
ELIF
The first argument of the first parameter requires the definition of a conditional component.
Binary expression for IF: included among these
x
is the conditional node, and in the case of true, the execution link is the
x->a->b
If the link is a false link, it is
x->b
。
<chain name="chain1">
THEN(
IF(x, a),
b
);
</chain>
@Component("x")
public class XCmp extends NodeIfComponent {
@Override
public boolean processIf() throws Exception {
//do your biz
return true;
}
}
Ternary expression for IF: included among these
x
is the conditional node, and in the case of true, the execution link is the
x->a->c
If the link is a false link, it is
x->b->c
。
<chain name="chain1">
THEN(
IF(x, a, b),
c
);
</chain>
ELIF expression: ELIF
Keyword usage is actually similar to
java
linguistic
else if
Similarly, it can be followed by more than one, and
IF
As with binary expression arguments, they usually end with a
ELSE
, which is used for multi-conditional judgment:
<chain name="chain1">
IF(x1, a).ELIF(x2, b).ELIF(x3, c).ELIF(x4, d).ELSE(THEN(m, n));
</chain>
circular programming
FOR loop: FOR
Loop expressions are used for a fixed number of loops and are typically used as:
<chain name="chain1">
FOR(5).DO(THEN(a, b));
</chain>
The above expression means to put
a->b
This link is a fixed loop.
5
times. If you’re not sure how many times you want to loop when you define the rule, and you won’t know until the code runs. Then you can also define it like this:
<chain name="chain1">
FOR(f).DO(THEN(a, b));
</chain>
included among these
f
This node needs to be for the times loop component, which returns a
int
number of cycles.
f
The definition of a node that needs to inherit the
NodeForComponent
The need to realize
processFor
Methods:
@LiteflowComponent("f")
public class FCmp extends NodeForComponent {
@Override
public int processFor() throws Exception {
//Here the result of the for is returned according to the business.
}
}
Loop subscript fetch: keywordFOR...DO...
In theDO
Any of thesejava
components can all be accessed via thethis.getLoopIndex()
to get the subscript. The subscript is obtained in the script via the_meta.loopIndex
to get.
WHILE loop:
<chain name="chain1">
WHILE(w).DO(THEN(a, b));
</chain>
included among these
w
This node needs to be a conditional loop component that returns a boolean value for the
true
then the loop continues
@LiteflowComponent("w")
public class WCmp extends NodeWhileComponent {
@Override
public boolean processWhile() throws Exception {
// Here the while result is returned according to the business.
}
}
Loop subscript fetch: keywordWHILE...DO...
In theDO
Any node inside can be passedthis.getLoopIndex()
to get the subscript. The subscript is obtained in the script via the_meta.loopIndex
to get.
ITERATOR iterative loop
<chain name="chain1">
ITERATOR(x).DO(THEN(a, b));
</chain>
included among these
x
This node needs to be for an iteration loop component that returns an iterator:
x
The definition of a node that needs to inherit the
NodeIteratorComponent
The need to realize
processIterator
Methods:
@LiteflowComponent("x")
public class XCmp extends NodeIteratorComponent {
@Override
public Iterator<?> processIterator() throws Exception {
List<String> list = ListUtil.toList("jack", "mary", "tom");
return list.iterator();
}
}
BREAK
LiteFlow
The same goes for
BREAK
syntax, which represents an exit from the loop.
BREAK
The keywords can be followed in the
FOR
and
WHILE
Later, it is usually used as:
<chain name="chain1">
FOR(f).DO(THEN(a, b)).BREAK(c);
</chain>
<chain name="chain1">
WHILE(w).DO(THEN(a, b)).BREAK(c);
</chain>
included among these
c
This node needs to return a boolean value for the exit loop component, for the
true
then the loop is exited.
c
The definition of a node that needs to inherit the
NodeBreakComponent
The need to realize
processBreak
Methods:
@LiteflowComponent("c")
public class CCmp extends NodeBreakComponent {
@Override
public boolean processBreak() throws Exception {
//Here the result of the break is returned according to the business.
}
}
BREAK
The keyword is judged at the end of each loop.