Search code examples
jsfnetbeansglassfishjavabeansfacelets

In jsf, how should a bean communicate with a regular java class (aka the business logic)


This is a jsf project on glassfish, developed with Netbeans. I try to connect my beans to my regular java classes.

Here is what I understand:
- Managed beans or their CDI equivalent take care of the UI-related user data (eg, user input)
- The business logic is implemented in regular java classes
- 2 Managed beans or their CDI equivalent can commmunicate with @injection

What I am missing is: how do beans communicate with regular java classes? (where my business logic is?)
In other word, I wish I couldrun my java classes by using the beans as arguments to their constructor!

I tried:
- including a @Inject annotation in my java classes, but that does not work (the bean is not injected, remains null)
like

public class myJavaProgram (){
@Inject
UserInputBean userInputBean;
//my business logic using the properties of userInputBean here...  //does not work, userInputBean is null!
}
  • passing the properties of the bean as arguments in the constructor of my java class. Works, but ugly: why can't I simply pass the whole bean directly as an argument to the constructor? But when I do that I get again a null pointer exception on the bean in my java class.

    Am I missing something? Thx!

Solution

  • Modern enterprise applications usually use the dependency injection pattern throughout the entire application, not just the presentation layer. So you'd have a data access layer contributing beans such as EntityManager. These are injected into business services, that form the business service layer. The business services, in turn, are injected into your JSF backing beans. What dependency injection container is best is a matter of debate, you can also mix them.

    In the Java EE 6 standard (at least how I read it), EJB acts as dependency injection container for the data access and the business service layer, and CDI as dependency injection container for the presentation layer (that's why you can inject EJBs in CDI beans). Others want to replace EJB and use CDI through all layers. Yet others still smart from the hurt J2EE inflicted, and use Spring as dependency injection container.

    To give a little code, you might do:

    @Named
    @SessionScoped
    public class UserBean {
    
        @Inject UserService userService;
    
        User user;
    
        public void save() {
            userService.create(user);
        }
    
    }
    
    @Stateless
    public class UserService {
        public void create(User user) { ... }
    }