How to manually inject dependencies into a bean in a AfterBeanDiscovery event listener (CDI)











up vote
0
down vote

favorite












I am using CDI 1.2 (Weld 2.3.5) and want to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener. I'm expecting that this would allow me to ensure that its Initialization would precede the @PostConstruct initialization of other beans in the deployment container.



However, I am looking to use a bean declared via @Produces as a dependency for the bean I am trying to create. According to the BeanManager API doc, I am not allowed to call a BeanManager.getReference() method during the AfterBeanDiscovery event. So I find myself a little stuck; I'm not sure if/how I can retrieve/use a dependency declared in the container as a parameter when constructing my bean in my ABD listener.



So far, I have the following:



// Producer bean configuration

@Produces
@CustomConfigType
public CustomConfig auditConfig() {
CustomConfig config = new CustomConfig();
config.setConfigFile("config/myconfig.properties");
config.setDataSource(datasource);
config.setResourceAccessor(new ClassLoaderResourceAccessor(getClass().getClassLoader()));
return config;
}


// CDI Extension

public class CDIBootstrap implements Extension {

void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
AnnotatedType<CDICustomConfig> at = bm.createAnnotatedType(CDICustomConfig.class);

// this clearly fails as I am not allowed to use forEach() and retrieve an instance of the CustomConfig as declared using the @Produces annotation. But my goal is to accomplish something like this
CDI.current().select(CustomConfig.class, new AnnotationLiteral<CustomConfigType>(){}).forEach(config -> {
Bean instance = new Bean<CDICustomConfig>() {

@Override
public Set<Type> getTypes() {
Set<Type> types = new HashSet<>();
types.add(CDICustomConfig.class);
types.add(Object.class);
return types;
}


@Override
public Class<? extends Annotation> getScope() {
return Dependent.class;
}
...
// Bolierplate methods
...
@Override
public Set<InjectionPoint> getInjectionPoints() {
return it.getInjectionPoints();
}

@Override
public CDICustomConfig create(CreationalContext<CDICustomConfig> ctx) {
// I would like to use the @Produces bean reference here in the instance constructor
CDICustomConfig instance = new CDICustomConfig(config, config.getDataSource(), config.getResourceAccessor());
it.inject(instance, ctx);
it.postConstruct(instance);
return instance;
}

@Override
public void destroy(CDICustomConfig instance, CreationalContext<CDICustomConfig> ctx) {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
};
abd.addBean(instance);
});
}


I'm still learning how to best leverage the JEE/CDI events and listeners, so perhaps this is not the right approach. Is there anyway to legally do what I am hoping to do? Is there any way to use/access a CDI controlled bean instance from within the ABD event listener?



I'm looking to support multiple @Produces CustomConfig beans, and generate a CDICustomConfig for each instance of a CustomConfig bean found in the context. How should I approach this?










share|improve this question






















  • Would you be so kind to describe why it is required to "to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener." What goal you are trying to achieve?
    – Illya Kysil
    Nov 21 at 21:46












  • You need to rethink your approach, why do you want that? What you are trying to do is not meant to work, AfterBeanDiscovery is too early for beans to exist. Soonest you can do that is AfterDeploymentValidation.
    – Siliarus
    Nov 26 at 10:06










