Search code examples
jsfjakarta-eecdiview-scopeseam3

How do you find CDI beans of/in the current view (scope)?


In a Java EE 6, CDI 1.1.x, Seam 3 etc. environment, we need to find all CDI beans of the current view (@ViewScoped). What I have tried so far is using:

@Named
@ViewScoped
public class ViewHelper
{
    @Inject
    private BeanManager beanManager;

    public doSomethingWithTheBeanInstances()
    {
        Set<Bean<?>> beans = this.getBeanManager().getBeans( 
            Object.class, new AnnotationLiteral<Any>(){}
        );

        // do something
        ...
    }
}

However, this returns all beans it manages.

I need to find only those within the scope of the current view and - that would be ideal - only those that implement a specific interface (inherited over over multiple hierarchy levels).

What's the way to do it?

Note since CDI has no view scope, we're using Seam 3 to be able to annotate all our view-scoped beans like:

@Named
@ViewScoped
public class ResultManagerColumnHandler extends BaseColumnHandler
{
    ....
}

The above would be an instance to look for (the @ViewScoped is a CDI replacement by Seam 3).

How can it be done?


Solution

  • I am not familiar with Seam, but from CDI standpoint, this is what I would try. However, bean it mind that it will only work if beanManager.getContext(ViewScoped.class); returns a valid context instance for you:

    @Inject
    BeanManager bm;
    
    public List<Object> getAllViewScoped() {
        List<Object> allBeans = new ArrayList<Object>();
        Set<Bean<?>> beans = bm.getBeans(Object.class);
        // NOTE - context has to be active when you try this
        Context context = bm.getContext(ViewScoped.class);
    
        for (Bean<?> bean : beans) {
            Object instance = context.get(bean);
            if (instance != null) {
                allBeans.add(instance);
            }
        }
    
        return allBeans;
    }
    

    You also asked to only obtain beans that implement certain interface. For that, simply modify the code line retrieving all beans with desired type:

    Set<Bean<?>> beans = bm.getBeans(MyInterface.class);