Aspect Oriented Programming Notes #4 – Proxy Mechanism

In a pure object-oriented sense we are calling a method of an object (Target object). That method has some code which is already in it. Aspect code has to run whenever we call this target method. How is it possible that some other code which is in some other class in some other method runs when we called this method, how is it even possible in a pure object-oriented paradigm.

It’s not actually possible. Aspect oriented programming is a completely different type of programming and what we do in Spring is we use some of the object oriented concepts to achieve aspect oriented programming. The way Spring uses these concepts is using a proxy.

We know proxy as a design pattern so what we do is instead of making a call to Class A, we make a call Class B and Class B internally makes a call to Class A but then it also adds some additional functionalities. This is something that Spring is doing behind the scenes for us.

Let’s try creating our own FactoryService class for having our own getBean() method:

public class FactoryService {
	
	public Object getBean(String beanType) {
		if(beanType.equals("Bicycle")) return new Bicycle();
		if(beanType.equals("Car")) return new Car();
		if(beanType.equals("Truck")) return new Truck();
		return null;
	}
}

Instead of using the:

ApplicationContext ctx = new AnnotationConfigApplicationContext(SomeConfiguration.class);
SomeClass sc = (SomeClass) ctx.getBean("someClass");

we are going to create a FactoryService instance and use that to get a bean.

FactoryService fs = new FactoryService();
Bicycle b = (Bicycle) fs.getBean("Bicycle");

What we are seeing here is instantiation of an object that we have done ourselves. We are not using Spring so none of the aspects or annotations are coming into play here. It’s our own factory service which initializing a bean and then we are calling a method of that bean. Basically we have an implementation of a factory service. We have hard-coded the instantiation but this is it.

Having implemented a factory service we will have a look at a primitive implementation of aspect oriented programming.

Let’s say we have a getBicycleName() method as a target and we want a separate aspect method to be called whenever a getBicycleName() (target) method needs to be run. How would we do that in our primitive implementation of a factory bean.

public class LoggingAspect {

        public void loggingAdvice() {
          System.out.println("Logging from the advice");
    }
}

We want the above loggingAdvice() method to be executed whenever we run getBicycleName() on our Bicycle object that we have got from the FactoryService. The way Spring works is by creating a proxy object. Also, we know that bean that we need to pass back whenever a fs.getBean("Bicycle") called has to be of type Bicycle, because we are casting it to Bicycle and we are assigning it to a local variable over here. So, the return type of this getBean("Bicycle") has to be type of Bicycle.

What we do is to add extra functionality instead of returning an instance of Bicycle class, we extend this class and then return an instance of that subclass which will be an extension of Bicycle class.

We need to create a new class that extends this Bicycle:

public class BicycleProxy extends Bicycle {
    return super.getBicycleName();
}

instead of returning an instance of Bicycle class, we had return an instance of the BicycleProxy:

public class FactoryService {
	
	public Object getBean(String beanType) {
		if(beanType.equals("Bicycle")) return new BicycleProxy();
		if(beanType.equals("Car")) return new Car();
		if(beanType.equals("Truck")) return new Truck();
		return null;
	}
}

What is the advantage of doing this, not passing the Bicycle itself?

Since we have a new method here, we can make additional calls before we call the target method.

public class BicycleProxy extends Bicycle {
    new LoggingAspect().loggingAdvice();
    return super.getBicycleName();
}

This acts as a @Before advice and gets executed before the actual call to the target method. This is our own implementation of @Before advice. Of course we have taken away lots of complexity, this happens dynamically in Spring, but we have statically write the code.

About Aliyar Güneş

I’am Aliyar Güneş, a learner and software developer from Istanbul, Turkey. I write C# and Java.
This entry was posted in Spring Framework, Works and tagged , , . Bookmark the permalink.

Leave a Reply