Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to establish the responsibility chain pattern in Workflow engine

2025-01-17 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article introduces the relevant knowledge of "how to establish the responsibility chain pattern in the workflow engine". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!

First, a simple understanding of the concept of chain of responsibility model

There is a lot of introduction to the chain of responsibility pattern on the Internet, as the rookie tutorial says: the chain of responsibility pattern (Chain of Responsibility Pattern) creates a chain of recipient objects for requests. In this pattern, each recipient usually contains a reference to another receiver. If an object cannot process the request, it passes the same request to the next recipient, and so on.

This conceptual term is rather abstract.

I have mentioned in the article "in-depth understanding of the principle of Spring Security authorization mechanism" that Spring Security uses the concept of filters in the authorization process. The filter chain is like a chain, and each filter in the middle contains a reference to another filter, thus linking the related filters together, like a chain. At this point, the request thread, like ants, crawls all the way down the chain-that is, each filter calls another filter reference method chain.doFilter (request, response) to pass the request layer by layer. When the request is passed to the filter that can be processed, it will be processed and forwarded back after processing. Through the filter chain, the request request can be processed in different filters, and the filters do not interfere with each other.

The whole process is roughly as follows:

The concept of the filter chain is actually the embodiment of the responsibility chain design pattern in Spring Security.

An excerpt from an online introduction to the chain of responsibilities model, which mainly includes the following roles:

Abstract handler (Handler) role: defines an interface for handling requests, including abstract processing methods and a successor connection.

Concrete handler (Concrete Handler) role: implement the abstract handler's processing method, determine whether the request can be processed, if it can be processed, then process it, otherwise transfer the request to its successor.

The Client role: creates a processing chain and submits a request to the specific handler object at the head of the chain, which does not care about the processing details and the delivery of the request.

Second, the establishment of responsibility chain model in Activiti workflow.

Recently, in the study of the Activiti workflow framework, it is found that all its implementations are implemented in the command pattern, and the Invoker role in the command pattern adopts the interceptor chain pattern, which is similar to the filter chain mentioned above, that is, the responsibility chain pattern in the design pattern.

The Activiti workflow version here is 6. 0.

CommandInterceptor is an interceptor interface that contains three methods:

The setNext () method sets each interceptor object to contain the next interceptor object during initialization, resulting in a chain of interceptors.

GetNext () can call the next interceptor object in each interceptor object

Execute () is the processing of the request by each interceptor. If the request cannot be processed in the previous interceptor chain, it will pass through next.execute (CommandConfig var1, Command)

Var2) passes the request to the next interceptor for processing, similar to the chain.doFilter (request, response) method in the above filter that calls the next filter to pass the request; public interface CommandInterceptor {T execute (CommandConfig var1, Command var2); CommandInterceptor getNext (); void setNext (CommandInterceptor var1);}

The abstract class AbstractCommandInterceptor implements the CommandInterceptor interceptor interface and acts as an abstract handler (Handler) in the chain of responsibility pattern. The main property of this class is protected CommandInterceptor next, and the next interceptor object can be called directly through next under the same package.

Public abstract class AbstractCommandInterceptor implements CommandInterceptor {protected CommandInterceptor next; public AbstractCommandInterceptor () {} public CommandInterceptor getNext () {return this.next;} public void setNext (CommandInterceptor next) {this.next = next;}}

Next, we will analyze how the interceptor chain initializes and works.

The SpringBoot integration Activiti configuration is as follows:

@ Configuration public class SpringBootActivitiConfig {@ Bean public ProcessEngine processEngine () {ProcessEngineConfiguration pro = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration (); pro.setJdbcDriver ("com.mysql.jdbc.Driver"); pro.setJdbcUrl ("xxxx"); pro.setJdbcUsername ("xxxx"); pro.setJdbcPassword ("xxx") / / avoid garbled pro.setActivityFontName ("Song style"); pro.setLabelFontName ("Song style"); pro.setAnnotationFontName ("Song style") in published images and xml Chinese; / / Database update strategy pro.setDatabaseSchemaUpdate (ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE); return pro.buildProcessEngine ();}}

At this point, after starting the project, the line of pro.buildProcessEngine () initializes the Activiti framework, and when you enter it, you will find that it has three implementations, and the default is the second, ProcessEngineConfigurationImpl.

Click on the Activiti framework to build buildProcessEngine as follows, where this.init () is used to initialize the environment, including configuration settings, JDBC connection, bean loading, and so on:

Public ProcessEngine buildProcessEngine () {this.init (); ProcessEngineImpl processEngine = new ProcessEngineImpl (this); if (this.isActiviti5CompatibilityEnabled & & this.activiti5CompatibilityHandler! = null) {Context.setProcessEngineConfiguration (processEngine.getProcessEngineConfiguration ()); this.activiti5CompatibilityHandler.getRawProcessEngine ();} this.postProcessEngineInitialisation (); return processEngine;}

In the this.init () method, the method that involves initializing the chain of responsibility mode is this.initCommandExecutors (), which is detailed as follows:

Public void initCommandExecutors () {this.initDefaultCommandConfig (); this.initSchemaCommandConfig (); / / initialize the command caller this.initCommandInvoker (); / / List stores the interceptor involved in this.initCommandInterceptors (); / / initialize the command executor this.initCommandExecutor ();}

Here we only need to focus on the last three methods--

This.initCommandInvoker ()

InitCommandInvoker () initializes the construction of an CommandInvoker interceptor, which inherits the interceptor abstract class AbstractCommandInterceptor mentioned above. This interceptor is the most important and critical in the whole filter chain, it is at the end of the whole chain, in fact, it is the final execution of the request, the first few interceptors are just passing the request.

Public void initCommandInvoker () {if (this.commandInvoker = = null) {if (this.enableVerboseExecutionTreeLogging) {this.commandInvoker = new DebugCommandInvoker ();} else {/ / initialize execution of this line of code this.commandInvoker = new CommandInvoker ();}

Here new CommandInvoker () an object, and then copy the address to the this.commandInvoker object reference, which will be used in the next initCommandInterceptors () method--

This.initCommandInterceptors ()

The main purpose of the initCommandInterceptors method is to create a List collection, and then save all the interceptors that need to be used into the List collection--

Public void initCommandInterceptors () {if (this.commandInterceptors = = null) {this.commandInterceptors = new ArrayList (); if (this.customPreCommandInterceptors! = null) {/ / user-defined front interceptor this.commandInterceptors.addAll (this.customPreCommandInterceptors);} / / the framework comes with a default interceptor this.commandInterceptors.addAll (this.getDefaultCommandInterceptors ()) If (this.customPostCommandInterceptors! = null) {this.commandInterceptors.addAll (this.customPostCommandInterceptors);} / Command caller, the last this.commandInterceptors.add (this.commandInvoker) in the interceptor chain;}}

The code for this.getDefaultCommandInterceptors () is as follows:

Public Collection

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report