Rich Web Experience

JSFOne

Private Events

Blogs

View all Blogs >>
  • Craig Walls

    Author of Spring in Action

    I've been scanning the early draft of OSGi R4.2, specifically RFC 124, "A Compo more»

  • John Heintz

    Principal Consultant with New Aspects of Software

    In a recent discussion interview questions came up, here's my favorite one.To set some context this question is designed to gauge the abst more»

  • Scott Leberknight

    Chief Architect at Near Infinity

    In almost every application I've done, the database tables have some kind of audit trail fields. Sometimes this is a separate "audit log"... more»

  • Alex Miller

    Sr. Engineer with Terracotta Inc.

    It’s time again for my monthly music club mix. This month is a bit of indulgent power pop and just a smattering of stuff I’ve... more»

  • Nathaniel Schutta

    Author, speaker, software engineer focused on user interface design.

    Recently, I sat through some vendor presentations and while I won’t name names, I just have to say: learn to give better talks. If I... more»

  • Stuart Halloway

    CEO of Relevance

    This is Part Three of a series of articles on Java.next. In Part Three, I will explore how the Java.next languages (JRuby, Groovy, Clo more»

  • Matt Raible

    Creator of AppFuse and author of Spring Live

    The developers of Seam have come up with a list of major issues with JSF. I'm assuming many more»

  • Jared Richardson

    Agile coach and co-author of Ship It

    The first scheduled class for the NFJS One venture is now official! And we don't even have the website live yet. :) This class will be a go... more»

  • Pratik Patel

    Enterprise Architect

    A fine fellow by the name of Srini came to my talk on JPA at the NoFl more»

  • Michael Nygard

    Agile technology leader and dynamicist

    A short while back, I did a brief series on the value of "d more»

  • Richard Haefel

    VP of Developer Relations, Curl Inc.

    more»

  • Kenneth Kousen

    President of Kousen IT, Inc.

    A couple of weeks ago I participated in a BriefingsDirect podcast about using more»

  • Neal Ford

    Application Architect at ThoughtWorks, Inc.

    A while back, Richard Monson-Haelfel was working on a presentation called "10 Things Every Software Architect Should Know", which was a great... more»

  • Ted Neward

    Enterprise, Virtual Machine and Language Wonk

    As Joel points out, we've made a draft of the S more»

  • Jason Rudolph

    Author of Getting Started with Grails

    As we’ve seen over the last several weeks, it’s remarkably easy for code to earn the badge of 100% more»

  • Erik Doernenburg

    Principal Consultant @ Thoughtworks

    The Spring framework has become ubiquitous in the Java world, and there are a large number of to more»

  • Mike Levin

    Software Developer specializing in Web2.0 websites

    more»

  • Ryan Shriver

    Business and Technology Consulting

    more»

  • Mark Johnson

    Director of Consulting at CGI

    At the Columbus NFJS show held on July 25-27th during one of the BOF sessions Dave Bock, Scott Davis and I discussed unit tests vs functional... more»

  • Joseph Nusairat

    Author of Beginning JBoss Seam & Co-Author of Beginning Groovy & Grails

    Well i am assuming Apress has the most random site in the world at times.But today only they have our recent book, Beginning Groovy & Grai more»

  • Venkat Subramaniam

    Founder of Agile Developer, Inc.

    I received a copy of "Beginning Groovy and Grails—From Novice to Professional" book by Apress written by more»

  • Andrew Glover

    Co-author of "Continuous Integration"

    Web Component Testing Screencast- my friend Rod Coffin demonstrates some interesting aspects re more»

  • Jeff Brown

    G2One Director Of North American Operations - Groovy and Grails Developer

    We are really excited to have a 3 day Groovy/Grails training event coming up in Chicago later this month. The training dates are August... more»

  • Brian Pontarelli

    Brian Pontarelli - founder of Inversoft

    I went to the 37 Signals event last night sponsored by CPB. The speake more»

  • Graeme Rocher

    Project Lead of the Grails Project & CTO of G2One

    I'll be giving a talk on the state of Grails at the London Groovy+Grails user group meeting on the 31st of July. more»

  • Keith Donald

    Lead of Spring Web and Creator of Spring Web Flow

    I am pleased to announce that Developing Rich Web Applications with Spring, a three-day bootcamp lead by SpringSource engineers on web... more»

  • Pramod Sadalage

    Co-author of "Refactoring Databases:Evolutionary Database Development"

    When creating a Foreign Key constraint on the database as shown below ALTER TABLE BOOK ADD (CONSTRAINT FK_BOOK_ more»

  • Vladimir Vivien

    Software Engineer / Consultant

    Judging from the list of features that will be included in NetBeans 6.5, more»

  • David Bock

    Principal Consultant, CodeSherpas Inc.

    I just spent this weekend speaking at the Ag ile IT Exchange conference i more»

  • Kirk Knoernschild

    Software Developer & Mentor

    I’ve published a summary of the OSGi survey results on the APS blog more»

  • Brian Goetz

    Author of Java Concurrency in Practice

    This surprised the heck out of me.  We recently finished a new TV room down in the basement.  We have a 50″ plasma TV, mounted on the... more»

  • Jason Harwig

    Senior Software Engineer at Near Infinity

    I was reading a blog entry at more»

  • Pete Behrens

    Organizational Agility Coach

    Marti nig & Associates Methods & Tools group recentl more»

  • Brian Sam-Bodden

    Java author, Ruby geek and Open Source Advocate

    In this installment we are going to build the Dashboard page of the Tempo application. T more»

  • Mark Fisher

    Spring Integration Lead

    In my recent post, I had mentio more»

  • Ron Bodkin

    Chief Software Architect, Quantcast

    I'm looking forward to speaking at The Rich Web Experience conference in San Jose next month. The event runs from September 7th through 9th.... more»

  • Mark Goodwin

    Web Application Security Specialist

    We've already looked at one of the two big problems posed by anti DNS pinning on Java applets; because there's rebinding on the applet and... more»

  • Scott Davis

    Author of "Groovy Recipes" & TDD Expert

    Every time I see a live show at the Denver Botanic more»

  • Romain Guy

    Java User Interface expert.

    more»

  • Ramnivas Laddad

    Author of AspectJ in Action, Principal at SpringSource

    InfoQ.com has published my AOP myths and realities talk recorded at a No Fluff Just Stuff conference. InfoQ.com founded by Floyd Marine more»

  • David Geary

    Author of Graphic Java and co-author of Core JSF

    The 2006 NFJS tour kicked off t more»

  • Howard Lewis Ship

    Creator of Tapestry and HiveMind

    <p>Tapestry 5 includes its own internal Inversion of Control container. This is often a point of contention ... why not just use <a... more»

  • Kito Mann

    Editor-in-chief of JSF Central and the author of JSF in Action

    A priority grouped list of more major issues that require extensive design and discussion.... more»

  • Jason Hunter

    Author of Java Servlet Programming

    I just posted the JDOM 1.1 release for download. This release includes about 20 improvements and bug fixes. more»

In the Spotlight - Mark Fisher

Mark Fisher

Spring Integration Lead

Mark Fisher is a Senior Software Engineer with SpringSource and lead of the Spring Integration product. As a core developer for the Spring Framework, he has played a central role in developing the annotation-based configuration features of Spring 2.5. He has also provided consulting and training services for clients across numerous industries throughout North America including several fortune 500 companies.

In addition to the "No Fluff, Just Stuff" symposium tour, Mark speaks regularly at conferences such as The Spring Experience and SpringOne. He has also presented at Java User Groups throughout the United States on various Spring-related topics.





















Presentations by Mark Fisher

Message Driven POJOs with Spring

Spring 2.0 introduced support for Message-Driven POJOs meaning that it is now possible to receive JMS messages asynchronously and delegate the handling of those messages to simple objects even within a lightweight application running outside of any application server. If your POJO has a return value, it will automatically be sent to a response destination."

Enterprise Security with Spring

Spring Security (formerly known as 'Acegi') enables self-contained, consistent, and extensible solutions for securing your applications. Version 2.0 provides major enhancements including a domain-specific XML namespace, convention-based defaulting, and annotation support. This provides a significantly simpler experience for developers while still supporting the same degree of flexibility."

Configuring Spring with Annotations

In this session, we will take a deep-dive into annotation-based dependency injection with Spring 2.5. You will learn how to combine annotation and XML formats, how to customize component scanning, and how to leverage Java 6 annotations within a Spring application. Since there is no "one size fits all" solution to application configuration, we will wrap up the discussion with general guidelines to consider when employing this approach."

Enterprise Integration Patterns with Spring - Part II

Building on Part I, Part II of this workshop will demo a series of messaging systems built on Spring. The samples will exercise event-driven scenarios involving distributed architectures with messaging and remoting. Each sample will highlight a variety of important enterprise integration patterns.
"

Enterprise Integration Patterns with Spring - Part I

In the first-part of this two-part workshop, Mark will focus on the essentials of Enterprise Integration with Spring. First, he will take a whirlwind tour of Spring's enterprise integration support libraries. Next, he will discuss the "big picture" of an event-driven architecture based on messaging with an overview of key enterprise integration patterns. Attendees will leave with a clear understanding of Spring's integration capabilities and an appreciation for the benefits of message-driven architecture, ready to put that into practice in Part II."

Enterprise Integration with Spring, Part 1

The first part of this two-part session will focus on the essentials of Enterprise Integration with Spring. The discussion will cover the enterprise integration support libraries in the Spring Framework core within the context of well-established design principles such as loose coupling and separation of concerns.
"

Enterprise Integration with Spring, Part 2

The second part of this two-part session will introduce Spring Integration, a new addition to the Spring portfolio. We will begin with a high-level overview of Enterprise Integration Patterns as catalogued in the highly influential book of the same name. We will then embark on a demo-driven exploration of Spring Integration to see how it enables the development of applications based on those patterns.
"

Configuring Spring with Annotations

In this session, we will take a deep-dive into annotation-based dependency injection with Spring 2.5. You will learn how to combine annotation and XML formats, how to customize component scanning, and how to leverage Java 6 annotations within a Spring application. Since there is no "one size fits all" solution to application configuration, we will wrap up the discussion with general guidelines to consider when employing this approach.
"

Simplifying Enterprise Applications with Spring, Part 1

Developing enterprise applications isn't easy. You not only have to worry about constantly evolving business logic, but also need to address infrastructure concerns ranging from transaction management and security to manageability and integration with diverse external applications. Spring, the most popular lightweight enterprise application framework, comes to the rescue by simplifying the common needs of enterprise applications. This session (part 1 of 2) presents the core concepts of the Spring Framework."

Simplifying Enterprise Applications with Spring, Part 2

This session (part 2 of 2) will cover advanced concepts in the Spring framework. While the core concepts in the first session will get you started with Spring, the advanced concepts in this session will help you be more effective at developing Spring-based applications."

SpringSource Team Blog
The voice of SpringSource


Mark Fisher's complete blog can be found at: http://blog.interface21.com/main/author/markf/

Friday, December 21, 2007

In my recent post, I had mentioned that the Subversion repository for Spring Integration would be publicly accessible soon, and I’m pleased to provide that link now. You can checkout the project with the following command:
[code]
svn co https://anonsvn.springframework.org/svn/spring-integration/base/trunk spring-integration
[/code]

If the checkout is successful, you should see the following directory structure:
[code]
spring-integration/
+–build-spring-integration/
+–spring-build/
+–spring-integration-core/
+–spring-integration-samples/
[/code]

I would like to take this opportunity to walk through a couple of the samples that are in ’spring-integration-samples’. Keep in mind this project is definitely a work-in-progress (currently a 0.5 SNAPSHOT), but the samples should give you an idea of how the programming model is taking shape, and I’m very much looking forward to getting some feedback.

Hello World

The first sample is the obligatory “Hello World” demo. This one demonstrates the main components: Message Channel and Message Endpoint. This demo also reveals how the Spring Integration approach is non-invasive - providing a complete separation of concerns between business logic and messaging. In this case, the “business logic” is a simple HelloService:
[code lang=”Java”]
public class HelloService {

public String sayHello(String name) {
return “Hello ” + name;
}
}
[/code]
This example uses an XML-based configuration for the Message Endpoint (we’ll see the annotation approach next):
[code lang=”XML”]
default-output-channel="outputChannel"
handler-ref="helloService"
handler-method="sayHello"/>
[/code]
There you see that ‘handler-ref’ simply points to a Spring-managed bean. If you have used Spring’s MessageListenerAdapter for asynchronous JMS reception, then this should look familiar - especially if you are using Spring 2.5’s new jms namespace and the “jms:listener” element. Finally, the HelloWorldDemo starts the application context and then interacts with the channels:
[code lang=”Java”]
ChannelRegistry channelRegistry = (ChannelRegistry) context.getBean(MessageBusParser.MESSAGE_BUS_BEAN_NAME);
MessageChannel inputChannel = channelRegistry.lookupChannel(”inputChannel”);
MessageChannel outputChannel = channelRegistry.lookupChannel(”outputChannel”);
inputChannel.send(new StringMessage(1, “World”));
System.out.println(outputChannel.receive().getPayload());
[/code]
That example involves lookup of the MessageBus bean - which implements the ChannelRegistry interface. However, in a non-demo “real world” scenario, any component that would access channels can have the registry provided via dependency injection. All it needs to do is implement ChannelRegistryAware (or use @Autowired). This is the same approach used elsewhere in Spring - such as ApplicationEventPublisherAware.

Annotation-driven Endpoint and Subscriber

The next example shows how to configure a Message Endpoint with annotations. In fact, this particular endpoint even provides the data that is translated (behind the scenes) into Message payload content with the @Polled method annotation. It could alternatively provide an input channel for receiving messages asynchronously.
[code lang=”Java”]
@MessageEndpoint(defaultOutput=”quotes”)
public class QuotePublisher {

@Polled(period=300)
public Quote getQuote() {
BigDecimal price = new BigDecimal(new Random().nextDouble() * 100);
return new Quote(generateTicker(), price.setScale(2, RoundingMode.HALF_EVEN));
}

private String generateTicker() {
// randomly generates 3-letter tickers
}
}
[/code]
On the receiving side, there is a @Subscriber annotation:
[code lang=”Java”]
public class QuoteSubscriber {

@Subscriber(channel=”quotes”)
public void log(Object o) {
System.out.println(o);
}
}
[/code]
Here is the XML which registers the annotation post-processor and the 2 Spring-managed beans (notice that this example is using the ’spring-integration’ schema as the primary namespace.
[code lang=”XML”]
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:beans="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/integration
http://www.springframework.org/schema/integration/spring-integration-1.0.xsd">


[/code]
By the way, the ‘annotation-driven’ element also enables the @Publisher annotation which triggers the creation of AOP advice for asynchronously sending the return value of any annotated method to a channel.

Simple Routing

The routing sample features a Message Endpoint that produces an incrementing integer every 3 seconds and a router that resolves the target channel name (note that a router method can also return more than one result and can return actual MessageChannel instances rather than names).
[code lang=”Java”]
@MessageEndpoint
public class Counter {

private AtomicInteger count = new AtomicInteger();

@Polled(period=3000)
public int getNumber() {
return count.incrementAndGet();
}

@Router
public String resolveChannel(int i) {
if (i % 2 == 0) {
return “even”;
}
return “odd”;
}
}
[/code]
On the receiving end of these channels, we have 2 different methods that simply log the message payload:
[code lang=”Java”]
@Component
public class NumberLogger {

@Subscriber(channel=”even”)
public void even(int i) {
System.out.println(”even: ” + i);
}

@Subscriber(channel=”odd”)
public void odd(int i) {
System.out.println(”odd: ” + i);
}
}
[/code]
By the way, notice that the NumberLogger is annotated with Spring’s @Component. The @MessageEndpoint annotation also contains @Component as a meta-annotation. Both are therefore “stereotypes” and eligible for autodetection with Spring 2.5’s classpath-scanning. The XML for this example is extremely simple:
[code lang=”XML”]


[/code]



Hopefully this provides a decent introduction to the Spring Integration programming model. Feel free to checkout the code and try out these samples yourself. I am currently working on a “Getting Started” guide that I will make available after the holidays. If you do checkout the code, please be sure to update frequently. The code is constantly evolving, and in particular I am refactoring much of the core consumer/dispatcher code with the goal of providing the simplest possible extension points for adding either polling or event-driven message sources. In the next blog post, I plan to show some new additions to the ’spring-integration-samples’ featuring those extension points.


Friday, December 14, 2007

Yesterday morning I presented a 2-part session at The Spring Experience entitled “Enterprise Integration Patterns with Spring”. The first presentation included an overview of core Spring support for enterprise integration - including JMS, remoting, JMX, scheduling, and email. That presentation also included a high-level discussion of several of the Enterprise Integration Patterns introduced in the book of the same name by Gregor Hohpe and Bobby Woolf. In the second presentation, I officially unveiled “Spring Integration” - a new addition to the Spring portfolio. Spring Integration builds upon Spring’s core support while providing a higher level of abstraction largely inspired by those patterns. Here I would like to provide a brief overview of the topics I discussed in that session. You can also read two articles about Spring Integration that appeared yesterday on eWeek and InfoWorld.

First I described the goals and motivations of Spring Integration - namely that the implementation model should be simple and non-invasive - providing philosophical consistency with core Spring principles. Business components should be decoupled from the underlying messaging infrastructure and therefore testable in isolation. The framework should hide the complexities of thread-management while still enabling full configurability of thread pools, queue capacities, and scheduling parameters. Custom extension points should be provided as well-defined strategy interfaces. It should be possible to use dynamic languages for integration logic, such as routing and transformation. Configuration options should include generic XML, domain-specific namespace support, and annotations. While building upon these core Spring principles, the implementation will be leveraging core Spring features including lifecycle management, task execution, aspect-oriented programming, transaction management, dynamic language support, JMS, remoting, mail, and scheduling.

By following those goals and motivations, Spring Integration will simplify development of enterprise integration solutions. Since the concepts and implementations are so consistent, it will facilitate incremental adoption for existing Spring users who are beginning to explore SOA and EDA. Finally, as a member of the Spring portfolio, it will provide seamless compatibility and timely co-evolution with other products in the Spring portfolio.

After discussing those goals and motivations, I walked through the API. The core components are the Message, MessageChannel, and MessageEndpoint. A Message is a container for any type of data as well as a header that provides common messaging properties (id, correlation id, expiration, return address, sequence info, etc.). A MessageChannel provides send and receive methods, and those methods accept a timeout. The receive methods also accept a MessageSelector with a single method: boolean accept(Message message). Here is the basic interface definition for a MessageChannel

[code lang=”Java”]
public interface MessageChannel {
boolean send(Message message);
boolean send(Message message, long timeout);
Message receive();
Message receive(long timeout);
Message receive(MessageSelector selector);
Message receive(MessageSelector selector, long timeout);
}
[/code]

A MessageEndpoint connects a MessageHandler to an inbound MessageChannel and/or an outbound MessageChannel. The MessageHandler is a generic interface that provides a foundation for transformers, routers, and any other component that handles an incoming Message.

[code lang=”Java”]
public interface MessageHandler {
Message handle(Message message);
}
[/code]

Channel Adapters are used for sending to and receiving from external data sources. For example, to send a JMS message, an OutboundJmsChannelAdapter is provided. When configuring the messaging system, that adapter can be sent messages as if it were just another channel. A MessageBus wires together the various endpoints and channels. This is consistent with the way that a Spring ApplicationContext wires together objects. In fact, the MessageBus is itself an ApplicationContextAware object and detects the various messaging components from its context. This is very similar to the behavior of a DispatcherServlet in a Spring MVC application. Spring Integration’s namespace support provides a concise way to configure the components:

[code lang=”XML”]




[/code]

Alternatively, there is support for annotations:
[code lang=”Java”]
@MessageEndpoint(input=“inputChannel�?, defaultOutput=“outputChannel�?)�?
public class SimpleAnnotatedEndpoint {

@Handler
public String sayHello(String name) {
return “Hello ” + name;
}
}
[/code]

Annotations for transformation and routing (e.g. @Router, @Splitter, and @Aggregator) will also be supported. Additionally, “channel adapters” can be created with annotations, such as @Polled for input and @DefaultOutput for output if the handler returns a message and that message does not provide its own ‘return address’. For example, the following endpoint would print out “Hello World” every 5 seconds:
[code lang=”Java”]
@MessageEndpoint
public class SampleAnnotatedEndpoint {

@Polled(period=5000)�?
public String getName() {
return “World”;
}

@Handler
public String sayHello(String name) {
return “Hello ” + name;
}

@DefaultOutput
public void display(String message) {
System.out.println(message);
}
}
[/code]

The @MessageEndpoint also works “out of the box” with Spring 2.5’s new component-detection capabilities. Therefore the above example would not require any XML configuration at all. For an even simpler way to create an endpoint for a single method, you can use the @Subscriber annotation on that method:
[code lang=”Java”]
@Subscriber(channel=“testChannel�?)�?
public void test(String s) {

}
[/code]
That annotation and a corresponding @Publisher are both enabled with a single ‘annotation-driven’ element from the Spring Integration namespace. The @Publisher builds upon Spring AOP in order to publish the return-value of a method. It will also support other advice types, such as ‘before’ and ‘after-throwing’.

The examples above are based on a 0.5 version of Spring Integration. Therefore, these interfaces and annotations are subject to change. In fact, we are particularly interested in feedback during this early phase. I have already had several interesting discussions with attendees here at The Spring Experience who are very excited by the possibilities of this new offering. The 1.0 Milestone 1 release will be available in early January, and the 1.0 Final release will be available by Q2 2008. The 1.0 Final version will support multiple configuration formats (XML, namespace, and annotations), point-to-point and publish/subscribe channels, and several adapters (minimally: JMS, RMI, HttpInvoker, Hessian/Burlap, File, EMail, JDBC, stream, and Spring ApplicationEvents). It will also work seamlessly with Spring’s transaction management and dynamic language support. Finally, it will integrate with other Spring portfolio products such as Spring Web Services, Spring Web Flow, Spring MVC, Spring Batch, and Spring Security. Of course, we will also be working closely with the Spring Dynamic Modules project to OSGi-enable the messaging components.

Stay tuned to this blog for more information in the coming days including the public availability of the code repository. Also, be sure to read those articles that appeared yesterday at eWeek and InfoWorld.


Friday, November 9, 2007

Last night I attended a New England Java User Group (NEJUG) meeting where Reza Rahman presented a “comparative analysis” of EJB 3 and Spring. Reza is one of the authors of EJB 3 in Action. I enjoyed meeting Reza and respect him for presenting what may be considered a controversial topic. Also I appreciate that he did attempt to address pros and cons for both EJB 3 and Spring. Nevertheless, I feel compelled to clarify a few points that were not wholly accurate in his coverage of Spring and which led me (and other attendees) to believe the presentation was motivated by a bias toward EJB 3. To be fair, unlike a fixed specification version, Spring is constantly evolving and some of the things that I will point out here are new features. On the other hand, some are Spring 2.0 features that have been available for more than a year. I personally believe that a “comparative analysis” must account for the up-to-date feature set of the latest stable version of the products being compared. I think it goes without saying that I might be a bit biased as well, but my motivation here is to provide a wholly objective response so that the presentation could perhaps be revised to reflect a more ‘apples-to-apples’ comparison. I will provide brief responses to 10 “themes” of the presentation.

1. EJB uses annotations for metadata. Spring uses XML.

It was mentioned that Spring is beginning to support more annotations but that it is “going to take them a while”. However, the Spring 2.0 release provided full JPA integration with @PersistenceContext for injecting the EntityManager and annotation-driven transaction management with Spring’s @Transactional annotation (supporting the same semantics as a @Stateless EJB with the default propagation of REQUIRED). I was particularly discouraged that the comparison did not include JPA on both sides (see point #3 below). Spring 2.0 also introduced full annotation-based AspectJ support (@Aspect, @Before, @After, @Around) and the concept of “stereotype” annotations. For example, the @Repository annotation enables non-invasive Exception translation for data-access code that uses JPA or Hibernate APIs directly (without Spring’s templates). Spring even provided annotation support as early as version 1.2, such as @ManagedResource for transparently exporting any Spring-managed object as a JMX MBean.

Now the main reason this issue is #1 for me, is the comment that it is “going to take them a while”. As one of the main developers of Spring 2.5’s annotation-driven configuration support, I must say that the Spring metadata model is extremely flexible and therefore we have been able to provide a comprehensive annotation-based model more quickly than one might expect. In fact, Spring 2.5 provides support for JSR-250 annotations: @Resource, @PostConstruct, and @PreDestroy - as well as @WebServiceRef and @EJB. Of particular interest is @Resource since it is the primary annotation used for dependency injection in EJB 3. With Spring, the @Resource annotation supports not only JNDI lookups (as with EJB 3) but also injection of any Spring-managed object. This effectively combines the main Spring advantage that was mentioned in this presentation (Spring supports DI of any type of object) with the main EJB 3 advantage (use of annotations instead of XML). Spring 2.5 also introduces an even more fine-grained annotation-driven dependency injection model based on @Autowired and the (extensible) @Qualifier annotation. Spring 2.5 also extends the “stereotype” annotations to include @Service and @Controller. Each of the stereotype annotations extends the generic @Component annotation by applying it as a meta-annotation. By applying the same technique, the @Component annotation provides an extension point for user-defined stereotypes. Spring can even auto-detect these annotated components as an alternative to XML configuration. For example, this excerpt is taken from the 2.5 version of the PetClinic sample application:

[code lang=”XML”]

[/code]

No additional XML is required for the web controllers since they use annotation-driven dependency injection and annotations for request mapping. I point this out, because the presentation specifically emphasized the verbosity of configuration for the web-tier:

[code lang=”Java”]
@Controller
public class ClinicController {

private final Clinic clinic;

@Autowired
public ClinicController(Clinic clinic) {
this.clinic = clinic;
}

[/code]

For up-to-date coverage of Spring’s annotation support, see: Introduction to Spring 2.5 on The Server Side, or the latest version of Spring’s reference manual - specifically the Annotation-based configuration section. Also, stay tuned to this blog and the Spring Framework home for some soon-to-be-released articles and blogs covering version 2.5.

2. Spring allows you to support multiple deployment environments but requires more configuration.

This one was actually presented as a Spring advantage but with an emphasis on the configuration overhead. The truth is any project where testing and agile development are taken seriously is going to require supporting “multiple deployment environments”. In other words, this particular topic often gets distorted as if it applies only to multiple production environments. In reality, having to deploy to an Application Server during each development and testing cycle is a major obstacle to agility. Typically Spring users will modularize their configuration such that “infrastructure” configuration (e.g. DataSource, TransactionManager, JMS ConnectionFactory) is separate and dynamic properties are externalized. Since Spring provides support for replacing ‘${placeholders}’ based on the externalized properties, the inclusion of different properties files typically becomes a transparent concern.

3. EJB with JPA, Spring with Hibernate

I must admit this one bothered me the most. In the comparison slides, the EJB 3 examples showed JPA with data-access via entityManager and the entityManager instance being provided with the @PersistenceContext annotation. On the other hand, the Spring examples used Hibernate and showed setter injection of the Hibernate SessionFactory. In my mind, this violates the first rule of a bona-fide “comparative analysis”: use the most similar feature available on both sides of the comparison. In this particular case, Spring does provide support for using the JPA API directly (i.e. JpaTemplate is completely optional; direct usage of the ‘entityManager’ still participates in Spring transactions, etc), and Spring also recognizes the @PersistenceContext annotation. This support has been available since Spring 2.0 (final release was more than a year ago), so I don’t understand why the comparison does not use JPA on the Spring side as well. Other parts of the comparison were clearly based on Spring 2.0, so this leaves the impression of being selectively out-of-date and revealing a bias. If this particular example were modified to be ‘apples-to-apples’, it would have undermined one of the main overall themes: that Spring requires more configuration whereas EJB 3 relies on standard annotations.

Now, even though I believe the usage of Hibernate rather than JPA on the Spring side distorted the comparison, it does simultaneously reveal a strength of Spring. If you do want to use the Hibernate API directly instead of relying on the JPA API, Spring enables that, and it does so in a consistent way with regard to Spring transaction management and Exception translation. This then opens up the opportunity to use Hibernate features that extend beyond the limitations of JPA, such as Hibernate’s “criteria” query API. By the same token, if you would like to add some direct JDBC for data-access where ORM is overkill, that is also supported in Spring - even when invoked within the same transaction as Hibernate or JPA data-access.

4. Spring makes no assumptions, you have to provide configuration.

One specific example was the definition of a transaction manager. It was stated that you have to understand things at the container-vendor level to configure Spring integration. This is incorrect. For example, the following bean definition does not contain any container-specific information, yet Spring will auto-detect the transaction manager in all Java EE Application Servers:

[code lang=”XML”]

[/code]

If you do want to leverage container-specific features such as per-transaction isolation levels, then Spring also provides a few specialized implementations: WebLogicJtaTransactionManager WebSphereUowTransactionManager, and OC4JJtaTransactionManager. Switching between these implementations is only a matter of changing this single definition.

In addition to this, the Spring configuration slides were unnecessarily verbose. I’m afraid this may also have been motivated by the goal of emphasizing that EJB unlike Spring relies on intelligent defaulting. For example, the slide showed:

[code lang=”XML”]

[/code]

Actually, if there is a single ‘transactionManager’ defined within a Spring context, then that attribute does not need to be provided explicitly on the ‘annotation-driven’ element. That attribute is available solely for enabling the usage of multiple transaction managers within one application if necessary. These techniques of “auto-detection” and “intelligent defaulting” apply throughout Spring, such as the JMS ‘connectionFactory’ for a message-listener (which is implicit in the example of #6 below) and the automatic location of an existing MBean server or RMI registry.

On a positive note, it was actually mentioned as an advantage that Spring allows for “local” transaction management. While EJB requires JTA for transaction management, many applications do not need distributed transactions across two-phase commit capable resources. In such cases, Spring allows for simpler transaction managers with less-overhead: DataSourceTransactionManager (for JDBC), HibernateTransactionManager, or JpaTransactionManager. I would have expected to hear a bit more detail on that particular Spring strength if the goal was to accurately describe the pros and cons. For example, this is a huge benefit for testing outside of the container or developing within a lightweight IDE environment such as Eclipse or IDEA.

Furthermore, if you do require JTA for distributed transactions but want to run in a lightweight container like Tomcat or Jetty, Spring easily supports standalone JTA providers like Atomikos and JOTM. Sure Spring’s transaction manager setup requires configuration of a single bean definition, but it really is a one-time cost - and well worth the benefit.

5. Spring does not have a stateful application paradigm.

The benefits of a stateless service layer are fairly well-established as a best practice, and Spring embraces that. Spring does provide scopes other than singleton however. Spring’s “prototype” scope enables a distinct instance for each injection or lookup, and Spring 2.0 introduced web scopes: “request” and “session”. The scoping mechanism itself is even extensible; it’s possible to define and map a custom scope to the notion of a conversation. Spring also supports simple object pooling with the CommonsPoolTargetSource, but object pooling is rarely the best solution for state management.

More importantly, Spring does provide very robust, highly configurable state-management for web applications via Spring Web Flow. There the conversational state is managed transparently, contrary to the claim of this presentation that developers have to interact directly with the HTTP Session to manage state in Spring applications. Furthermore, the repository configuration is pluggable so that various strategies may be used for physical storage of the state (session, client, backend cache, etc.). Finally, the latest developments in Spring Web Flow include support for extended persistence context and fully integrated support for JSF.

6. Spring requires configuration of a container per MessageListener.

Spring 2.5 provides a new ‘jms’ namespace to greatly simplify the configuration of message-listeners. Notice that there is no separate configuration for a container per-listener. Multiple listeners share the configuration, and intelligent defaulting is used extensively:

[code lang=”XML”]




[/code]

It was also mentioned that thread management is always a per-container issue. However, this is not true. The message listener containers actually use Spring’s TaskExecutor abstraction, and there are a number of implementations available. For example, if running on Java 5+, you can configure a thread-pool executor, or you can even configure a CommonJ WorkManager executor. The executors can easily be shared across multiple listener containers if desired. In fact, the ‘task-executor’ attribute is available on the ‘listener-container’ element (shown above) where it would be logically set 1 time but shared by each container instance that is created internally per listener definition.

7. Concurrent Consumers cannot be greater than 1.

Okay, this was truly the most bizarre moment of the night. The code slide depicted a perfectly stateless implementation of a MessageListener (as it should be!), and then the configuration slide showed the ‘maxConcurrentConsumers’ value set to 1. At this point, it was stated that setting the value to anything other than one would cause thread-safety issues. I’m sorry to say, but this is flat out misinformation. The concurrent consumers setting determines the number of threads that are available for receiving Messages, and the ‘maxConcurrentConsumers’ determines to what extent the consumer pool can grow under heavy load (as demand decreases, the number of consumers drops back to the value set as ‘concurrentConsumers’). As long as the MessageListener itself is thread-safe, this value can be increased to control throughput. Personally I would never use a MessageListener for anything other than delegating to a “service” so that even in the (very unlikely) case that I wanted to have a stateful object ultimately handling the content of the Message, then that target object would be configured with a pooling target source. The MessageListener itself would always be thread-safe and therefore the values for ‘concurrentConsumers’ and ‘maxConcurrentConsumers’ can be used as intended for managing throughput.

This topic raises one other point. A comprehensive comparison would reveal another pro of Spring here - namely Spring’s listener adapter. The adapter provides automatic conversion from the JMS Message to a simple Java payload and then delegates to any Spring-managed object to handle that payload. For example, in the configuration above, the “logger” and “tradeService” listeners do not even have to implement the MessageListener interface. If they do not, then Spring automatically wraps those POJOs with an adapter that converts the Message and determines which method to invoke. It even converts a return value (if there is one) into a JMS reply Message and automatically replies to the destination specified by the incoming Message’s ‘reply-to’ property. This same behavior is extremely difficult to implement from scratch since the JMS MessageListener handling method has a ‘void’ return type:

[code lang=”Java”]
public interface MessageListener {
void onMessage(Message message);
}
[/code]

8. Spring’s usage of the AspectJ expression language is powerful but cryptic.

EJB 3 is limited to @AroundInvoke, and the example showed this with some simple auditing applied through interception. The Spring example showed @Before advice since the auditing only required something to happen before the method execution (not around). I appreciated that the example emphasized the need to call context.proceed() on the EJB 3 side while the AspectJ @Before advice is much simpler. I was disappointed however that some of the attendees seemed to think that the AspectJ model was limited to @Before and therefore that EJB 3 @AroundInvoke was more powerful. To be comprehensive here, I would have included an example of @Around advice on the Spring side - to clarify that it is supported, but it is simply not always necessary.

The greatest limitation of the EJB 3 interception model is that the method (or class) that should be intercepted is directly annotated, whereas one of the fundamental goals of AOP is to be non-invasive - ultimately even supporting advice on code that is outside of your control. Given that goal, the AspectJ expression language is arguably as clear and concise as it can be while supporting all of the possible constructs where advice may be applied. While it may appear cryptic at first, it is fairly easy to learn. For example, it is conceptually similar but much more limited in scope than regular expressions (see the AspectJ homepage for the expression language reference for details).

9. Spring tool support has been sparse.

On this particular point, I would first point out that using Spring helps to reduce the development/test cycle so that a majority of a developer’s time is spent within the IDE not deploying to an Application Server, and IDEs are great tools. The Eclipse-based Spring IDE is an incredibly valuable add-on for development assistance in Spring projects, and IntelliJ also provides Spring support in IDEA. As far as deployment tools, Spring-based applications can of course be deployed into any container, and since Spring can utilize the underlying resources (DataSource, TransactionManager, JMS ConnectionFactory, etc), these are managed in the same way as with any application deployed within the particular container. Spring’s ability to expose any object as a JMX MBean (including support for the aforementioned @ManagedResource) and its support for JMX notifications/listeners is very powerful for custom monitoring and management requirements.

That said, clearly Spring could benefit from increased tool support. This is why the ‘Spring Tool Suite’ was just recently established to bring together Spring IDE, AJDT, AspectJ, and Mylyn and evolve into much more. For more information, see the articles and links available here.

10. With EJB as a standard, you can migrate from one vendor to another. With Spring, you still have to port the metadata.

Everyone knows that portability is “easier said than done”. While EJB 3 may be less painful than EJB 2 in this regard (less verbosity in the configuration), the fact remains that Application Servers offer different features and thus different configuration options. Clearly if you are deploying to an Application Server, you probably should take advantage of certain specific features. The problem with the original statement is that it implies something at the level of application configuration that makes Spring inherently less portable. On the contrary, any Spring user who has migrated from one Application Server to another would agree that Spring provides a significant amount of abstraction in this regard. In point #4 above, I mentioned that Spring’s JtaTransactionManager uses auto-detection within any Java EE Application Server and that the same applies for MBean servers, and RMI registries. Along these same lines, when using JPA, Spring detects persistence.xml and creates the EntityManagerFactory accordingly. In all of these cases, Spring metadata - whether it be annotations (@PersistenceContext, @Transactional, @Resource, etc) or XML (’jee:jndi-lookup’, etc) is just as portable as any EJB 3 application.

Even when moving beyond the capabilities of a typical EJB 3 application, minimal configuration changes provide significant convenience. In this regard, Spring actually facilitates portability to a much wider variety of environments: Tomcat, Jetty, standalone, Eclipse, IDEA, and so on. My suggestion here would be to grab the Spring distribution’s PetClinic sample application and try building and deploying the WAR file into multiple Application Servers. Then, notice that it can just as easily be deployed within Tomcat, and that the degree of portability actually far exceeds that of an EJB 3 application as soon as you want to switch between the different data access strategies that are supported by the application: JDBC, Hibernate and JPA. Take a close look at the different configuration files for those different versions (located within the ’samples/petclinic/war/WEB-INF’ directory). Especially with the additions of Spring 2.5, the configuration is extremely concise. Notice that the only change necessary to switch between these different versions is one line in the web.xml where the Spring context is bootstrapped. If you want to run with a container-managed DataSource, use the one line ‘jee:jndi-lookup’ element. Otherwise there is a bean definition for using a standalone DataSource, and the actual database properties are externalized into jdbc.properties.

Conclusion

Well, it looks as though I had more to say than I thought :) . My intention has been to provide some objective clarifications from the Spring perspective, and I hope that is evident to the reader. I know that this presentation has been very popular at JUGs and conferences, and I think it’s an important discussion. Many Java developers are overwhelmed by the vast number of options today, and it’s important that they have all of the facts necessary to make well-informed decisions. While I have not emphasized it here (and you probably don’t want me to go on any further), one point of the presentation as well as the book (EJB 3 in Action) is that Spring and EJB 3 need not be mutually exclusive. Spring can be used within EJB applications, EJBs can be accessed from Spring applications, and Spring now supports most of the same annotations: @Resource, @PersistenceContext, @PostConstruct, @PreDestroy, @EJB, and @WebServiceRef.


Tuesday, May 29, 2007

NOTE: This post has been updated as of May 31, 2007 to reflect the state of the 2.1-M2 official release

Two weeks ago I blogged about the new annotation-driven dependency injection capabilities of Spring 2.1, and I mentioned that I would follow-up with more info “later in the week”. It turns out that was a bit optimistic, but the good news is the functionality has evolved quite a bit in the meantime. Therefore, to follow along with the examples here you will need to download the 2.1-M2 official release (or if you are one of the first people to read this updated entry and M2 is not yet available, you should grab at least nightly build #115 which you can download here).

The first thing I want to demonstrate is how to create an application context without using any XML. For those who have used Spring’s BeanDefinitionReader implementations, this will look very familiar. Before creating the context however, we need a few “candidate” beans on the classpath. Continuing with the example from my previous blog, I have the following two interfaces:
[code lang=”Java”]
public interface GreetingService {
String greet(String name);
}
[/code]
[code lang=”Java”]
public interface MessageRepository {
String getMessage(String language);
}
[/code]
…and these corresponding implementations:
[code lang=”Java”]
@Component
public class GreetingServiceImpl implements GreetingService {

@Autowired
private MessageRepository messageRepository;

public String greet(String name) {
Locale locale = Locale.getDefault();
if (messageRepository == null) {
return “Sorry, no messages”;
}
String message = messageRepository.getMessage(locale.getDisplayLanguage());
return message + ” ” + name;
}
}
[/code]
[code lang=”Java”]
@Repository
public class StubMessageRepository implements MessageRepository {

Map messages = new HashMap();

@PostConstruct
public void initialize() {
messages.put(”English”, “Welcome”);
messages.put(”Deutsch”, “Willkommen”);
}

public String getMessage(String language) {
return messages.get(language);
}
}
[/code]

Now as promised… to assemble this admittedly trivial “application” without any XML:
[code lang=”Java”]
Locale.setDefault(Locale.GERMAN);
GenericApplicationContext context = new GenericApplicationContext();
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan(”blog”); // the parameter is ‘basePackage’
context.refresh();
GreetingService greetingService = (GreetingService) context.getBean(”greetingServiceImpl”);
String message = greetingService.greet(”Standalone Beans”);
System.out.println(message);
[/code]
And the result:
[code lang=”Java”]
Willkommen Standalone Beans
[/code]

Essentially, this is the exact same behavior as when using the component-scan XML element from the new “context” namespace (as demonstrated in my previous blog). However, I want to focus on some of the newer features as well as customization options. First, I will remove the @Repository annotation from the StubMessageRepository, and rerun the tests which produces the following exception:
[code lang=”Java”]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘greetingServiceImpl’: Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private blog.MessageRepository blog.GreetingServiceImpl.messageRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [blog.MessageRepository] is defined: expected single bean but found 0
[/code]
Clearly the @Autowired annotation indicates a required dependency by default, but this can easily be switched by adding the ‘required’ parameter with a value of ‘false’, such as:
[code lang=”Java”]
@Component
public class GreetingServiceImpl implements GreetingService {

@Autowired(required=false)
private MessageRepository messageRepository;

[/code]
The result after this modification:
[code lang=”Java”]
Sorry, no messages
[/code]

To make things a bit more interesting, I will add the JDBC version of the MessageRepository (also from the previous post):
[code lang=”Java”]
@Repository
public class JdbcMessageRepository implements MessageRepository {

private SimpleJdbcTemplate jdbcTemplate;

@Autowired
public void createTemplate(DataSource dataSource) {
this.jdbcTemplate = new SimpleJdbcTemplate(dataSource);
}

@PostConstruct
public void setUpDatabase() {
jdbcTemplate.update(”create table messages (language varchar(20), message varchar(100))”);
jdbcTemplate.update(”insert into messages (language, message) values (’English’, ‘Welcome’)”);
jdbcTemplate.update(”insert into messages (language, message) values (’Deutsch’, ‘Willkommen’)”);
}

@PreDestroy
public void tearDownDatabase() {
jdbcTemplate.update(”drop table messages”);
}

public String getMessage(String language) {
return jdbcTemplate.queryForObject(”select message from messages where language = ?”, String.class, language);
}
}
[/code]
As long as the stub version still does not contain the @Repository annotation, rerunning the tests will now produce the following exception:
[code lang=”Java”]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘greetingServiceImpl’: Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private blog.MessageRepository blog.GreetingServiceImpl.messageRepository; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘jdbcMessageRepository’: Autowiring of methods failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire method: public void blog.JdbcMessageRepository.createTemplate(javax.sql.DataSource); nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [javax.sql.DataSource] is defined: expected single bean but found 0
[/code]

Obviously a chain reaction of autowiring failures has resulted since no DataSource is available in the context. However, as a firm believer in test-driven development, I would like to unit test my implementation prior to setting up the infrastructure. Luckily, the scanner is fairly customizable, and I can provide filters, such as:
[code lang=”Java”]
Locale.setDefault(Locale.GERMAN);
GenericApplicationContext context = new GenericApplicationContext();

boolean useDefaultFilters = false;

ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context, useDefaultFilters);
scanner.addExcludeFilter(new AssignableTypeFilter(JdbcMessageRepository.class));
scanner.addIncludeFilter(new AnnotationTypeFilter(Component.class));
scanner.addIncludeFilter(new RegexPatternTypeFilter(Pattern.compile(”blog\\.Stub.*”)));
scanner.scan(”blog”);

context.refresh();
GreetingService greetingService =
(GreetingService) context.getBean(”greetingServiceImpl”);
String message = greetingService.greet(”Standalone Beans”);
System.out.println(message);
[/code]
As you can see, I disabled the ‘defaultFilters’ and explicitly added my own. In this case, that was not completely necessary since the default includes the @Component and @Repository annotations, but I wanted to show the various filtering options - including not only annotations, but also assignable types and even regular expressions. The main goal of course was to disable the JDBC version of MessageRepository in favor of the stub, and according to my result, that is exactly what happened:
[code lang=”Java”]
Willkommen Standalone Beans
[/code]

Assuming that I am now ready to incorporate the JDBC version, I will likely need to include some XML configuration for the DataSource, such as:
[code lang=”XML”]
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-2.1.xsd">


[/code]
Then, I can combine the scanning with an XmlBeanDefinitionReader (notice that I have reverted to the default filters only):
[code lang=”Java”]
Locale.setDefault(Locale.GERMAN);
GenericApplicationContext context = new GenericApplicationContext();

ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.scan(”blog”);

BeanDefinitionReader reader = new XmlBeanDefinitionReader(context);
reader.loadBeanDefinitions(”classpath:/blog/dataSource.xml”);

context.refresh();
GreetingService greetingService = (GreetingService) context.getBean(”greetingServiceImpl”);
String message = greetingService.greet(”Hybrid Beans”);
System.out.println(message);
[/code]
The context contains both the scanned beans as well as those defined in XML, and the result is:
[code lang=”Java”]
Willkommen Hybrid Beans
[/code]

Up to this point, you’ve seen that 0 candidate beans will cause the autowiring to fail unless the ‘required’ parameter of @Autowired is set to false. Given that the autowiring is following ‘by-type’ semantics, more than 1 bean will cause a failure regardless of the required parameter’s value. For example, after adding the @Repository annotation back to the StubMessageRepository and rerunning the previous example, I receive the following exception:
[code lang=”Java”]
org.springframework.beans.factory.BeanCreationException: Error creating bean with name ‘greetingServiceImpl’: Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private blog.MessageRepository blog.GreetingServiceImpl.messageRepository; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [blog.MessageRepository] is defined: expected single bean but found 2
[/code]
This can be resolved by switching to ‘by-name’ semantics - accomplished via Spring 2.1’s support for the JSR-250 @Resource annotation:
[code lang=”Java”]
@Component
public class GreetingServiceImpl implements GreetingService {

@Resource(name=”jdbcMessageRepository”)
private MessageRepository messageRepository;

[/code]

You probably noticed in the previous example that the bean name (as specified in the @Resource annotation) defaults to the decapitalized non-qualified classname. To override this behavior, it is possible to add your own implementation of the BeanNameGenerator strategy, such as:
[code lang=”Java”]
private static class MyBeanNameGenerator implements BeanNameGenerator {

public String generateBeanName(BeanDefinition definition, BeanDefinitionRegistry registry) {
String fqn = definition.getBeanClassName();
return Introspector.decapitalize(fqn.replace(”blog.”, “”).replace(”Jdbc”, “”));
}
}
[/code]
Then providing this strategy to the scanner overrides the default:
[code lang=”Java”]
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(context);
scanner.setBeanNameGenerator(new MyBeanNameGenerator());
scanner.scan(”blog”);
[/code]
And therefore, the name specified in the @Resource annotation can be modified accordingly:
[code lang=”Java”]
@Resource(name=”messageRepository”)
private MessageRepository messageRepository;
[/code]
NOTE: When relying on the container for autowiring, the default naming strategy is typically sufficient (i.e. it works “behind the scenes”). Therefore the naming strategy should only be considered for cases where you will be referring to beans by name elsewhere. Even then, for isolated cases it is much simpler to explicitly provide a bean name in the ’stereotype’ annotation (e.g. @Repository(”messageRepository”)). Providing your own strategy can be useful if you are able to take advantage of naming conventions that are used consistently throughout your application (This particular example is a little contrived, but hopefully demonstrates that the strategy is very accommodating so that you can follow your own naming conventions).

So far all of the beans have been configured with the default ’singleton’ scope, but scope resolution is another customizable strategy of the scanner. The default will look for a @Scope annotation on each component. For example, to configure the GreetingServiceImpl as a ‘prototype’, simply add the following:
[code lang=”Java”]
@Scope(”prototype”)
@Component
public class GreetingServiceImpl implements GreetingService { .. }
[/code]
While the default annotation approach is quite simple, scope is almost always a deployment-specific consideration. Therefore it often does not belong at the class-level or in the source code at all. For these reasons, the following strategy interface is available and may be specified on the scanner as with the BeanNameGenerator in the previous example:
[code lang=”Java”]
public interface ScopeMetadataResolver {
ScopeMetadata resolveScopeMetadata(BeanDefinition definition);
}
[/code]
Note that the name generation and scope resolution strategies may also be provided in the XML-based configuration, such as:
[code lang=”XML”]
name-generator="blog.MyBeanNameGenerator"
scope-resolver="blog.MyScopeMetadataResolver"/>
[/code]

Likewise, custom filters can be added as sub-elements:
[code lang=”XML”]





[/code]

I realize this entry has already covered quite a bit of ground, but there is one last topic I would like to cover. In the previous post, I included an aspect with the <aop:aspectj-autoproxy/> element. Now I want to demonstrate how to add the autoproxy behavior with our standalone version. First, the aspect itself (same as last time):
[code lang=”Java”]
@Aspect
public class ServiceInvocationLogger {

private int invocationCount;

@Pointcut(”execution(* blog.*Service+.*(..))”)
public void serviceInvocation() {}

@Before(”serviceInvocation()”)
public void log() {
invocationCount++;
System.out.println(”service invocation #” + invocationCount);
}
}
[/code]
Next, I need to add an include filter for the @Aspect annotation (it is no longer included in the default filters):
[code lang=”Java”]
scanner.addIncludeFilter(new AnnotationTypeFilter(Aspect.class));
scanner.scan(”blog”);
[/code]
And finally, I need to register the AspectJ annotation-based autoproxy creator (prior to calling refresh() on the context):
[code lang=”Java”]
AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(context);
context.refresh();
[/code]
The result:
[code lang=”Java”]
service invocation #1
Willkommen Hybrid Beans
[/code]

Hopefully this entry and the preceding one have provided a sufficient introduction to these new features of Spring 2.1. You should now have a decent understanding of how to combine the component scanning and annotation configuration in small doses alongside “traditional” Spring XML configuration if you prefer. Also, by providing your own filters, name generators, and scope resolvers, you can customize the configuration process. The official 2.1-M2 release contains more detailed information in the reference documentation.

Stay tuned to this Interface21 Team Blog to learn about more new features as we continue to progress from the current milestone phase toward the RC1 release of Spring 2.1, and if you are not particularly excited about the annotation-driven configuration, then you may want to keep an eye out for an upcoming blog by Costin Leau on Spring Java Configuration - which offers yet another alternative to XML but without the invasiveness of annotations in your application code.


Friday, May 18, 2007

Keith Donald

When Sun scheduled my JavaOne 2007 session on Spring Web Flow for Friday, the last day of the conference, I wasn't sure what to expect. I was honored to have been accepted again this year, but I wondered what I would see in terms of attendance presenting on the last day of the 4-day conference.

I could not have been more pleased with how things transpired. When I checked in at speaker setup on Thursday 800 people had pre-registered for my Friday session. Fifteen minutes before my talk was to begin the room had reached that number. In the end, 1000 JavaOne attendees came to room 307-310 of the Moscone center to experience an adrenaline-powered Spring Web Flow test drive.

Spring Web Flow Test Drive

In this blog I am hoping to re-create some the most exciting parts of my JavaOne Web Flow presentation. Checkout the screen cast below to see what was personally the most exhiliterating part of the presentation for me–building out a search flow from the ground up for deployment in a Java Server Faces (JSF) environment.


This search flow lets you enter some search criteria, see some results, execute a new search, and browse a result's details if you choose (existing WebFlowians will recognize this as the JSF version of the familiar Phonebook sample application).

When watching the screen cast note how Web Flow manages all navigation and state for the application, while standard JSF components care for view rendering and model data binding. Also note even when I screw something up I can quickly fix it and get back to work because I never need to restart my server or switch my editor.

The Spring IDE visualization of this flow is below:

Search flow

Get the code for this demo here. If you are using Eclipse with Web Tools you can import phonebook as an Dynamic Web Project and fire up the webapp inside your IDE.

Spring Web Flow at Spring One

Be sure to catch Erwin's talks on Spring Web Flow at SpringOne on June 20th-22nd. He'll be presenting two very interesting sessions that show how to put this product to work.