前言:

对于采购了国产应用服务器、ORACLE和IBM应用服务器的公司来说,还采用spring+tomcat去实现这些服务器本来就有的Jatarka EE的能力,是对服务器价值的巨大浪费。

对于AI编程时代,也不用再顾及团队的人只会Spring了。我的应用采用Jatarka EE 11标准实现,采用JSF+EJB+JPA,严禁采用第三方JSF库和第三方JS库,在AI的帮助下,采用Jatarka EE 11+JS/CSS/HTML是完全可行的。这将降低初学者学习编程的难度。避免一开始就一堆完全无法控制的东西。把主要精力放在业务和领域知识的学习。


❯ 现在部署的安全模块的文件大小?

Listed 1 directory (ctrl+o to expand)

● Bash(unzip -l /home/clauder/projects/openbusiness/target/openbusiness-security.war | tail -n +4 | head -60)

⎿   0 07-06-2026 20:06 META-INF/

81 07-06-2026 20:06 META-INF/MANIFEST.MF

0 07-06-2026 20:06 WEB-INF/

… +27 lines (ctrl+o to expand)

● 安全模块部署包 openbusiness-security.war 大小 171 KB。

内含 35 个 EJB 类、11 个 Entity 类、Web Bean、Facelets 页面(14 个 XHTML)、CSS、JS

等。对于一个完整的安全控制台(认证、授权、角色管理、用户管理、权限矩阵、角色层级、审计日志、菜单管理),非常紧凑。

※ recap: We standardized the UI style guide (SKILL.md) by documenting 4 reusable patterns from the existing Oracle Redwood implementation: form action buttons, master-detail, modal

dialogs (3 subtypes), and panels. You decided that's sufficient and we stopped. The security module WAR is 171 KB. (disable recaps in /config)


❯ 为什么列表中不描述 Facade接口,是作为EJB的一部分吗?有几个接口?

Searched for 1 pattern, listed 1 directory (ctrl+o to expand)

● Bash(for f in /home/clauder/projects/openbusiness/src/main/java/openlabx/org/cn/security/ejb/{UserFacade,RoleFacade,UserService,RoleService,AuthorizationEngine}.java…)

⎿  === UserFacade.java ===

package openlabx.org.cn.security.ejb;

… +70 lines (ctrl+o to expand)

● 没有接口。项目中所有 EJB 都是直接注入具体类,没有定义 @Local 或 @Remote 接口。

EJB 包内共有 17 个类,按职责分三层:

┌─────────────────────────┬──────┬──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐

│ 层 │ 数量 │ 类 │

├─────────────────────────┼──────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤

│ Facade(Web │ 6 │ UserFacade, RoleFacade, ResourceFacade, MenuFacade, AuditLogFacade, UserCategoryFacade │

│ 层调用入口) │ │ │

├─────────────────────────┼──────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤

│ Service(核心业务逻辑) │ 9 │ UserService, RoleService, ResourceService, MenuService, AuditLogService, UserCategoryService, AuthorizationService, ResourceLookupService, │

│ │ │ EmailNotificationService │

├─────────────────────────┼──────┼──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┤

│ Infrastructure │ 2 │ AuthorizationEngine, DatabaseIdentityStore │

└─────────────────────────┴──────┴──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘

加上 6 个异常类 + PasswordHasher + SessionRegistry + PasswordExpiryScheduler,共 17 个。

Facade 不是接口,是 @Stateless 具体类,通过 @Inject 注入 Service。这是 EJB 3.1+ 的 no-interface view 方式,容器直接从具体类生成代理。

❯ 那以后导出(产生)API如何处理?

● 这取决于模块间是同进程调用还是跨进程调用,两种路径不同:

方案 A:同进程(同一 EAR/WAR 内)— @Local 接口

给 Facade 抽接口,@Inject 按接口类型注入:

@Local

public interface UserFacadeLocal {

User createUser(User user, String password, String createdBy);

List searchUsers(String query, int offset, int limit);

// ... 只暴露需要的方法

}

@Stateless

public class UserFacade implements UserFacadeLocal {

// 现有实现不变

}

其他模块引用时:@Inject private UserFacadeLocal userFacade;

方案 B:跨进程(微服务)— REST 端点

每个模块独立部署,通过 HTTP/JSON 通信:

@Path("/api/users")

@Stateless

public class UserResource {

@Inject private UserFacade userFacade;

@GET

@Produces(MediaType.APPLICATION_JSON)

public List searchUsers(@QueryParam("q") String query) { ... }

}

---

目前项目还不需要做决定。关键是先把 Facade 层作为明确的模块边界来对待——只通过 Facade 暴露给外部,Service 永远是内部实现。将来要导出 API 时,Facade 就是天然的切分点,抽接口或加 REST

注解都只在这一层做。

你觉得这个方向对吗?还是已经有跨模块调用的需求了?

更多推荐