users@glassfish.java.net

EJB3 Observer pattern

From: Witold Szczerba <pljosh.mail_at_gmail.com>
Date: Mon, 18 Feb 2008 15:54:03 +0100

Hi there,
in my EJB3 application I have lot of session beans like this:
@Stateless
public class LoanActivationBean implements LoanActivationLocal {
 ...
     public void execute(Loan loan) {
        ScheduleGenerator scheduleGenerator = new ScheduleGenerator(loan);
        Set<LoanScheduleEntry> schedule = scheduleGenerator.getResult();

        loanDao.persistSchedule(loan, schedule);

        if (loan.getProposal().isRestructuring()) {
            loanRestructActivation(loan);
        }
        documentsService.groupGenerateActivationDocuments(loan);
        loan.setLoanStatus(em.getReference(DictLoanStatus.class,
DictLoanStatus.ACTIVE));
        loan.setStatusChangeDate(new Date());

        actionService.genereteOrUpdateBeforeEndAction(loan, schedule);
    }
}

As you can see, when somebody is activating loan there are few steps
that does need to be accomplished:
1) generate schedule and persist it
2) check if this is a restructuring loan and if so - invoke additional
operations
3) generate special documents
4) change loan status
5) do something with action subsystem

Originally, there were only steps: 1,2 and 4, but later, other guys
had to add their special actions - one to feed document service and
one for actions/tasks service.

I really don't like the way it looks like now. My loan activation
service is really not interested in those two other services but their
code is inside my class. There are many, many other services in our
application that looks more or less like this.

I was thinking about Observer pattern. My session bean could invoke
all interested observers that are registered... but the problem is how
to register those services?
I was thinking about something like this:

lets add field like List<LoanActivationObserver> observers into my
LoanActivationService and one method like this:
public void addObserver(LoanActivationObserver observer) {
  observers.add(observer);
}

The problem is: how and where other services should register themselves.
I was thinking about such an idea: let every session bean that would
like to be notified about newly activated loans create life-cycle,
post construct method:

@Stateless
public class SomeServiceBean implements SomeServiceLocal,
LoanActivationObserver {

 @EJB LoanActivationLocal loanActivationBean;
 @Resource SessionContext ctx;
 @PostConstruct initialize() {
    loanActivationBean.addObserver(ctx.getBussinessObject(LoanActivationObserver.class));
   }
   ...other methods including the one from LoanActivationObserver interface...
}

I am very surprised I couldn't find anything like this on the net
before, as this looks like a very simple Observer pattern
implementation in EJB3 environment and this is one of the most
important pattern to decouple application code.

Is this idea actually correct from EJB3 point of view? Can I be sure
that @PostConstruct method will be invoked before my
LoanActivationBean will activate any loan, or maybe EJB3 server is not
going to create stateless session beans that were not invoked
explicitly?
What do you think about all this?

Regards,
Witold Szczerba