Archive
Fast Forward To MVC 'ONE'
- Pretty interface, which users to love to use it. (Example mint.com)
- Interactive & Intuitive interface.
- Functional interface. It does what it promises and always does that.
- Low or almost NIL learning curve for any new developer.
- Able to extend interface + functionality by 3rd party developers. (That strives any web product)
- Quick turn around of code to market
- Able to remove or disable code or by choice of end user. (user is deployer)
That’s this post is all about. I know, many of you, thinking, c’mon man, Nineties called, they want their MVC one back. But lets entertain this idea for a while. For example, I want to write simple webapp ‘java press’ blogging engine, able to deploy it with in couple of weeks and my available heap size is 64MB (pretty common for VPS plans). If I go by spring mvc route, it will take me a couple of weeks, just enough to setup my environment, DBs, etc etc. I will have re-hash my knowledge of spring, and spring mvc controllers etc etc. But if I just pick JSPs model, i am ready to convert static HTMLs with-in a day.
- For deployments for small companies or concept deliveries or Y combinator kinda projects, time to deliver is small.
- You don’t have to muck around which framework to use. You think of doing something, and you doing it.
- Think of 3rd party developers pool, you get access to. If you document well, even PHP developer can pick JSP skills in few days and write JSPs for your webapp. (Imagine hiring PHP developer for spring MVC work. I don’t have time & budget for training).
- With new JEE specs coming out, you are always safe to upgrade your app and take advantages of new features without rewriting anything. (That’s what spring says, we give you another layer of abstraction. But you have upgrade code for spring 3.x now, isn’t it?)
- For scalability, it’s cheaper than before, clustering solutions based upon clouds. So my one deployment supports 50 concurrent sessions, I will just throw couple extra virtual tomcat instances, with in same cloud instance. or couple other different ways.
- I am less worried about performance, because recent benchmarks for tomcat 6 using JDK 6, is impressive.
- Using data source pooling, getting connections from JSP isn’t resource intensive. (As part of SDK, some classes with static methods can provided, to provide some encapsulation on common used API calls)
- web.xml supports basic security model. And again, as part of SDK, some common servlet filters can be provided for cross cutting concerns like security, logging, transactions.
- DB Caching can be ignored for now, assuming DB server and tomcat instance are co-located or installed in same instance. Caching adds lots of code maintenance, research & testing. Benefits of using caching diminishes in small db and small users.
- Well known advantage of JSP, do code change and see changes immediately on web browser. Hence time to see results, while doing development is almost nil. We all have taken coffee breaks in our past projects while waiting for server to bounce.
Spring scope using Example
This post is about to experiment about spring framework ‘singleton’ and ‘prototype’ scope. I created couple of tests to show proof of concept and clear our understanding of ‘singleton’ scope.
Those are new or fairly new to spring framework, they sometimes get confused, when they read the term ‘singleton’ in spring beans. As traditionally, we know, Singleton class pattern makes sure, we have single instance of that class per jvm. But when we talk about singleton pattern in spring framework world or lets say spring context world, it’s singleton pattern applied per spring container. Now we can have multiple containers initiated in a java virtual machine, hence we can have multiple instance of same class possible, but single instance per container per bean definition.
Example, Lets use simple java bean, which stores it’s own creation time and also defines equals method to check that equality.
public class SpringBean {
private long createTime;
public SpringBean()
{
this.createTime = System.currentTimeMillis();
}
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
SpringBean other = (SpringBean) obj;
if (this.createTime != other.createTime) {
return false;
}
return true;
}
}
My spring context file defined only two beans
- <bean id=”singletonBean” class=”com.jframeworks.learn.SpringBean”/>
- <bean id=”prototypeBean” class=”com.jframeworks.learn.SpringBean” scope=”prototype”/>
Both beans use same class but different scope. Lets define a testsuite class which will initiate these beans and run some basic tests.
Class: SpringScopeTestSuite, method = runTests
public SpringScopeTestSuite(ApplicationContext ctx, ApplicationContext ctx2) {
this.ctx = ctx;
this.ctx2 = ctx2;
}
...............
public void runTests(String name) throws InterruptedException
{
SpringBean singletonBean0 = this.getBeanUsingContext("singletonBean");
Thread.sleep(50);//To make sure, next bean from context is at different timestamp.
SpringBean singletonBean1 = (SpringBean) this.getCtx().getBean("singletonBean");
Thread.sleep(50);
SpringBean protoTypeBean0 = (SpringBean) this.getCtx().getBean("prototypeBean");
Thread.sleep(50);
SpringBean protoTypeBean1 = (SpringBean) this.getCtx().getBean("prototypeBean");
Thread.sleep(50);
SpringBean singletonBean2 = (SpringBean) this.getCtx2().getBean("singletonBean");
Thread.sleep(50);
SpringBean protoTypeBean2 = (SpringBean) this.getCtx2().getBean("prototypeBean");
System.out.println(name + " =====================================================");
System.out.println(name + " Equality Tests");
System.out.println(name + " =====================================================");
System.out.println(name + " Two beans references with Scope 'singleton'");
System.out.println(name + " singletonBean0.equals(singletonBean1) = " + singletonBean0.equals(singletonBean1));
System.out.println(name + " singletonBean1.equals(singletonBean2) = " + singletonBean1.equals(singletonBean2));
System.out.println(name + " singletonBean1.equals(protoTypeBean1) = " + singletonBean1.equals(protoTypeBean1));
System.out.println(name + " protoTypeBean0.equals(protoTypeBean1) = " + protoTypeBean0.equals(protoTypeBean1));
System.out.println(name + " protoTypeBean1.equals(protoTypeBean2) = " + protoTypeBean1.equals(protoTypeBean2));
System.out.println(name + " =====================================================");
}
To run this test, lets define test runner class, ‘BasicSpringScopeTest’
public class BasicSpringScopeTest
{
public static void main( final String[] args )
{
try {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationConfig.xml");
ApplicationContext ctx2 = new ClassPathXmlApplicationContext("applicationConfig.xml");
SpringScopeTestSuite test = new SpringScopeTestSuite(ctx, ctx2);
test.runTests("singleThread");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Now executing this class, we see this output…
singleThread =====================================================
singleThread Equality Tests
singleThread =====================================================
singleThread Two beans references with Scope 'singleton'
singleThread singletonBean0.equals(singletonBean1) = true
singleThread singletonBean1.equals(singletonBean2) = false
singleThread singletonBean1.equals(protoTypeBean1) = false
singleThread protoTypeBean0.equals(protoTypeBean1) = false
singleThread protoTypeBean1.equals(protoTypeBean2) = false
singleThread =====================================================
Analysis.
As singletonBean0 and singletonBean1 comes from same container, and their scope is default ‘singleton’, hence they are same instance.
singletonBean1 and singletonBean2, though are same bean and ‘singleton’ scope, but they comes from different container. Hence they are different instance of same class.
singletonBean1 and prototypeBean1 comes from same container and same class, but prototypeBean1 is different bean definition and ‘prototype’ scope. Every time, this bean retrieved from container, spring container creates new instance. Hence they are not equals. They are not equal for two reasons
- They are two different bean definition (even same class type)
- prototypeBean is defined as ‘prototype’ scope’
Next equality check is for prototypeBean0 and prototypeBean1 beans. Even they come from same container but they still not equal, because they refer to spring bean defined as ‘prototype’ scope.
Last equality check is for prototypeBean1 and prototypeBean2 beans. They are not equal for two reasons..
- They both comes from different spring container
- They refer to spring bean defined as ‘prototype’ scope.
Conclusion
Spring framework takes away boiler plate code of defining Singleton classes in code base. This aligns with their philosphy of letting developers concentrate on business logic instead of writing boiler plate code.
Just to be clear, in spring world, a bean definition is singleton not bean class. We can have multiple of bean definitions of same class, each representing different singleton class. This makes spring container light weight container. Prototype scope is not used widely, but it can specified depending upon technical requirements.
For further testing, there is another code, which runs test suite in mutli-threaded environment.
public class AdvancedSpringScopeTest
{
public static void main( final String[] args )
{
try
{
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationConfig.xml");
ApplicationContext ctx2 = new ClassPathXmlApplicationContext("applicationConfig.xml");
SpringScopeTestSuite testSuite = new SpringScopeTestSuite(ctx, ctx2);
Thread thread1 = new Thread(testSuite, "thread1");
Thread thread2 = new Thread(testSuite, "thread2");
Thread thread3 = new Thread(testSuite, "thread3");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
This class output is..
thread2 =====================================================
thread2 Equality Tests
thread2 =====================================================
thread2 Two beans references with Scope 'singleton'
thread1 =====================================================
thread1 Equality Tests
thread1 =====================================================
thread1 Two beans references with Scope 'singleton'
thread1 singletonBean0.equals(singletonBean1) = true
thread3 =====================================================
thread1 singletonBean1.equals(singletonBean2) = false
thread2 singletonBean0.equals(singletonBean1) = true
thread2 singletonBean1.equals(singletonBean2) = false
thread2 singletonBean1.equals(protoTypeBean1) = false
thread1 singletonBean1.equals(protoTypeBean1) = false
thread1 protoTypeBean0.equals(protoTypeBean1) = false
thread3 Equality Tests
thread3 =====================================================
thread3 Two beans references with Scope 'singleton'
thread3 singletonBean0.equals(singletonBean1) = true
thread3 singletonBean1.equals(singletonBean2) = false
thread3 singletonBean1.equals(protoTypeBean1) = false
thread1 protoTypeBean1.equals(protoTypeBean2) = false
thread1 =====================================================
thread2 protoTypeBean0.equals(protoTypeBean1) = false
thread3 protoTypeBean0.equals(protoTypeBean1) = false
thread2 protoTypeBean1.equals(protoTypeBean2) = false
thread2 =====================================================
thread3 protoTypeBean1.equals(protoTypeBean2) = false
thread3 =====================================================
thread1.start();
thread2.start();
thread3.start();
//make sure, all threads finish.
Thread.sleep(2500);
Spring scope using Example
This post is about to experiment about spring framework ‘singleton’ and ‘prototype’ scope. I created couple of tests to show proof of concept and clear our understanding of ‘singleton’ scope.
Those are new or fairly new to spring framework, they sometimes get confused, when they read the term ‘singleton’ in spring beans. As traditionally, we know, Singleton class pattern makes sure, we have single instance of that class per jvm. But when we talk about singleton pattern in spring framework world or lets say spring context world, it’s singleton pattern applied per spring container. Now we can have multiple containers initiated in a java virtual machine, hence we can have multiple instance of same class possible, but single instance per container per bean definition.
Example, Lets use simple java bean, which stores it’s own creation time and also defines equals method to check that equality.
public class SpringBean {
private long createTime;
public SpringBean()
{
this.createTime = System.currentTimeMillis();
}
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (this.getClass() != obj.getClass()) {
return false;
}
SpringBean other = (SpringBean) obj;
if (this.createTime != other.createTime) {
return false;
}
return true;
}
}
My spring context file defined only two beans
- <bean id=”singletonBean” class=”com.jframeworks.learn.SpringBean”/>
- <bean id=”prototypeBean” class=”com.jframeworks.learn.SpringBean” scope=”prototype”/>
Both beans use same class but different scope. Lets define a testsuite class which will initiate these beans and run some basic tests.
Class: SpringScopeTestSuite, method = runTests
public SpringScopeTestSuite(ApplicationContext ctx, ApplicationContext ctx2) {
this.ctx = ctx;
this.ctx2 = ctx2;
}
...............
public void runTests(String name) throws InterruptedException
{
SpringBean singletonBean0 = this.getBeanUsingContext("singletonBean");
Thread.sleep(50);//To make sure, next bean from context is at different timestamp.
SpringBean singletonBean1 = (SpringBean) this.getCtx().getBean("singletonBean");
Thread.sleep(50);
SpringBean protoTypeBean0 = (SpringBean) this.getCtx().getBean("prototypeBean");
Thread.sleep(50);
SpringBean protoTypeBean1 = (SpringBean) this.getCtx().getBean("prototypeBean");Thread.sleep(50);
SpringBean singletonBean2 = (SpringBean) this.getCtx2().getBean("singletonBean");
Thread.sleep(50);
SpringBean protoTypeBean2 = (SpringBean) this.getCtx2().getBean("prototypeBean");
System.out.println(name + " =====================================================");
System.out.println(name + " Equality Tests");
System.out.println(name + " =====================================================");
System.out.println(name + " Two beans references with Scope 'singleton'");
System.out.println(name + " singletonBean0.equals(singletonBean1) = " + singletonBean0.equals(singletonBean1));
System.out.println(name + " singletonBean1.equals(singletonBean2) = " + singletonBean1.equals(singletonBean2));
System.out.println(name + " singletonBean1.equals(protoTypeBean1) = " + singletonBean1.equals(protoTypeBean1));
System.out.println(name + " protoTypeBean0.equals(protoTypeBean1) = " + protoTypeBean0.equals(protoTypeBean1));
System.out.println(name + " protoTypeBean1.equals(protoTypeBean2) = " + protoTypeBean1.equals(protoTypeBean2));
System.out.println(name + " =====================================================");
}
To run this test, lets define test runner class, ‘BasicSpringScopeTest’
public class BasicSpringScopeTest
{
public static void main( final String[] args )
{
try {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationConfig.xml");
ApplicationContext ctx2 = new ClassPathXmlApplicationContext("applicationConfig.xml");
SpringScopeTestSuite test = new SpringScopeTestSuite(ctx, ctx2);
test.runTests("singleThread");
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Now executing this class, we see this output…
singleThread =====================================================
singleThread Equality Tests
singleThread =====================================================
singleThread Two beans references with Scope 'singleton'
singleThread singletonBean0.equals(singletonBean1) = true
singleThread singletonBean1.equals(singletonBean2) = false
singleThread singletonBean1.equals(protoTypeBean1) = false
singleThread protoTypeBean0.equals(protoTypeBean1) = false
singleThread protoTypeBean1.equals(protoTypeBean2) = false
singleThread =====================================================
Analysis.
As singletonBean0 and singletonBean1 comes from same container, and their scope is default ‘singleton’, hence they are same instance.
singletonBean1 and singletonBean2, though are same bean and ‘singleton’ scope, but they comes from different container. Hence they are different instance of same class.
singletonBean1 and prototypeBean1 comes from same container and same class, but prototypeBean1 is different bean definition and ‘prototype’ scope. Every time, this bean retrieved from container, spring container creates new instance. Hence they are not equals. They are not equal for two reasons
- They are two different bean definition (even same class type)
- prototypeBean is defined as ‘prototype’ scope’
Next equality check is for prototypeBean0 and prototypeBean1 beans. Even they come from same container but they still not equal, because they refer to spring bean defined as ‘prototype’ scope.
Last equality check is for prototypeBean1 and prototypeBean2 beans. They are not equal for two reasons..
- They both comes from different spring container
- They refer to spring bean defined as ‘prototype’ scope.
Conclusion
Spring framework takes away boiler plate code of defining Singleton classes in code base. This aligns with their philosphy of letting developers concentrate on business logic instead of writing boiler plate code.
Just to be clear, in spring world, a bean definition is singleton not bean class. We can have multiple of bean definitions of same class, each representing different singleton class. This makes spring container light weight container. Prototype scope is not used widely, but it can specified depending upon technical requirements.
For further testing, there is another code, which runs test suite in mutli-threaded environment.
public class AdvancedSpringScopeTest
{
public static void main( final String[] args )
{
try
{
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationConfig.xml");
ApplicationContext ctx2 = new ClassPathXmlApplicationContext("applicationConfig.xml");
SpringScopeTestSuite testSuite = new SpringScopeTestSuite(ctx, ctx2);
Thread thread1 = new Thread(testSuite, "thread1");
Thread thread2 = new Thread(testSuite, "thread2");
Thread thread3 = new Thread(testSuite, "thread3");
}
catch (Exception ex)
{
ex.printStackTrace();
}
}
}
This class output is..
thread2 =====================================================
thread2 Equality Tests
thread2 =====================================================
thread2 Two beans references with Scope 'singleton'
thread1 =====================================================
thread1 Equality Tests
thread1 =====================================================
thread1 Two beans references with Scope 'singleton'
thread1 singletonBean0.equals(singletonBean1) = true
thread3 =====================================================
thread1 singletonBean1.equals(singletonBean2) = false
thread2 singletonBean0.equals(singletonBean1) = true
thread2 singletonBean1.equals(singletonBean2) = false
thread2 singletonBean1.equals(protoTypeBean1) = false
thread1 singletonBean1.equals(protoTypeBean1) = false
thread1 protoTypeBean0.equals(protoTypeBean1) = false
thread3 Equality Tests
thread3 =====================================================
thread3 Two beans references with Scope 'singleton'
thread3 singletonBean0.equals(singletonBean1) = true
thread3 singletonBean1.equals(singletonBean2) = false
thread3 singletonBean1.equals(protoTypeBean1) = false
thread1 protoTypeBean1.equals(protoTypeBean2) = false
thread1 =====================================================
thread2 protoTypeBean0.equals(protoTypeBean1) = false
thread3 protoTypeBean0.equals(protoTypeBean1) = false
thread2 protoTypeBean1.equals(protoTypeBean2) = false
thread2 =====================================================
thread3 protoTypeBean1.equals(protoTypeBean2) = false
thread3 =====================================================
thread1.start();
thread2.start();
thread3.start();
//make sure, all threads finish.
Thread.sleep(2500);
Recent Comments