1 Reply Latest reply on Jul 5, 2011 1:23 PM by cernicb

    Circular dependencies of generic classes

    cernicb

      Hello, I have a @RequestScoped @Named bean composed of several @Dependent modules. Each module has to be @Dependent since they are generic classes. I develop a simple jsf 2.0 application and invoke-application-phase processes action methods from that dependent modules. Most action methods must call other modules, besides module they reside in. So what I need is that each of my modules can obtain current instances of all other modules. What is the best practice to achieve this?


      So far, each @Dependent module has private reference to @RequestScoped bean that holds them all. I fill that references through modules set methods. I call these setters in @PostConstruct of @RequestScoped     bean. I don't know if that is a good approach. I use glassfish 3.1 build 43.

        • 1. Re: Circular dependencies of generic classes
          cernicb

          Hello again, maybe I found proper solution for my problem. Simple application I develop consists of three @RequestScoped beans, for country, municipality and town pages. They all extend one base generic class, BaseJsfBean. And each of them has some modules, such as action module for page actions, and data module for data access. These modules are java generics with @Dependent scope. So I created base class for all the modules as well, and in there I placed BaseJsfBean field. In base module class constructor I obtain current RequestScoped instance via getHostInstance method:


          public static <T> T getHostInstance(Instance<T> source, InjectionPoint injectionPoint, Annotation... qualifiers) {
               T result = null;
               if (source != null && injectionPoint != null) {
                    @SuppressWarnings("unchecked")
                    Class<T> paramClass = (Class<T>) injectionPoint.getMember().getDeclaringClass();
                    Instance<T> instance = source.select(paramClass, qualifiers);
                    if (instance != null)
                         result = instance.get();
               }
               return result;
          }
          



          This way, all modules have reference to client proxy of my current @RequestScoped bean. And when dependent modules have to comunicate among themselves, they do it via @RequestScoped bean instance. Base module class constructor is


          public BaseModule(Instance<BaseJsfBean<T, I>> jsfBeanSource, InjectionPoint injectionPoint) {
               this.jsfBean = getHostInstance(jsfBeanSource, injectionPoint);
          }
          



          Whenever I add new module to module package by extending BaseModule class, I am forced to call this super constructor in order to satisfy compiler, and hence I cannot forget to obtain current @RequestScoped bean for my new module.


          And this way, it's enough for @RequestScoped beans only to have constructor and module field declarations, for example:


          @Inject
          public CountryJsfBean(GenericBean<Country, Long> genericBean, GenericDataModel<Country, Long> dataModel, ActionModule<Country, Long> actionMdl, FilterModule<Country, Long> filterMdl) {
               this.genericBean = genericBean;
               this.filterMdl = filterMdl;
               this.actionMdl = actionMdl;
               this.dataModel = dataModel;
          }
          



          I just want to ask if all this is too complicated, and is there a simpler way to achieve what I showed here?