多模块Maven Java项目(JBoss部署)模块间通信方式及示例咨询
Great question! Let's break this down clearly for your multi-module Maven app running on JBoss.
In a multi-module Maven project (organized via a parent POM), your modules are essentially separate JAR/WAR/EAR artifacts deployed to JBoss. Communication between them falls into two main categories, with several practical approaches:
- Local Communication (Same JBoss Instance):
- Dependency injection + shared API modules (most efficient for in-JVM calls)
- EJB Local Interfaces
- CDI (Contexts and Dependency Injection) beans
- Remote Communication (Cross JBoss Instances):
- EJB Remote Interfaces
- JMS (Java Message Service) for async, decoupled communication
- REST APIs (for loose coupling or cross-language support)
Absolutely! JBoss is a full Jakarta EE (formerly Java EE) container with first-class support for EJBs. They're a great fit for both local and remote module communication:
- Local EJBs: Offer near-native performance since calls happen within the same JVM, no network overhead.
- Remote EJBs: Enable communication across different JBoss instances, with built-in transaction and security support.
- Perfect for multi-module setups: You can isolate EJB interfaces in a shared API module, keeping your implementation modules decoupled.
Let's walk through a concrete setup with three core modules: a shared API, an EJB service implementation, and a web module that calls the EJB.
Project Structure
my-parent-app/ ├── pom.xml (Parent POM) ├── my-ejb-api/ (Shared interface JAR) │ └── pom.xml ├── my-ejb-service/ (EJB implementation JAR) │ └── pom.xml └── my-web-module/ (WAR module calling the EJB) └── pom.xml
1. Parent POM Configuration
Define modules and centralized dependency management to keep versions consistent:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <groupId>com.example</groupId> <artifactId>my-parent-app</artifactId> <version>1.0.0</version> <packaging>pom</packaging> <modules> <module>my-ejb-api</module> <module>my-ejb-service</module> <module>my-web-module</module> </modules> <dependencyManagement> <dependencies> <!-- Jakarta EE API (matches JBoss EAP 7.4+) --> <dependency> <groupId>jakarta.platform</groupId> <artifactId>jakarta.jakartaee-api</artifactId> <version>8.0.0</version> <scope>provided</scope> </dependency> </dependencies> </dependencyManagement> </project>
2. Shared EJB API Module (my-ejb-api)
This module only contains interfaces, so other modules can depend on it without coupling to implementation details:
package com.example.ejb.api; import jakarta.ejb.Local; // Use @Remote instead for cross-instance calls @Local public interface UserService { String getUserNameById(Long userId); }
Its pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.example</groupId> <artifactId>my-parent-app</artifactId> <version>1.0.0</version> </parent> <artifactId>my-ejb-api</artifactId> <packaging>jar</packaging> </project>
3. EJB Implementation Module (my-ejb-service)
Depend on the API module and implement the EJB:
package com.example.ejb.service; import com.example.ejb.api.UserService; import jakarta.ejb.Stateless; @Stateless // Stateless EJB for lightweight, pooled instances public class UserServiceImpl implements UserService { @Override public String getUserNameById(Long userId) { // Replace with actual business logic (e.g., DB call) return "User_" + userId; } }
Its pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.example</groupId> <artifactId>my-parent-app</artifactId> <version>1.0.0</version> </parent> <artifactId>my-ejb-service</artifactId> <packaging>ejb</packaging> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>my-ejb-api</artifactId> <version>1.0.0</version> </dependency> </dependencies> </project>
4. Web Module Calling the EJB (my-web-module)
Depend on the API module and inject the EJB via CDI (recommended for JBoss):
package com.example.web; import com.example.ejb.api.UserService; import jakarta.inject.Inject; import jakarta.servlet.annotation.WebServlet; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; import jakarta.servlet.http.HttpServletResponse; import java.io.IOException; @WebServlet("/user") public class UserServlet extends HttpServlet { @Inject private UserService userService; // JBoss handles injection automatically @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException { Long userId = Long.parseLong(req.getParameter("id")); String userName = userService.getUserNameById(userId); resp.getWriter().write("Fetched User: " + userName); } }
For remote EJB calls, you can use JNDI lookup instead:
// Inside your servlet or bean InitialContext ctx = new InitialContext(); UserService remoteUserService = (UserService) ctx.lookup( "ejb:/my-ejb-service/UserServiceImpl!com.example.ejb.api.UserService" );
Its pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <groupId>com.example</groupId> <artifactId>my-parent-app</artifactId> <version>1.0.0</version> </parent> <artifactId>my-web-module</artifactId> <packaging>war</packaging> <dependencies> <dependency> <groupId>com.example</groupId> <artifactId>my-ejb-api</artifactId> <version>1.0.0</version> </dependency> </dependencies> </project>
- Package as EAR: For simplicity, add an EAR module to your parent project to package all modules together. This ensures JBoss handles class loading correctly between modules.
- Remote EJB Setup: For cross-instance calls, add a
jboss-ejb-client.propertiesfile to your calling module with connection details for the remote JBoss server. - Version Compatibility: Ensure your Jakarta EE API version matches your JBoss version (e.g., JBoss EAP 7.4 uses Jakarta EE 8).
内容的提问来源于stack exchange,提问作者user4919313