  • @IllyaKysil What I'm trying to achieve was modeled on the liquibase-cdi module. My goal was to manually create/instantiate a bean during the ABD event that would automatically get injected with all its dependencies. But as @Siliarus pointed out, I'm at at the right point in the lifecycle. In the end, I moved my bean to a method which @Observes @Initialized(ApplicationScoped.class) instead
    – Eric B.
    Nov 27 at 23:36















up vote
0
down vote

favorite












I am using CDI 1.2 (Weld 2.3.5) and want to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener. I'm expecting that this would allow me to ensure that its Initialization would precede the @PostConstruct initialization of other beans in the deployment container.



However, I am looking to use a bean declared via @Produces as a dependency for the bean I am trying to create. According to the BeanManager API doc, I am not allowed to call a BeanManager.getReference() method during the AfterBeanDiscovery event. So I find myself a little stuck; I'm not sure if/how I can retrieve/use a dependency declared in the container as a parameter when constructing my bean in my ABD listener.



So far, I have the following:



// Producer bean configuration

@Produces
@CustomConfigType
public CustomConfig auditConfig() {
CustomConfig config = new CustomConfig();
config.setConfigFile("config/myconfig.properties");
config.setDataSource(datasource);
config.setResourceAccessor(new ClassLoaderResourceAccessor(getClass().getClassLoader()));
return config;
}


// CDI Extension

public class CDIBootstrap implements Extension {

void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
AnnotatedType<CDICustomConfig> at = bm.createAnnotatedType(CDICustomConfig.class);

// this clearly fails as I am not allowed to use forEach() and retrieve an instance of the CustomConfig as declared using the @Produces annotation. But my goal is to accomplish something like this
CDI.current().select(CustomConfig.class, new AnnotationLiteral<CustomConfigType>(){}).forEach(config -> {
Bean instance = new Bean<CDICustomConfig>() {

@Override
public Set<Type> getTypes() {
Set<Type> types = new HashSet<>();
types.add(CDICustomConfig.class);
types.add(Object.class);
return types;
}


@Override
public Class<? extends Annotation> getScope() {
return Dependent.class;
}
...
// Bolierplate methods
...
@Override
public Set<InjectionPoint> getInjectionPoints() {
return it.getInjectionPoints();
}

@Override
public CDICustomConfig create(CreationalContext<CDICustomConfig> ctx) {
// I would like to use the @Produces bean reference here in the instance constructor
CDICustomConfig instance = new CDICustomConfig(config, config.getDataSource(), config.getResourceAccessor());
it.inject(instance, ctx);
it.postConstruct(instance);
return instance;
}

@Override
public void destroy(CDICustomConfig instance, CreationalContext<CDICustomConfig> ctx) {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
};
abd.addBean(instance);
});
}


I'm still learning how to best leverage the JEE/CDI events and listeners, so perhaps this is not the right approach. Is there anyway to legally do what I am hoping to do? Is there any way to use/access a CDI controlled bean instance from within the ABD event listener?



I'm looking to support multiple @Produces CustomConfig beans, and generate a CDICustomConfig for each instance of a CustomConfig bean found in the context. How should I approach this?










share|improve this question






















  • Would you be so kind to describe why it is required to "to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener." What goal you are trying to achieve?
    – Illya Kysil
    Nov 21 at 21:46












  • You need to rethink your approach, why do you want that? What you are trying to do is not meant to work, AfterBeanDiscovery is too early for beans to exist. Soonest you can do that is AfterDeploymentValidation.
    – Siliarus
    Nov 26 at 10:06










