Archive

Posts Tagged ‘IoC’

Why Spring Framework?

November 21, 2009 3 comments

 

 

Why Spring Framework?

 

Since the widespread implementation of J2EE applications in 1999/2000, it has not been an unqualified success in practice. While it has brought a welcome standardization to core middle-tier concepts such as transaction management, many — perhaps most — J2EE applications are over-complex, take excessive effort to develop, and exhibit disappointing performance. EJB  soon became  a widely accepted enterprise solution. But as time passed, many could recognize the disadvantages of using EJB.

In EJB versions prior to 3.0, a single EJB component requires a remote/local interface, a home interface, and a bean implementation class. Hence EJBs were called heavyweight components. Moreover, in those EJB versions, an EJB component could only run within an EJB container and had to look up other EJBs with JNDI (Java Naming and Directory Interface). So EJB components were technology dependent because they could not be reused and tested outside the scope of an EJB container.

Spring framework hence came out to reduce such complexities in enterprise application development. You can think of Spring framework as, minus of EJB’s disadvantages plus a comprehensively layered modular Java/JEE  framework which is flexible, light-weight, less intruisive and technology independent. Spring is applicable in a wide range of environments, not just server-side J2EE applications which was the original motivation. Spring also offers many valuable services for J2EE applications.

 

Problems with the Traditional Approach to J2EE:

Experience has highlighted specific causes of complexity and other problems in J2EE applications. (Of course, not all of these problems are unique to J2EE!) In particular:

  • J2EE applications tend to contain excessive amounts of “plumbing” code. Many code reviews repeatedly reveal a high proportion of code that doesn’t do anything: JNDI lookup code, Transfer Objects, try/catch blocks to acquire and release JDBC resources. Writing and maintaining such plumbing code proves a major drain on resources that should be focused on the application’s business domain.
  • Many J2EE applications use a distributed object model where it is inappropriate. This is one of the major causes of excessive code and code duplication. It’s also conceptually wrong in many cases. Internally distributed applications are more complex than co-located applications, and often much less performant. Of course, if your business requirements dictate a distributed architecture, you need to implement a distributed architecture and accept the trade-off that incurs (and Spring offers features to help in such scenarios). But you shouldn’t do so without a compelling reason.
  • The EJB component model is unduly complex. EJB was conceived as a way of reducing complexity when implementing business logic in J2EE applications; it has not succeeded in this aim in practice.
  • EJB is overused. EJB was essentially designed for internally distributed, transactional applications. While nearly all non-trivial applications are transactional, distribution should not be built into the basic component model.
  • Many “J2EE design patterns” are not, in fact, design patterns, but workarounds for technology limitations. Overuse of distribution, and use of complex APIs such as EJB, have generated many questionable design patterns; it’s important to examine these critically and look for simpler, more productive, approaches.
  • J2EE applications are hard to unit test. The J2EE APIs, and especially, the EJB component model, were defined before the agile movement took off. Thus their design does not take into account ease of unit testing. Through both APIs and implicit contracts, it is surprisingly difficult to test applications based on EJB and many other J2EE APIs outside an application server. Yet unit testing outside an application server is essential to achieve high test coverage and to reproduce many failure scenarios, such as loss of connectivity to a database. It is also vital to ensuring that tests can be run quickly during the development or maintenance process, minimizing unproductive time waiting for redeployment.
  • Certain J2EE technologies have simply failed. The main offender here is entity beans, which have proven little short of disastrous for productivity and in their constraints on object orientation.

 

The traditional response to these problems has been to wait for tool support to catch up with the J2EE specifications, meaning that developers don’t need to wrestle with the complexity noted above. However, this has largely failed. Tools based on code generation approaches have not delivered the desired benefits, and have exhibited a number of problems of their own. In this approach, you might generate all those verbose JNDI lookups, Transfer Objects, and try/catch blocks.

In general, experience has shown that frameworks are better than tool-enabled code generation. A good framework is usually much more flexible at runtime than generated code; it should be possible to configure the behavior of one piece of code in the framework, rather than change many generated classes. Code generation also poses problems for round-tripping in many cases. A well-conceived framework can also offer a coherent abstraction, whereas code generation is typically just a shortcut that fails to conceal underlying complexities during the whole project lifecycle. (Often complexities will re-emerge damagingly during maintenance and troubleshooting.)

A framework-based approach recognizes the fact that there is a missing piece in the J2EE jigsaw: the application developer’s view. Much of what J2EE provides, such as JNDI, is simply too low level to be a daily part of programmer’s activities. In fact, the J2EE specifications and APIs can be judged as far more successful, if one takes the view that they do not offer the developer a programming model so much as provide a solid basis on which that programming model should sit. Good frameworks supply this missing piece and give application developers a simple, productive, abstraction, without sacrificing the core capability of the platform.

 

