[Cao Gong's essay] talk about the contract between Maven framework and plug-ins

Cao Gong code shift 2021-09-15 10:02:24
cao gong essay talk contract

say something Maven Contract between framework and plug-in


Maven The framework is like various platforms in the company now , Stipulate some contracts , Then try to pull the business side , Let's do ecological Co Construction on this platform .Maven In the same way , In fact, it is a framework for plug-in execution ,Maven At first, I didn't know who would contribute the plug-in , If you write all kinds of plug-ins , For the platform side , It could be a disaster , therefore , The platform side is responsible for setting standards , To write plug-ins on my platform , What must be done .

Maven A contract is made for the plug-in , This contract , It's through api jar Package mode . Every time I release Maven The new version , Accompanied by , There will be one api jar package .

If someone wants to be based on this version api jar Package to develop plug-ins , You need to introduce this plug-in into your plug-in project . And then according to api jar Contract interface in package , To implement their own plug-in logic .

such as ,maven clean In the engineering code of the plug-in , It depends on api jar package . as follows :

api jar What does the contract interface look like in the package ?

public interface Mojo {
void execute() throws MojoExecutionException, MojoFailureException;

The core method is this , As long as you implement this interface, you're done .

As a framework , How to call this plug-in ? In short , Namely :

1、 Find the implementation class of the plug-in jar package , Then construct a class loader for the plug-in , To load this jar package , Then find the corresponding class that implements the contract interface , Like here CleanMojo

2、 Loaded this CleanMojo Of class after , Of course, reflection generates objects , Then cast to the contract interface , Then the contract interface is called . such as :

Class cleanMojoClass = The class loader of the plug-in loads the class of the plug-in jar package ;
Mojo cleanMojo = (Mojo)cleanMojoClass.newInstance();

Only this and nothing more , Our theoretical knowledge is enough , Can we show the code 了 ?

The engineering practice

We will simulate the above process ,

  1. To build a Maven module, Used to store plug-ins api Contract interface ;
  2. To build a Maven module, introduce api, Implement plug-ins api, such , Even if our plug-in is implemented ;
  3. Next , Compile these two projects , hold jar Package installation to local warehouse ;
  4. Another new project , simulation Maven Framework to load plug-ins , And execute the plug-in .

plug-in unit api engineering

Direct use maven Of archetype Medium quickstart, Create a new one module, It's very simple , Just an interface :

And then execute mvn install, Install to local warehouse .

Plug in implementation project

stay pom in , We will introduce api.


The code is also simple , Just an implementation class .

And then execute mvn install, Install to local warehouse .

Main works , Simulate the framework to call the plug-in

The main project is to simulate our Maven frame , Because we call the plug-in , It must have been through api The way , therefore ,pom It must introduce api Of .


Next , We wrote a test class :

public static void main( String[] args ) throws MalformedURLException, ClassNotFoundException, InstantiationException, IllegalAccessException {
// 1.1 It's about 
URL urlForPluginApi = new URL("file:/C:\\Users\\Administrator\\.m2\\repository\\org\\example\\my-plugin-api\\1.0-SNAPSHOT\\my-plugin-api-1.0-SNAPSHOT.jar");
URL urlForPluginImpl = new URL("file:/C:\\Users\\Administrator\\.m2\\repository\\org\\example\\my-plugin-implementation\\1.0-SNAPSHOT\\my-plugin-implementation-1.0-SNAPSHOT.jar");
URL[] urls = {urlForPluginApi, urlForPluginImpl};
// 1.2
URLClassLoader urlClassLoader = new URLClassLoader(urls,ClassLoader.getSystemClassLoader()){
public Class<?> loadClass(String name) throws ClassNotFoundException {
// Guarantee : When looking for class , Give priority to finding your own classpath, Can't find , And give it to parent classloader
Class<?> clazz = findClass(name);
return clazz;
}catch (ClassNotFoundException exception ){
return super.loadClass(name);
// 1.3
Class<?> implClazzByPluginClassloader = urlClassLoader.loadClass("org.example.MyMojoImplementation");
// 1.4 
MojoInterface mojoInterface = (MojoInterface) implClazzByPluginClassloader.newInstance();
// 1.5 
System.out.println( "Hello World!" );

Let me briefly explain the above code first :

  • 1.1 It's about , Constructed two url, Point to two files in my local warehouse , That is to say api.jar The implementation corresponding to the plug-in jar

  • 1.2 It's about , Use 1.1 Medium url, Constructed a classloader, This classloader Of parent classloader, What we pass is , Systematic AppClassloader.

    meanwhile , We rewritten this classloader act , The rewritten behavior is as follows : When you encounter a class to load , Give priority to loading , That is, I will go to my two url Inside looking for , See if you can find , If you can't find it , Will enter the exception , After the exception is caught by us , hand parent classloader To load the ;

  • 1.3 It's about , We use the new classloader, To load the implementation class of the plug-in

  • 1.4 It's about , utilize 1.3 Of the implementation class loaded at class, Reflection generates objects , Forced to MojoInterface Interface object

  • 1.5 It's about , Execute plug-in logic in a polymorphic manner

You might as well think about , Everyone feels , What is the final implementation result ? our “hello world” Can you print it out ?

This code , We uploaded gitee, You can pull it down and see .


Let me show you , Execution results :

Let's see. , Is this like a word , In my plug-in code , It implements the interface , Why can't we transform upward ?:

public class MyMojoImplementation implements MojoInterface{
public void execute() {
System.out.println("implementation execute business logic");

This ... How to put it? ... Let me explain to you , We load MyMojoImplementation when , Find this class , It also implements the interface MojoInterface, that , This interface class needs to be loaded , Because we classloader Has been rewritten ( Priority is given to loading by yourself ), therefore , In the end ,MojoInterface It's just like MyMojoImplementation equally , Are loaded by the plug-in class loader .

In the end , In the upward transformation , There will be the following situation , The two sides don't match , It's a mistake .

 MojoInterface( This class in the framework , It is loaded by the class loader of the framework ) mojoInterface = (MojoInterface) implClazzByPluginClassloader.newInstance();( The interface implemented by this implementation class , Is loaded by the plug-in class loader )

After class questions

We changed the code , Changed to the following , result , You can run through our hello world 了 . Why is this ?

I'm daily , Shenzhen Tencent employee , The back end of repeated horizontal jumps between Chengdu and Shenzhen java A program ape . Previously in Shenzhen 3 year , Later I went to Chengdu 4 year , Now I come to Shenzhen , Also started writing the front end , If you need to push inside, you can come to me . For front-line coding practice 、 The Internet 、 database 、 High concurrency, etc .

Also welcome to add me , Pull into the technology group to communicate ; Tencent can also find me .

This article by the blog one article many sends the platform OpenWrite Release !

本文为[Cao Gong code shift]所创,转载请带上原文链接,感谢

  1. L'arrivée de marchandises sèches, l'entretien d'emploi Java 12 grandes usines ont réussi à changer d'emploi,
  2. Multiple postures for handling container time in k8s environment
  3. Echarts remove left Gap, Blank
  4. Hotspot Weekly | zoom $100 million, docker fees, $38 billion Data bricks
  5. JsonMappingException: No serializer found for class org.apache.ibatis.executor.loader.javassist.JavassistProxyFactory...
  6. Java. Security. Securerandom source code analysis Java. Security. EGD = file: / dev /. / urandom
  7. When using IntelliJ idea, jump directly and quickly from the mapper interface to mapper.xml
  8. When idea writes SQL in mybatis XML, the solution to the problems of table name, field and red reporting
  9. Spring cloud integrates Nacos
  10. 应届毕业生Java笔试题目,2021大厂Java社招最全面试题,
  11. Liver explosion! Take you to understand Hadoop serialization
  12. linux系列之:告诉他,他根本不懂kill
  13. java版gRPC实战之三:服务端流
  14. RabbitMQ核心知识总结!
  15. linux系列之:告诉他,他根本不懂kill
  16. java版gRPC实战之三:服务端流
  17. RabbitMQ核心知识总结!
  18. 10天拿到字节跳动Java岗位offer,学习Java开发的步骤
  19. 10天拿到字节跳动Java岗位offer,Java知识点思维导图
  20. Résumé des connaissances de base de rabbitmq!
  21. 10天拿到字節跳動Java崗比特offer,Java知識點思維導圖
  22. 10 jours pour obtenir un Byte Jump Java post offer, Java Knowledge point Mind Map
  23. 10 jours pour obtenir l'octet Jump Java post offer, apprendre les étapes du développement Java
  24. Java version of gppc Reality Three: server side stream
  25. Linux Series: Dites - lui qu'il ne connaît pas kill du tout
  26. "Data structure and algorithm" of front end -- binary search
  27. 2020-2021京东Java面试真题解析,如何才能通过一线互联网公司面试
  28. 13 SpringBoot整合RocketMQ实现过滤消息-根据SQL表达式过滤消息
  29. 12 SpringBoot整合RocketMQ实现过滤消息-根据TAG方式过滤消息
  30. 11 SpringBoot整合RocketMQ实现事务消息
  31. 11 springboot Consolidated rocketmq Implementation transaction message
  32. 12 springboot Consolidated rocketmq Implements Filtering messages - Filtering messages according to tag method
  33. 13 springboot Consolidated rocketmq Implementation Filtering messages - Filtering messages according to SQL expressions
  34. linux系列之:告诉他,他根本不懂kill
  35. (1)java Spring Cloud+Spring boot企业快速开发架构之微服务是什么?它的优缺点有哪些?
  36. Oracle 检查 DATE 列 RANGE 分区表已有分区的最大日期时间
  37. ConcurrentHashMap--原理
  38. 2020 - 2021 JD Java interview Real question Analysis, How can interview through First - Line Internet Company
  39. Concurrenthashmap - - Principes
  40. Oracle vérifie l'heure de date maximale d'une partition existante dans la colonne date
  41. Docker Compose 实践及梳理
  42. Qu'est - ce qu'un microservice pour Java Spring Cloud + Spring Boot Enterprise Quick Development architecture?Quels sont ses avantages et ses inconvénients?
  43. Plus sign interview knowledge points in Java
  44. Pratique et organisation de la composition des dockers
  45. Linux Series: Dites - lui qu'il ne connaît pas kill du tout
  46. Convenient CSS and jQuery drop-down menu solution
  47. Linux analog packet loss rate
  48. Redis:我是如何与客户端进行通信的
  49. 15 useful cron work examples commonly used by Senior Linux system administrators
  50. 24个 JavaScript 循环遍历方法,你都知道吗?
  51. Reading notes of JavaScript advanced programming (3rd Edition) 4
  52. 30分钟学会Docker里面开启k8s(Kubernetes)登录仪表盘(图文讲解)
  53. 24 méthodes de traversée de boucle Javascript, vous savez?
  54. 30 minutes pour apprendre à ouvrir le tableau de bord k8s (kubernets) dans le docker (explication graphique)
  55. Redis: comment je communique avec les clients
  56. Wsl2: Windows native Linux subsystem
  57. 30分钟学会Docker里面开启k8s(Kubernetes)登录仪表盘(图文讲解)
  58. Python高级用法总结(8)-函数式编程
  59. 261页前端面试题宝典,JavaScript变量声明提升
  60. The performance of JVM and Java applications of the same version differs by 30% on X86 and aarch64 platforms. Why?