Agile != Scrum

“I hate Agile. It’s full of these pointless meetings like planning – which is a complete waste of time.”

I’ve overheard a colleague of mine say this the other morning. Of course, he meant Scrum. Many people think these two concepts are the very same and use them interchangeably. Agile, however, is a much broader category;it contains loads of software development methodologies – one such being Scrum itself. Let’s see a quick (and far not complete) overview: 

 

info

 

The bars above show how heavyweight a process is. The more things prescribed by a methodology, the more heavyweight it is. Scrum is pretty huge; it defines roles, meetings – it pretty much schedules your days two weeks ahead. On the other hand, Lean development only defines principles – like amplify learning – and does not say anything about implementation details.

So if you think Agile is bad (a waste of time, too restrictive, or on the contrary, too permissive), you perhaps just had a not so well chosen process. Take another look, it may worth trying a new agile methodology.

Spring’s BeanFactoryAware – DOs and DON’Ts

Spring makes it possible to set application context and/or bean factory into any Spring bean (this is a key point; keep in mind that you cannot inject these object into POJOs). In order to do that, your bean has to implement the interface BeanFactoryAware or ApplicationContextAware. There is only one method you have to implement:

public class OneBean implements BeanFactoryAware {

    private BeanFactory beanFactory;

    //....

    void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }
}

It is now pretty obvious that the class that implements this interface has to be a Spring bean – as the setter method will be called by the container reflectively.

Simply put, it is very easy to get hold of the bean factory object; however, this mechanism should not be overused. Better said, it should be very rarely used. Let’s take some examples when and when should not this thing be used.

Do not inject the bean factory just to publish it to other beans. The injected bean factory should never be published; if you end up writing a getter for it, that should ring the bell:

public class OneBean implements BeanFactoryAware {

    private BeanFactory beanFactory;

    //....

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public BeanFactory getBeanFactory() {
        return beanFactory;
    }
}

This should be avoided, as this anti-pattern does not encourage good dependency injection. In most of the cases dependencies should come through constructor arguments; in more rare cases through method parameters.

Do not inject the bean factory just for getting beans by their name.

public class OneBean implements BeanFactoryAware {

    private BeanFactory beanFactory;

    //....

    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        this.beanFactory = beanFactory;
    }

    public void doAwesomeThings() {
        //...
        AwesomeBean awesomeBean = (AwesomeBean)beanFactory.getBean("myAwesomeBean");
        awesomeBean.doSomeWork();
        //...
    }
}

This – again – is not good practice. If you do this, it is not worth doing dependency injection, as the snipped above is not much better than creating objects with the new keyword. Not to mention the hardcoded bean name, which is an anti-pattern in itself, but leave that one for now.

So, when to inject the bean factory? Frankly, I cannot think of very many situations when injecting a bean factory is a good idea. The only acceptable situation that I can think of is when you have a group of similar beans and have to select the one to us after the container has started. Let’s take an example: You have support for several credit cards in your application. The user can select their card type through a user interface. In the business logic, you need the correct credit card handler. You cannot inject this dependency at start up time as you don’t know what to inject; you have to defer this decision until the user has made their selection. Now, you can have something like this:

public class CreditCardProcessorFactory implements BeanFactoryAware {

 private BeanFactory beanFactory;
 private static final String CARD_TYPE_SUFFIX = "CardHandler";
 //....

 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
 this.beanFactory = beanFactory;
 }

 public CreditCardProcessor getCreditCardProcessor(String cardType) {
 return (CreditCardProcessor)beanFactory.getBean(cardType + CARD_TYPE_SUFFIX);
 }
}

This way you can avoid injecting all the credit card processors you support and use only one of them.

The process is very similar for ApplicationContextAware too. However, it should be even more rare when you need the whole ApplicationContext and not just the BeanFactory.