6.4. 使用 Jakarta EE
服务供应商只要您正确设置了 META-INF/services 文件以指向您的提供商,即可将其打包在任意 Jakarta EE 组件中。例如,如果您的供应商需要使用第三方库,可以在 ear 中打包您的供应商,并将这些第三方库存储在 ear 的 lib/ 目录中。另请注意,提供程序 jars 可以使用 jboss-deployment-structure.xml 文件,该文件 EJB、WARS 和 EARs 可在 JBoss EAP 环境中使用。有关此文件的详情,请参阅 JBoss EAP 文档。它允许您在其他精细操作中拉取外部依赖项。
提供商工厂 实施需要是普通 java 对象。但是,我们目前还支持将提供程序类实施为有状态 EJB。这是实现它的方式:
@Stateful
@Local(EjbExampleUserStorageProvider.class)
public class EjbExampleUserStorageProvider implements UserStorageProvider,
UserLookupProvider,
UserRegistrationProvider,
UserQueryProvider,
CredentialInputUpdater,
CredentialInputValidator,
OnUserCache
{
@PersistenceContext
protected EntityManager em;
protected ComponentModel model;
protected KeycloakSession session;
public void setModel(ComponentModel model) {
this.model = model;
}
public void setSession(KeycloakSession session) {
this.session = session;
}
@Remove
@Override
public void close() {
}
...
}
您可以定义 @Local 注释并指定您的提供程序类。如果没有这样做,EJB 将不会正确代理供应商实例,您的供应商将无法正常工作。
您可以在供应商的 close () 方法上放置 @Remove 注释。如果没有,则有状态的 bean 不会被清理,您最终可能会看到错误消息。
提供商工厂 的 Ixmplementations 需要是普通 java 对象。您工厂类在其 create () 方法中对 Stateful EJB 执行 JNDI 查找。
public class EjbExampleUserStorageProviderFactory
implements UserStorageProviderFactory<EjbExampleUserStorageProvider> {
@Override
public EjbExampleUserStorageProvider create(KeycloakSession session, ComponentModel model) {
try {
InitialContext ctx = new InitialContext();
EjbExampleUserStorageProvider provider = (EjbExampleUserStorageProvider)ctx.lookup(
"java:global/user-storage-jpa-example/" + EjbExampleUserStorageProvider.class.getSimpleName());
provider.setModel(model);
provider.setSession(session);
return provider;
} catch (Exception e) {
throw new RuntimeException(e);
}
}