Thursday, March 26, 2015

Spring Basic - Understanding scope and Alias

I have been using basic coding structure in explaining most of the concepts ,including AOP.
Below is the link
http://cgenit.blogspot.com/2015/03/aop-basic-application-code-and.html


Spring has basically 6 bean scopes and except for "singleton" and "prototype" other four are valid in the context of web-aware Spring ApplicationContext.

Following table shows the details

Table 5.3. Bean scopes
ScopeDescription
singleton(Default) Scopes a single bean definition to a single object instance per Spring IoC container.
prototypeScopes a single bean definition to any number of object instances.
requestScopes a single bean definition to the lifecycle of a single HTTP request; that is, each HTTP request has its own instance of a bean created off the back of a single bean definition. Only valid in the context of a web-aware Spring ApplicationContext.
sessionScopes a single bean definition to the lifecycle of an HTTP Session. Only valid in the context of a web-aware Spring ApplicationContext.
global sessionScopes a single bean definition to the lifecycle of a global HTTP Session. Typically only valid when used in a portlet context. Only valid in the context of a web-aware Spring ApplicationContext.
applicationScopes a single bean definition to the lifecycle of a ServletContext. Only valid in the context of a web-aware Spring ApplicationContext.

You can refer http://docs.spring.io/spring/docs/current/spring-framework-reference/html/beans.html#beans-factory-scopes   for more details.

Here I am going to explain the behavior of the singleton and the prototype.

Singleton -basically make sure there will be only once instance , in this case one instance per container.
Prototype - gives you a new instance in each time you request or refer the bean definition.

Remember : Spring container default configuration is "singleton"

Let's check it with application. we are using "ShapeService" bean definition to understand this.
We get the bean calling same definition twice and let's compare the two object.
If the result is true , then two object are similar --> mean Singleton.

xml definition for bean

spring.xml
----------------------------------------------------------------------------------------------------


<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName" scope="singleton" id="shapeServiceId"></bean>

----------------------------------------------------------------------------------------------------

AppMain.java
----------------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);
ShapeService shapeService1 = ctx.getBean("shapeService",
ShapeService.class);



shapeService.getCircle();
System.out.println("shapeService and shapeService1 equal="
+ shapeService.equals(shapeService1));

}

}

----------------------------------------------------------------------------------------------------

output
===========================================================
shapeService and shapeService1 equal=true
===========================================================

Not : two objects are similar, Singleton

We can try with omitting the "singleton" scope definition. most of the time we write omitting this.
----------------------------------------------------------------------------------------------------
<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName"  id="shapeServiceId"></bean>

----------------------------------------------------------------------------------------------------

output will be still same
===========================================================
shapeService and shapeService1 equal=true
===========================================================

Now let's change the scope to prototype and see the result.

----------------------------------------------------------------------------------------------------
<bean name="shapeService" class="org.aop.service.ShapeService"

autowire="byName" scope="prototype" id="shapeServiceId"></bean>

----------------------------------------------------------------------------------------------------

output resulting "false"
===========================================================
shapeService and shapeService1 equal=false
===========================================================

This is beacuse , prototype returns a new object for each call.


Now let's look at that with Alias.
Alias is referring same object with a different name. When we need create more than one bean from the same bean definition we can use Alias mechanism.

There are two ways to create alias
      1. we can give the alias names in the "name" attribute with space. comma or semicolon.
I have used space for my example.
     2.  use Alias tag

below is the sample bean definitions

spring.xml
----------------------------------------------------------------------------------------------------
<bean name="shapeService shapeService1 shapeService2" class="org.aop.service.ShapeService" autowire="byName" scope="singleton" id="shapeServiceId"></bean> <alias name="shapeService" alias="shapeServiceAlias" />


----------------------------------------------------------------------------------------------------

Here i have used singleton scope. That will help us to test and tell you that all beans are refer to one. When you compare with equal all must be equal.
We retrieve each bean and compare. Below is the test code and output.

AppMain .java
----------------------------------------------------------------------------------------------------
package org.aop.main;

import org.aop.service.ShapeService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class AppMain {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"spring.xml");

// you need to cast if not use second parameter ShapeService.class
ShapeService shapeService = ctx.getBean("shapeService",
ShapeService.class);
ShapeService shapeService1 = ctx.getBean("shapeService1",
ShapeService.class);
ShapeService shapeService2 = ctx.getBean("shapeService2",
ShapeService.class);
ShapeService shapeService3 = ctx.getBean("shapeServiceId",
ShapeService.class);
ShapeService shapeService4 = ctx.getBean("shapeServiceAlias",
ShapeService.class);

// FactoryService factoryService = new FactoryService();
// ShapeService shapeService = (ShapeService) factoryService
// .getBean("shapeService");

shapeService.getCircle();
System.out.println("shapeService and shapeService1 equal="
+ shapeService.equals(shapeService1));
System.out.println("shapeService and shapeService2 equal="
+ shapeService.equals(shapeService2));
System.out.println("shapeService and shapeServiceId equal="
+ shapeService.equals(shapeService3));
System.out.println("shapeService and shapeServiceAlias equal="
+ shapeService.equals(shapeService4));

}

}


----------------------------------------------------------------------------------------------------

Output :: Note ::all equal as all refer to one with singleton
===========================================================
shapeService and shapeService1 equal=true
shapeService and shapeService2 equal=true
shapeService and shapeServiceId equal=true
shapeService and shapeServiceAlias equal=true
===========================================================

So you can see the output being true as all refer to one bean definition and scope is singleton. Actually to test this we need to use the singleton scope as with prototype we cannot exactly tell it refers to same bean definition.
so we can see the output , if we change the scope to prototype.

spring.xml  Note:: scope change to prototype
----------------------------------------------------------------------------------------------------
<bean name="shapeService shapeService1 shapeService2" class="org.aop.service.ShapeService" autowire="byName" scope="prototype" id="shapeServiceId"></bean> <alias name="shapeService" alias="shapeServiceAlias" />

----------------------------------------------------------------------------------------------------

Output :: after change to prototype
===========================================================
shapeService and shapeService1 equal=false
shapeService and shapeService2 equal=false
shapeService and shapeServiceId equal=false
shapeService and shapeServiceAlias equal=false
===========================================================


all will be false as each time new instance will be created with the prototype scope.

No comments:

Post a Comment