  • @IllyaKysil What I'm trying to achieve was modeled on the liquibase-cdi module. My goal was to manually create/instantiate a bean during the ABD event that would automatically get injected with all its dependencies. But as @Siliarus pointed out, I'm at at the right point in the lifecycle. In the end, I moved my bean to a method which @Observes @Initialized(ApplicationScoped.class) instead
    – Eric B.
    Nov 27 at 23:36













up vote
0
down vote

favorite









up vote
0
down vote

favorite











I am using CDI 1.2 (Weld 2.3.5) and want to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener. I'm expecting that this would allow me to ensure that its Initialization would precede the @PostConstruct initialization of other beans in the deployment container.



However, I am looking to use a bean declared via @Produces as a dependency for the bean I am trying to create. According to the BeanManager API doc, I am not allowed to call a BeanManager.getReference() method during the AfterBeanDiscovery event. So I find myself a little stuck; I'm not sure if/how I can retrieve/use a dependency declared in the container as a parameter when constructing my bean in my ABD listener.



So far, I have the following:



// Producer bean configuration

@Produces
@CustomConfigType
public CustomConfig auditConfig() {
CustomConfig config = new CustomConfig();
config.setConfigFile("config/myconfig.properties");
config.setDataSource(datasource);
config.setResourceAccessor(new ClassLoaderResourceAccessor(getClass().getClassLoader()));
return config;
}


// CDI Extension

public class CDIBootstrap implements Extension {

void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
AnnotatedType<CDICustomConfig> at = bm.createAnnotatedType(CDICustomConfig.class);

// this clearly fails as I am not allowed to use forEach() and retrieve an instance of the CustomConfig as declared using the @Produces annotation. But my goal is to accomplish something like this
CDI.current().select(CustomConfig.class, new AnnotationLiteral<CustomConfigType>(){}).forEach(config -> {
Bean instance = new Bean<CDICustomConfig>() {

@Override
public Set<Type> getTypes() {
Set<Type> types = new HashSet<>();
types.add(CDICustomConfig.class);
types.add(Object.class);
return types;
}


@Override
public Class<? extends Annotation> getScope() {
return Dependent.class;
}
...
// Bolierplate methods
...
@Override
public Set<InjectionPoint> getInjectionPoints() {
return it.getInjectionPoints();
}

@Override
public CDICustomConfig create(CreationalContext<CDICustomConfig> ctx) {
// I would like to use the @Produces bean reference here in the instance constructor
CDICustomConfig instance = new CDICustomConfig(config, config.getDataSource(), config.getResourceAccessor());
it.inject(instance, ctx);
it.postConstruct(instance);
return instance;
}

@Override
public void destroy(CDICustomConfig instance, CreationalContext<CDICustomConfig> ctx) {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
};
abd.addBean(instance);
});
}


I'm still learning how to best leverage the JEE/CDI events and listeners, so perhaps this is not the right approach. Is there anyway to legally do what I am hoping to do? Is there any way to use/access a CDI controlled bean instance from within the ABD event listener?



I'm looking to support multiple @Produces CustomConfig beans, and generate a CDICustomConfig for each instance of a CustomConfig bean found in the context. How should I approach this?










share|improve this question













I am using CDI 1.2 (Weld 2.3.5) and want to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener. I'm expecting that this would allow me to ensure that its Initialization would precede the @PostConstruct initialization of other beans in the deployment container.



However, I am looking to use a bean declared via @Produces as a dependency for the bean I am trying to create. According to the BeanManager API doc, I am not allowed to call a BeanManager.getReference() method during the AfterBeanDiscovery event. So I find myself a little stuck; I'm not sure if/how I can retrieve/use a dependency declared in the container as a parameter when constructing my bean in my ABD listener.



So far, I have the following:



// Producer bean configuration

@Produces
@CustomConfigType
public CustomConfig auditConfig() {
CustomConfig config = new CustomConfig();
config.setConfigFile("config/myconfig.properties");
config.setDataSource(datasource);
config.setResourceAccessor(new ClassLoaderResourceAccessor(getClass().getClassLoader()));
return config;
}


// CDI Extension

public class CDIBootstrap implements Extension {

void afterBeanDiscovery(@Observes AfterBeanDiscovery abd, BeanManager bm) {
AnnotatedType<CDICustomConfig> at = bm.createAnnotatedType(CDICustomConfig.class);

// this clearly fails as I am not allowed to use forEach() and retrieve an instance of the CustomConfig as declared using the @Produces annotation. But my goal is to accomplish something like this
CDI.current().select(CustomConfig.class, new AnnotationLiteral<CustomConfigType>(){}).forEach(config -> {
Bean instance = new Bean<CDICustomConfig>() {

@Override
public Set<Type> getTypes() {
Set<Type> types = new HashSet<>();
types.add(CDICustomConfig.class);
types.add(Object.class);
return types;
}


@Override
public Class<? extends Annotation> getScope() {
return Dependent.class;
}
...
// Bolierplate methods
...
@Override
public Set<InjectionPoint> getInjectionPoints() {
return it.getInjectionPoints();
}

@Override
public CDICustomConfig create(CreationalContext<CDICustomConfig> ctx) {
// I would like to use the @Produces bean reference here in the instance constructor
CDICustomConfig instance = new CDICustomConfig(config, config.getDataSource(), config.getResourceAccessor());
it.inject(instance, ctx);
it.postConstruct(instance);
return instance;
}

@Override
public void destroy(CDICustomConfig instance, CreationalContext<CDICustomConfig> ctx) {
it.preDestroy(instance);
it.dispose(instance);
ctx.release();
}
};
abd.addBean(instance);
});
}


I'm still learning how to best leverage the JEE/CDI events and listeners, so perhaps this is not the right approach. Is there anyway to legally do what I am hoping to do? Is there any way to use/access a CDI controlled bean instance from within the ABD event listener?



I'm looking to support multiple @Produces CustomConfig beans, and generate a CDICustomConfig for each instance of a CustomConfig bean found in the context. How should I approach this?







java java-ee cdi weld bean-manager






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 11 at 20:50









Eric B.

10.2k28104205




10.2k28104205












