question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Add API and/or injection capabilities to obtain "otherwise injected" bean from producer

See original GitHub issue

For a producer, which is an enabled alternative, with type X it’s sometimes needed to obtain the bean of type X that would have been injected for X had the producer not been there. This is in particularly the case when custom interception is being applied (though this is definitely not the only use case):

For example, a producer:


@Alternative
@Priority(500)
@ApplicationScoped
public class SurroundingBean {

    @Produces
    public X produce(InterceptionFactory<X> interceptionFactory, BeanManager beanManager) {
        return ...
    }
}

This would obtain that “previous instance” of X via code like:

X previous  =
    createRef(
        beanManager.resolve(
            beanManager.getBeans(X.class)
                       .stream()
                       .filter(e -> !e.getBeanClass().equals(SurroundingBean.class))
                       .collect(toSet())), 
            beanManager);

With createRef being defined as:

X createRef(Bean<?> bean, BeanManager beanManager) {
    return (X) 
        beanManager.getReference(
            bean, 
            X.class, 
            beanManager.createCreationalContext(bean));
}

This is a lot of ceremony obviously, which could be greatly simplified.

Issue Analytics

  • State:closed
  • Created a year ago
  • Comments:44 (17 by maintainers)

github_iconTop GitHub Comments

2reactions
arjantijmscommented, May 17, 2022

I don’t see the similarity between the two cases, they seem disparate enough.

At a high level they are actually more similar than they look.

You produce a new bean that delegates parts or everything to another bean with the same type.

Using the producer with a delegation to the original bean, you are in full control of the exact implementation of the wrapper, as long as it adhered to the type being created.

Using the decorator with a delegation to the original bean, the wrapper is created for you.

Where they differ is in obtaining the original bean and the ability to apply interceptors. With the decorator, obtaining the original bean is trivial, but obtaining the InterceptorFactory is not. Whereas with the producer, obtain the original bean is not trivial, but obtaining the InterceptorFactory is trivial.

1reaction
arjantijmscommented, May 23, 2022

Thing is, CDI isn’t a configuration spec in itself.

Not for the kind of configuration MP Config is used for (key/values), but it is IMHO for the kind of configuration that tells you which beans need to be made available with which services (decorators and interceptors and such). Although I’m not a fan of referring to spring too much, they call (or called, it’s been a while) this area configuration too.

when it seemingly puts more weight on user shoulders than just declarative config.

It puts much less weight on the shoulders, since ultimately the building blocks are beans (authentication mechanisms and identity stores) and interceptors (services such as remember me). Now the user doesn’t have to learn how to override or wrap things using some custom config, which may or may not allow for what the user wants.

Instead, if you know how to enable a bean (which can be done by just defining it and having it in the class path), you can tell which i.e. identity store to use. You can decorate or intercept these, return them from a producer, have them in an archive, create them from an extension, etc etc. It’s all the standard CDI APIs. Making all these things possible and then specify them using the custom machinery of Faces took years, and required us to introduce tons of factories and config files and custom listeners etc.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Injecting Objects by Using Producer Methods
When you inject the object in another managed bean, the container automatically invokes the producer method, initializing the value to 100:
Read more >
Chapter 11. Portable extensions
Providing its own beans, interceptors and decorators to the container. Injecting dependencies into its own objects using the dependency injection service.
Read more >
Core Technologies
Dependency injection (DI) is a process whereby objects define their dependencies (that is, the other objects with which they work) only through constructor ......
Read more >
pact-jvm
i have added pact jvm concumer dependency, ``` <dependency> <groupId>au.com.dius</groupId> <artifactId>pact-jvm-consumer-junit_2.12</artifactId> ...
Read more >
Inject spring bean dynamically - java
Clients only have to implement the MyInterfaceReloader interface, which only sets an attribute. Dynamic proxy is a very good approach, though, I ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found