这篇文章与我的older SO Post有关,其中我试图了解WELD对无参数构造函数的要求。
现在,我正试图弄清楚CDI是否有办法将@ApplicationScoped
bean(@Normal)注入@Dependent
范围。根据我从WELD中读到的内容,要求是使非私有的无参数构造函数可代理。但是,我无法控制bean定义,因为它是由库提供的。我的代码正在执行以下操作:
@Produces
@ApplicationScoped
@Named("keycloakAdmin")
public Keycloak getKeycloakAdminClient(@Named("keycloakDeployment") final KeycloakDeployment deployment) {
String clientId = deployment.getResourceName();
Map<String, Object> clientCredentials = deployment.getResourceCredentials();
// need to set the resteasy client connection pool size > 0 to ensure thread safety (https://access.redhat.com/solutions/2192911)
ResteasyClient client = new ResteasyClientBuilder().connectionPoolSize(CONNECTION_POOL_SIZE).maxPooledPerRoute(CONNECTION_POOL_SIZE)
.defaultProxy("localhost",8888)
.build();
KeycloakBuilder builder = KeycloakBuilder.builder()
.clientId(clientId)
.clientSecret((String) clientCredentials.get(CredentialRepresentation.SECRET))
.realm(deployment.getRealm())
.serverUrl(deployment.getAuthServerBaseUrl())
.grantType(OAuth2Constants.CLIENT_CREDENTIALS)
.resteasyClient(client);
return builder.build();
}
// error thrown here that cannot inject @Normal scoped bean as it is not proxyable because it has no no-args constructor
@Produces
@Dependent
@Named("keycloakRealm")
public RealmRepresentation getKeycloakRealm( @Named("keycloakAdmin") final Keycloak adminClient ){
// error thrown here that cannot inject @Normal scoped bean as it is not proxyable because it has no no-arg
return adminClient.realm(resolveKeycloakDeployment().getRealm()).toRepresentation();
}
问题是我不控制Keycloak
bean;它由图书馆提供。因此,我无法为bean提供无参数构造函数。
这是否意味着无法做到?有没有可以使用的变通方法?这似乎是WELD的一个重大限制,特别是在@Produce
第三方bean时。
我的目标是为应用程序提供一个Keycloak
bean,因为它是线程安全的,只需要初始化一次。但是,我希望能够将它注入非应用程序范围的bean中。
有一个@Singleton
范围可以解决我的问题,但如果@Singleton
适用于这种情况,那么两个不同范围的目的是什么?在什么情况下,人们想要一个非代理单身人士(@Singleton)与代理人(@ApplicationScoped)?或者整个容器是@Singleton
,而应用程序(WAR)的@ApplicationScoped
只是代替?它如何适用于EAR或多耳?