  • Would you be so kind to describe why it is required to "to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener." What goal you are trying to achieve?
    – Illya Kysil
    Nov 21 at 21:46












  • You need to rethink your approach, why do you want that? What you are trying to do is not meant to work, AfterBeanDiscovery is too early for beans to exist. Soonest you can do that is AfterDeploymentValidation.
    – Siliarus
    Nov 26 at 10:06










  • @IllyaKysil What I'm trying to achieve was modeled on the liquibase-cdi module. My goal was to manually create/instantiate a bean during the ABD event that would automatically get injected with all its dependencies. But as @Siliarus pointed out, I'm at at the right point in the lifecycle. In the end, I moved my bean to a method which @Observes @Initialized(ApplicationScoped.class) instead
    – Eric B.
    Nov 27 at 23:36


















  • Would you be so kind to describe why it is required to "to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener." What goal you are trying to achieve?
    – Illya Kysil
    Nov 21 at 21:46












  • You need to rethink your approach, why do you want that? What you are trying to do is not meant to work, AfterBeanDiscovery is too early for beans to exist. Soonest you can do that is AfterDeploymentValidation.
    – Siliarus
    Nov 26 at 10:06










  • @IllyaKysil What I'm trying to achieve was modeled on the liquibase-cdi module. My goal was to manually create/instantiate a bean during the ABD event that would automatically get injected with all its dependencies. But as @Siliarus pointed out, I'm at at the right point in the lifecycle. In the end, I moved my bean to a method which @Observes @Initialized(ApplicationScoped.class) instead
    – Eric B.
    Nov 27 at 23:36
















Would you be so kind to describe why it is required to "to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener." What goal you are trying to achieve?
– Illya Kysil
Nov 21 at 21:46






Would you be so kind to describe why it is required to "to manually instantiate a bean and inject its dependencies during an AfterBeanDiscovery event listener." What goal you are trying to achieve?
– Illya Kysil
Nov 21 at 21:46














You need to rethink your approach, why do you want that? What you are trying to do is not meant to work, AfterBeanDiscovery is too early for beans to exist. Soonest you can do that is AfterDeploymentValidation.
– Siliarus
Nov 26 at 10:06




You need to rethink your approach, why do you want that? What you are trying to do is not meant to work, AfterBeanDiscovery is too early for beans to exist. Soonest you can do that is AfterDeploymentValidation.
– Siliarus
Nov 26 at 10:06












@IllyaKysil What I'm trying to achieve was modeled on the liquibase-cdi module. My goal was to manually create/instantiate a bean during the ABD event that would automatically get injected with all its dependencies. But as @Siliarus pointed out, I'm at at the right point in the lifecycle. In the end, I moved my bean to a method which @Observes @Initialized(ApplicationScoped.class) instead
– Eric B.
Nov 27 at 23:36




@IllyaKysil What I'm trying to achieve was modeled on the liquibase-cdi module. My goal was to manually create/instantiate a bean during the ABD event that would automatically get injected with all its dependencies. But as @Siliarus pointed out, I'm at at the right point in the lifecycle. In the end, I moved my bean to a method which @Observes @Initialized(ApplicationScoped.class) instead
– Eric B.
Nov 27 at 23:36

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53253104%2fhow-to-manually-inject-dependencies-into-a-bean-in-a-afterbeandiscovery-event-li%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53253104%2fhow-to-manually-inject-dependencies-into-a-bean-in-a-afterbeandiscovery-event-li%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Xamarin.iOS Cant Deploy on Iphone

Glorious Revolution

Dulmage-Mendelsohn matrix decomposition in Python