Using AOP to Retrieve Spring Beans

In order to perform IoC with Spring, the programmer(s) should use a spring factory object to access each bean (might be defined in an XML file) when the beans are required.

This process might cause some problems in many ways and some of them are:

– The programmers who need to access an instance of a bean must be aware of the name of the bean that is specified in the XML file.

– Each time a programmer retrieves a bean, a casting to the requested type must be made.

* Although these two issues might be resolved by using one of the factory patterns, this type of solution would simply contradict with the use of Spring Framework and IoC for that case.

– A constructor call can still be made to one of these beans’ classes. This is problematic when we are dealing with singleton beans – which is most likely to be the case when we need Spring and IoC.

Using AOP, we can simply deal with those kind of problems. Although it would be wiser to use Spring Framework for wiring, I will demonstrate it using AspectJ.

package ali.test;

public class Foo {

private String bar;

public void setBar(String bar)
{
this.bar = bar;
}

public String getBar()
{
return bar;
}
}

We need to have a spring factory type.

package ali.test;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringFactory {

private ApplicationContext context = null;
public SpringFactory()
{
init();
}
private void init()
{
context = new ClassPathXmlApplicationContext(“/applicationContext.xml”);
}

public Object getBean(String name)
{
return context.getBean(name);
}
}

And let applicationContext.xml file be

<?xml version=”1.0″ encoding=”UTF-8″?>
<beans xmlns=”http://www.springframework.org/schema/beans”
xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”
xmlns:aop=”http://www.springframework.org/schema/aop”
xsi:schemaLocation=”http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-2.0.xsd”>

<bean id=”foo” class=”ali.test.Foo” scope=”singleton”>
<property name=”bar” value=”hello!”/>
</bean>

</beans>

So far so good. Now, we are adding our FooCreationAspect that will grab the instance of requested bean using Spring Factory in each call.

package ali.test;

public aspect FooCreationAspect {

private SpringFactory fac;

public FooCreationAspect()
{
fac = new SpringFactory();
}

pointcut fooCreationViaConstructor() : call(Foo.new(..));

Foo around() : fooCreationViaConstructor()
{
Foo f = (Foo)fac.getBean(“foo”);
return f;
}
}

Simple as that. A few tests are to be made:

public static void main(String[] args)
{
Foo f = new Foo();

System.out.println(f.getBar());

f.setBar(“bar2”);

Foo f2 = new Foo();

System.out.println(f2.getBar());
}

The output is :

hello!

bar2

Simply illustrates that the same bean is returned as f2, even if we make a separate constructor call.

Notice that one should be be careful using this technique. If some some complex tasks need to be completed at each execution of the constructor, perhaps the use of this technique needs some second considerations. However, usually (and ideally!) bean objects don’t perform any complex operations and this technique would work well frequently.

Moreover, you may also want to annotate the constructor to make developers aware of the fact that the type is singleton.

Tags: ,

Leave a Reply