Using J2EE “out of the box” is not an attractive option. Many J2EE APIs and services are cumbersome to use. J2EE does a great job of standardizing low-level infrastructure, solving such problems as how can Java code access transaction management without dealing with the details of XA transactions. But J2EE does not provide an easily usable view for application code.That is the role of an application framework, such as Spring.

 

Recognizing the importance of frameworks to successful J2EE projects, many developers and companies have attempted to write their own frameworks, with varying degrees of success. In a minority of cases, the frameworks achieved their desired goals and significantly cut costs and improved productivity. In most cases, however, the cost of developing and maintaining a framework itself became an issue, and framework design flaws emerged. As the core problems are generic, it’s much preferable to work with a single, widely used (and tested) framework, rather than implement one in house.

No matter how large an organization, it will be impossible to achieve a degree of experience matching that available for a product that is widely used in many companies. If the framework is open source, there’s an added advantage in that it’s possible to contribute new features and enhancements that may be adopted. (Of course it’s possible to contribute suggestions to commercial products, but it’s typically harder to influence successful commercial products, and without the source code it’s difficult to make equally useful contributions.) Thus, increasingly, generic frameworks such as Struts and Hibernate have come to replace in-house frameworks in specific areas.

The Spring Framework grew out of this experience of using J2EE without frameworks, or with a mix of in-house frameworks. However, unlike Struts, Hibernate, and most other frameworks, Spring offers services for use throughout an application, not merely in a single architectural tier. Spring aims to take away much of the pain resulting from the issues in the list we’ve seen, by simplifying the programming model, rather than concealing complexity behind a complex layer of tools.

 

Spring enables you to enjoy the key benefits of J2EE, while minimizing the complexity encountered by application code.The essence of Spring is in providing enterprise services to Plain Old Java Objects (POJOs). This is particularly valuable in a J2EE environment, but application code delivered as POJOs is naturally reusable in a variety of runtime environments.

 

 

Spring in Context:

Spring is a manifestation of a wider movement. Spring is the most successful product in what can broadly be termed agile J2EE. While Spring has been responsible for real innovation, many of the ideas it has popularized were part of the zeitgeist and would have become important even had there been no Spring project. Spring’s greatest contribution — besides a solid, high quality, implementation — has been its combination of emerging ideas into a coherent whole, along with an overall architectural vision to facilitate effective use.

 

Inversion of Control and Dependency Injection: Read more…

Spring Framework Terminologies

November 19, 2009 Leave a comment

 

Chapter 1: Terminologies

 

Design Patterns:

A design pattern is a conceptual general reusable solution to a commonly occurring problem in software design. A design pattern can’t be transformed directly into code. It is a template for how to solve a problem that can be used in many different situations. Design patterns such as Factory, Builder, Decorator, and Service Locator (to name a few) have widespread recognition and acceptance within the software industry. Design patterns are best practices given a name that describe what the pattern does, where the pattern is best applied and the problems that the pattern addresses etc.

 

Framework:

Framework is a step ahead of design patterns. It is basically a conceptually organized structure based on best practices and design patterns to address complex issues. A software framework is an abstraction in which generic functionality can be selectively overridden, specialized or extensible by user code. Frameworks are similar to software libraries in way that they are reusable code wrapped in a well-defined API. However unlike libraries, the overall program’s flow of control is not dictated by the caller, but by the framework. This inversion of control is the distinguishing feature of software frameworks.

 

Object-Oriented Frameworks:

An object-oriented framework is a semi-finished object-oriented application laid out on OOPS concepts such as Inheritance, Polymorphism, Abstraction and Encapsulation.   Object-oriented design patterns typically show relationships and interactions between classes or objects. It encapsulates common features that can be used across the same application or even different applications. Common examples of such frameworks include Apache Struts, JSF, and Spring etc. A framework-driven approach to application development usually involves integration of multiple object-oriented frameworks and creation of specific functionalities as extensions to these frameworks.

Every framework provides its own extension points called hotspots. Hotspots are specific to a framework, usually pertaining to integration (application programming/service provider interfaces) and configuration (external metadata). For example, the EJB 2.0 specifications define hotspots for Java bean objects to be deployed in an EJB container.

 

Inversion of Control:

Inversion of control is a generic principle and not a design pattern. Rather, it is a broad concept that is implemented by several design patterns.

Inversion of control is applied during communication between a framework and custom application logic. A common feature of frameworks is to maintain control of all communication activities within an application because of which the primary objective of an application module will only be to provide functionalities that can be invoked by the framework. Compare this to a scenario without frameworks, in which there is a significant effort on how the modules can invoke and manage each other.

 

Application modules won’t have to directly access each other’s capabilities when deployed on top of a framework. The same is also true for invocations from external entities. Instead, every request must be routed through the framework. The framework, in turn, can make multiple calls across more than one module in a controlled fashion before returning a result back to the caller.

In the light of what has been said so far, inversion of control can be summed up as:

“Don’t call us (framework); we’ll call you (application)”

 

Service Locator pattern: Read more…