Archive

Posts Tagged ‘spring’

Using exceptions when designing an API

August 31st, 2014 No comments

Many knows the tradeoff of using exceptions while designing an application:

  • On one hand, using try-catch block nicely segregates between regular code and exception handling code
  • On the other hand, using exceptions has a definite performance cost for the JVM

Every time I’ve been facing this quandary, I’ve ruled in favor of the former, because “premature optimization is evil”. However, this week has proved me that exception handling in designing an API is a very serious decision.

I’ve been working to improve the performances of our application and I’ve noticed many silent catches coming from the Spring framework (with the help of the excellent dynaTrace tool). The guilty lines comes from the RequestContext.initContext() method:

if (this.webApplicationContext.containsBean(REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME)) {
    this.requestDataValueProcessor = this.webApplicationContext.getBean(
    REQUEST_DATA_VALUE_PROCESSOR_BEAN_NAME, RequestDataValueProcessor.class);
}

Looking at the JavaDocs, it is clear that this method (and the lines above) are called each time the Spring framework handles a request. For web applications under heavy load, this means quite a lot! I provided a pass-through implementation of the RequestDataValueProcessor and patched one node of the cluster. After running more tests, we noticed response times were on average 5% faster on the patched node compared to the un-patched node. This is not my point however.

Should an exception be thrown when the bean is not present in the context? I think not… as the above snippet confirms. Other situations e.g. injecting dependencies, might call for an exception to be thrown, but in this case, it has to be the responsibility of the caller code to throw it or not, depending on the exact situation.

There are plenty of viable alternatives to exceptions throwing:

Returning null
This means the intent of the code is not explicit without looking at the JavaDocs, and so the worst option on our list
Returning an Optional<T>
This makes the intent explicit compared to returning null. Of course, this requires Java 8
Return a Guava’s Optional<T>
For those of us who are not fortunate enough to have Java 8
Returning one’s own Optional<T>
If you don’t use Guava and prefer to embed your own copy of the class instead of relying on an external library
Returning a Try
Cook up something like Scala’s Try, which wraps either (hence its old name – Either) the returned bean or an exception. In this case, however, the exception is not thrown but used like any other object – hence there will be no performance problem.

Conclusion: when designing an API, one should really keep using exceptions for exceptional situations only.

As for the current situation, Spring’s BeanFactory class lies at center of a web of dependencies and its multiple getBean() method implementation cannot be easily replaced with one of the above options without forfeiting backward compatibility. One solution, however, would be to provide additional getBeanSafe() methods (or a better relevant name) using one of the above options, and then replace usage of their original counterpart step by step inside the Spring framework.

 

Send to Kindle
Categories: Java Tags: , ,

Spring configuration modularization for Integration Testing

July 27th, 2014 1 comment

Object-Oriented Programming advocates for modularization in order to build small and reusable components. There are however other reasons for this. In the case of the Spring framework, modularization enables Integration Testing, the ability to test the system or parts of it, including assembly configuration.

Why is it so important to test the system assembled with the final configuration? Let’s take a simple example, the making of a car. Unit Testing the car would be akin to testing every nuts and bolts of the car separately, while Integration Testing the car would be like driving it on a circuit. By testing only the car’s components separately, selling the assembled car is a huge risk as nothing guarantees it will behave correctly in real-life conditions.

Now that we have asserted Integration Testing is necessary to guarantee the adequate level of internal quality, it’s time to enable Integration Testing with the Spring framework. Integration Testing is based on the notion of SUT. Defining the SUT is to define the boundaries between what is tested and its dependencies. In nearly all cases, test setup will require to provide some kind of test double for each required dependency. Configuring those test doubles can only be achieved by modularizing Spring configuration, so that they can replace dependent beans located outside the SUT.

Sample bean dependency diagram

Fig. 1 – Sample bean dependency diagram

Spring’s DI configuration comes in 3 different flavors: XML – the legacy way, autowiring and the newest JavaConfig. We’ll have a look at how modularization can be achieved for each flavor. Mixed DI modularization can be deduced from each separate entry.

Autowiring

Autowiring is an easy way to assemble Spring applications. It is achieved through the use of either @Autowiring or @Inject. Let’s cover quickly autowiring: as injection is implicit, there’s no easy way to modularize configuration. Applications using autowiring will just have to migrate to another DI flavor to allow for Integration Testing.

XML

XML is the legacy way to inject dependencies, but is still in use. Consider the following monolithic XML configuration file:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
     xmlns:jee="http://www.springframework.org/schema/jee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
      http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee.xsd">
  <jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" />
  <bean id="productRepository" class="ProductRepository">
    <constructor-arg ref="dataSource" />
  </bean>
  <bean id="customerRepository" class="CustomerRepository">
    <constructor-arg ref="dataSource" />
  </bean>
  <bean id="orderRepository" class="OrderRepository">
    <constructor-arg ref="dataSource" />
  </bean>
  <bean id="orderService" class="OrderService">
    <constructor-arg ref="productRepository" index="0" />
    <constructor-arg ref="customerRepository" index="1" />
    <constructor-arg ref="orderRepository" index="2" />
  </bean>
</beans>

At this point, Integration Testing orderService is not easy as it should be. In particular, we need to:

  • Download the application server
  • Configure the server for the jdbc/MyDataSource data source
  • Deploy all classes to the server
  • Start the server
  • Stop the server After the test(s)

Of course, all previous tasks have to be automated! Though not impossible thanks to tools such as Arquillian, it’s contrary to the KISS principle. To overcome this problem and make our life (as well as test maintenance) easier in the process requires tooling and design. On the tooling part, we’ll be using a local database. Usually, such a database is of the in-memory kind e.g. H2. On the design part, his requires separating our beans by creating two different configuration fragments, one solely dedicated to the data source to be faked and the other one for the beans constituting the SUT.

Then, we’ll use a Maven classpath trick: Maven puts the test classpath in front of the main classpath when executing tests. This way, files found in the test classpath will “override” similarly-named files in the main classpath. Let’s create two configuration files fragments:

  • The “real” JNDI datasource as in the monolithic configuration
    <beans ...>
      <jee:jndi-lookup id="dataSource" jndi-name="jdbc/MyDataSource" />
    </beans>
  • The Fake datasource
    <beans...>
      <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource">
          <property name="driverClassName" value="org.h2.Driver" />
          <property name="url" value="jdbc:h2:~/test" />
          <property name="username" value="sa" />
          <property name="maxActive" value="1" />
      </bean>
    </beans>

    Note we are using a Tomcat datasource object, this requires the org.apache.tomcat:tomcat-jdbc:jar library on the test classpath. Also note the maxActive property. This reflects the maximum number of connections to the database. It is advised to always set it to 1 for test scenarios so that connections pool exhaustion bugs can be checked as early as possible.

The final layout is the following:

Fig. 2 – Project structure for Spring XML configuration Integration Testing

  1. JNDI datasource
  2. Other beans
  3. Fake datasource

The final main-config.xml file looks like:

<?xml version="1.0" encoding="UTF-8"?>
<beans...>
  <import resource="classpath:datasource-config.xml" />
  <!-- other beans go here -->
</beans>

Such a structure is the basics to enable Integration Testing.

JavaConfig

JavaConfig is the most recent way to configure Spring applications, bringing both compile-time (as autowiring) and explicit configuration (as XML) safety.

The above datasources fragments can be “translated” in Java as follows:

  • The “real” JNDI datasource as in the monolithic configuration
    @Configuration
    public class DataSourceConfig {
    
        @Bean
        public DataSource dataSource() throws Exception {
            Context ctx = new InitialContext();
            return (DataSource) ctx.lookup("jdbc/MyDataSource");
        }
    }
  • The Fake datasource
    public class FakeDataSourceConfig {
    
        public DataSource dataSource() {
            org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();
            dataSource.setDriverClassName("org.h2.Driver");
            dataSource.setUrl("jdbc:h2:~/test");
            dataSource.setUsername("sa");
            dataSource.setMaxActive(1);
            return dataSource;
        }
    }

However, there are two problems that appear when using JavaConfig.

  1. It’s not possible to use the same classpath trick with an import as with XML previously, as Java forbids to have 2 (or more) classes with the same qualified name loaded by the same classloader (which is the case with Maven). Therefore, JavaConfig configuration fragments shouldn’t explicitly import other fragments but should leave the fragment assembly responsibility to their users (application or tests) so that names can be different, e.g.:
    @ContextConfiguration(classes = {MainConfig.class, FakeDataSource.class})
    public class SimpleDataSourceIntegrationTest extends AbstractTestNGSpringContextTests {
    
        @Test
        public void should_check_something_useful() {
            // Test goes there
        }
    }
  2. The main configuration fragment uses the datasource bean from the other configuration fragment. This mandates for the former to have a reference on the latter. This is obtained by using the @Autowired annotation (one of the few relevant usage of it).
    @Configuration
    public class MainConfig {
    
        @Autowired
        private DataSource dataSource;
    
        // Other beans go there. They can use dataSource!
    }

Summary

In this article, I showed how Integration Testing to a Fake data source could be achieved by modularizing the monolithic Spring configuration into different configuration fragments, either XML or JavaConfig.

However, the realm of Integration Testing – with Spring or without, is vast. Should you want to go further, I’ll hold a talk on Integration Testing at Agile Tour London on Oct. 24th and at Java Days Kiev on Oct. 17th-18th.

This article is an abridged version of a part of the Spring chapter of Integration Testing from the Trenches. Have a look at it, there’s even a sample free chapter!

Integration Testing from the Trenches

Send to Kindle
Categories: Java Tags: ,

Easier Spring version management

July 6th, 2014 No comments

Earlier on, Spring migrated from a monolithic approach – the whole framework, to a modular one – bean, context, test, etc. so that one could decide to use only the required modules. This modularity came at a cost, however: in the Maven build configuration (or the Gradle one for that matter), one had to specify the version for each used module.

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
    ...
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.0.5.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.0.5.RELEASE</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Of course, professional Maven users would improve this POM with the following:

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
    ...
   <properties>
        <spring.version>4.0.5.RELEASE</spring.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>${spring.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>${spring.version}</version>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

There’s an more concise way to achieve the same through a BOM-typed POM (see section on scope import) since version 3.2.6 though.

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
    ...
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework</groupId>
                <artifactId>spring-framework-bom</artifactId>
                <type>pom</type>
                <version>4.0.5.RELEASE</version>
                <scope>import</scope>
            </dependency>
        <dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

Note that Spring’s BOM only sets version but not scope, this has to be done in each user POM.

Spring released very recently the Spring IO platform which also includes a BOM. This BOM not only includes Spring dependencies but also other third-party libraries.

<?xml version="1.0" encoding="UTF-8"?>
<project ...>
    ...
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>io.spring.platform</groupId>
                <artifactId>platform-bom</artifactId>
                <type>pom</type>
                <version>1.0.0.RELEASE</version>
                <scope>import</scope>
            </dependency>
        <dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.testng</groupId>
            <artifactId>testng</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
</project>

There’s one single problem with Spring IO platform’s BOM, there’s no simple mapping from the BOM version to declared dependencies versions. For example, the BOM’s 1.0.0.RELEASE maps to Spring 4.0.5.RELEASE.

To go further:

Send to Kindle
Categories: Java Tags: ,

The right bean at the right place

June 22nd, 2014 No comments

Among the different customers I worked for, I noticed a widespread misunderstanding regarding the use of Spring contexts in Spring MVC.

Basically, you have contexts, in a parent-child relationship:

  • The main context is where service beans are hosted. By convention, it is spawned from the /WEB-INF/applicationContext.xml file
    but this location can be changed by using the contextConfigLocation context parameter. Alternatively, one can use the AbstractAnnotationConfigDispatcherServletInitializer and in this case, configuration classes should be parts of the array returned by the getRootConfigClasses() method.
  • Web context(s) is where Spring MVC dispatcher servlet configuration beans and controllers can be found. It is spawned from <servlet-name>-servlet.xml or, if using the JavaConfig above, comes from classes returned by the getServletConfigClasses() method

As in every parent-child relationship, there’s a catch:

Beans from the child contexts can access beans from the parent context, but not the opposite.

That makes sense if you picture this: I want my controllers to be injected with services, but not the other way around (it would be a funny idea to inject controllers in services). Besides, you could have multiple Spring servlets with its own web context, each sharing the same main context for parent. When it goes beyond controllers and services, one should decide in which context a bean should go. For some, that’s pretty evident: view resolvers, message sources and such go into the web context; for others, one would have to spend some time thinking about it.

A good rule of thumb to decide in which context which bean should go is the following: IF you had multiple servlets (even if you do not), what would you like to share and what not.

Note: this way of thinking should not be tied to your application itself, as otherwise you’d probably end up sharing message sources in the main application context, which is a (really) bad idea.

This modularization let you put the right bean at the right place, promoting bean reusability.

Send to Kindle
Categories: JavaEE Tags: , ,

Vaadin and Spring integration through JavaConfig

March 9th, 2014 No comments

When I wrote the first version of Learning Vaadin, I hinted at how to integrate Vaadin with the Spring framework (as well as CDI). I only described the overall approach by providing a crude servlet that queried the Spring context to get the Application instance.

At the time of Learning Vaadin 7, I was eager to work on add-ons the community provided in terms of Spring integration. Unfortunately, I was sorely disappointed, as I found only few and those were lacking in one way or another. The only stuff mentioning was an article by Petter Holmström – a Vaadin team member (and voluntary fireman) describing how one should do to achieve Vaadin & Spring integration. It was much more advanced than my own rant but still not a true ready-to-be-used library.

So, when I learned that both Vaadin and Spring teams joined forces to provided a true integration library between two frameworks I love, I was overjoyed. Even better, this project was developed by none other than Petter for Vaadin and Josh Long for Pivotal. However, the project was aimed at achieving DI through auto-wiring. Since JavaConfig makes for a cleaner and more testable code, I filled an issue to allow that. Petter kindly worked on this, and in turn, I spent some time making it work.

The result of my experimentation with Spring Boot Vaadin integration has been published on morevaadin.com, a blog exclusively dedicated to Vaadin.

Send to Kindle
Categories: JavaEE Tags: , ,

Integrate Spring JavaConfig with legacy configuration

November 9th, 2013 1 comment

The application I’m working on now uses Spring both by parsing for XML Spring configuration files in pre-determined locations and by scanning annotations-based autowiring. I’ve already stated my stance on autowiring previously, this article only concerns itself on how I could use Spring JavaConfig without migrating the whole existing codebase in a single big refactoring.

This is easily achieved by scanning the package where the JavaConfig class is located in the legacy Spring XML configuration file:

<ctx:component-scan base-package="ch.frankel.blog.spring.javaconfig.config" />

However, we may need to inject beans created through the old methods into our new JavaConfig file. In order to achieve this, we need to autowire those beans into JavaConfig:

@Configuration
public class JavaConfig {

    @Autowired
    private FooDao fooDao;

    @Autowired
    private FooService fooService;

    @Autowired
    private BarService barService;

    @Bean
    public AnotherService anotherService() {

        return new AnotherService(fooDao);
    }

    @Bean
    public MyFacade myFacade() {

        return new MyFacade(fooService, barService, anotherService());
    }
}

You can find complete sources for this article (including tests) in IDEA/Maven format.

Thanks to Josh Long and Gildas Cuisinier for the pointers on how to achieve this.

Send to Kindle
Categories: Java Tags: ,

My case against autowiring

November 3rd, 2013 8 comments

Autowiring is a particular kind of wiring, where injecting dependencies is not explicit but actually managed implicitly by the container. This article tries to provide some relevant info regarding disadvantages of using autowiring. Although Spring is taken as an example, the same reasoning can apply to JavaEE’s CDI.

Autowiring basics

Autowiring flavors

Autowiring comes into different flavors:

  • Autowiring by type means Spring will look for available beans that match the type used in the setter. For example, for a bean having a setCar(Car car) method, Spring will look for a Car type (or one of its subtype) in the bean context.
  • Autowiring by name means Spring search strategy is based on beans name. For the previous example, Spring will look for a bean named car regardless of its type. This both requires the bean to be named (no anonymous bean here) and implies that the developer is responsible for any type mistmatch (if the car bean is of type Plane).

Autowiring is also possible for constructor injection.

Autowiring through XML configuration

Let’s first dispel some misconceptions: autowiring does not imply annotations. In fact, autowiring is available through XML since ages and can be enabled with the following syntax.

<bean autowire="byType" class="some.Clazz" />

This means Spring will try to find the right type to fill the dependency(ies) by using setter(s).

Alternative autowire parameters include:

  • by name: instead of matching by type, Spring will use bean names
  • constructor: constructor injection restricted to by-type
  • autodetect: use constructor injection, but falls back to by-type if no adequate constructor is found

Autowiring through annotations configuration

Available annotations are the following:

Annotation Description Source
 org.springframework.bean.factory.@Autowired  Wires by type  Spring 2.5+
 javax.annotation.@Resource  Wires by name  JavaEE 5+
 javax.inject.@Inject  Wires by type  JavaEE 6+
javax.inject.@Qualifier  Narrows type wiring  JavaEE 6+

Dependency Injection is all about decoupling your classes from one another to make them more testable. Autowiring through annotations strongly couples annotated classes to annotations libraries. Admittedly, this is worse for Spring’s @Autowired than for others as they are generally provided by application servers.

Why it is so bad after all?

Autowiring is all about simplifying dependency injection, and although it may seem seductive at first, it’s not maintainable in real-life projects.

Explicit dependency injection is – guess what, explicitly defining a single bean to match the required dependency. Even better, if Java Configuration is used, it is validated at compile time.

On the opposite, autowiring is about expressing constraints on all available beans in the Spring context so that one and only one matches the required dependency. In effect, you delegate wiring to Spring, tasking him to find the right bean for you. This means that by adding beans in your context, you run the risk of providing more than one match, if your previous constraints do not apply to the new beans. The larger the project, the larger the team (or even worse, the number of teams), the larger the context, the higher the risk.

For example, imagine you crafted a real nice service with a single implementation, that you need to inject somewhere. After a while, someone notices your service but creates an alternative implementation for some reason. By just declaring this new bean in the context, along with the former, it will break container initialization! Worse, it may be done in an entirely different part of the application, with seemingly no link with the former. At this point, good luck to analyze the reason of the bug.

Note that autowiring by name if even worse, since bean names have a probability of collision, even across different type hierarchies.

Autowiring is bad in Spring, but it is even worse in CDI where every class in the classpath is a candidate for injection. By the way, any CDI guru reading this post care to explain why autowiring is the only way of DI? That would be really enlightening.

Summary

In this post, I tried to explain what is autowiring. It can be used all right, but now you should be aware of its con. IMHO, you should only use it for prototyping or quick-and-dirty proof of concepts, everything that can be discarded after a single use. If really needed, prefer wiring by type over wiring by name as at least it matching doesn’t depend on a String.

Send to Kindle
Categories: Java Tags: , ,

Spring method injection with Java Configuration

October 27th, 2013 No comments

Last week, I described how a Rich Model Object could be used with Spring using Spring’s method injection from an architectural point of view.

What is missing, however, is how to use method injection with my new preferred method for configuration, Java Config. My start point is the following, using both autowiring (<shudder>) and method injection.

public abstract class TopCaller {

    @Autowired
    private StuffService stuffService;

    public SomeBean newSomeBean() {

        return newSomeBeanBuilder().with(stuffService).build();
    }

    public abstract SomeBeanBuilder newSomeBeanBuilder();
}

Migrating to Java Config requires the following steps:

  1. Updating the caller structure to allow for constructor injection
  2. For method injection, provide an implementation for the abstract method in the configuration class
  3. That’s all…
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

@Configuration
public class JavaConfig {

    @Bean
    public TopCaller topCaller() {

        return new TopCaller(stuffService()) {

            @Override
            public SomeBeanBuilder newSomeBeanBuilder() {

                return someBeanBuilder();
            }
        };
    }

    @Bean
    public StuffService stuffService() {

        return new StuffService();
    }

    @Bean
    @Scope(BeanDefinition.SCOPE_PROTOTYPE)
    public SomeBeanBuilder someBeanBuilder() {

        return new SomeBeanBuilder();
    }
}
Send to Kindle
Categories: Java Tags: , ,

Rich Domain Objects and Spring Dependency Injection are compatible

October 20th, 2013 3 comments

I’m currently working in a an environment where most developers are Object-Oriented fanatics. Given that we develop in Java, I think that it is a good thing – save the fanatics part. In particular, I’ve run across a deeply-entrenched meme that states that modeling Rich Domain Objects and using Spring dependency injection at the same time is not possible. Not only is this completely false, it reveals a lack of knowledge of Spring features, one I’ll be trying to correct in this article.

However, my main point is not about Spring but about whatever paradigm one holds most dear, be it Object-Oriented Programming, Functional Programming, Aspect-Oriented Programming or whatever. Those are only meant to give desired properties to software: unit-testable, readable, whatever… So one should always focus on those properties than on the way of getting them. Remember:

When the wise man points at the moon, the idiot looks at the finger.

Back to the problem at hand. The basic idea is to have some bean having reference on some service to do some stuff (notice the real-word notions behind this idea…) so you could call:

someBean.doStuff()

The following is exactly what not to do:

public class TopCaller {

    @Autowired
    private StuffService stuffService;

    public SomeBean newSomeBean() {

        return new SomeBeanBuilder().with(stuffService).build();
    }
}

This design should be anathema to developers promoting unit-testing as the new() deeply couples the TopCaller and SomeBeanBuilder classes. There’s no way to stub this dependency in a test, it prevents testing the createSomeBean() method in isolation.

What you need is to inject SomeBean prototypes into the SomeBeanBuilder singleton. This is method injection and is possible within Spring with the help of lookup methods (I’ve already blogged about that some time ago and you should probably have a look at it).

public abstract class TopCaller {

    @Autowired
    private StuffService stuffService;

    public SomeBean newSomeBean() {

        return newSomeBeanBuilder().with(stuffService).build();
    }

    public abstract SomeBeanBuilder newSomeBeanBuilder();
}

With the right configuration, Spring will take care of providing a different SomeBeanBuilder each time the newSomeBeanBuilder() method is called. With this new design, we changed the strong coupling between TopCaller and SomeBeanBuilder to a soft coupling, one that can be stubbed in tests and allow for unit-testing.

In the current design, it seems the only reason for SomeBeanBuilder to exist is to pass the StuffService from the TopCaller to SomeBean instances. There is no need to keep it with method injection.

There are two different possible improvements:

  1. Given our “newfound” knowledge, inject:
    • method newSomeBean() instead of newSomeBeanBuilder() into TopCaller
    • StuffService directly into SomeBean

  2. Keep StuffService as a TopCaller attribute and pass it every time doStuff() is invoked

I would favor the second option since I frown upon a Domain Object keeping references to singleton services, unless there are many parameters to pass at every call. As always, there’s not a single best choice, but only contextual choices.

Also, I would also use explicit dependency management instead of some automagic stuff, but that another debate.

I hope this piece proved beyond any doubt that Spring does not prevent Rich Domain Model, far from it. As a general rule, know about tools you use and go their way instead of following some path just for the sake of it .

Send to Kindle

Spring 3.2 sweetness

June 23rd, 2013 No comments

Even the most extreme Spring opponents have to admit it is all about making developers life easier. Version 3.2 of Spring MVC brings even more sweetness to the table.

Sweetness #1: No web.xml

The ability to run a webapp without any web deployment descriptor comes from Servlet 3.0.

One option would be to annotate your servlet with the @WebServlet annotation to set mapping and complementary data. When you get your servlet for free, like Spring’s DispatcherServlet, you’d need to subclass you servlet for no other purpose than adding annotation(s).

Alternatively, Servlet 3.0 offers a way to both programmatically register servlets in the container and to offer hooks at startup through the ServletContainerInitializer interface. The container will call the onStartup() method of all concrete implementation at webapp startup. The Spring framework leverages this feature to do so for WebApplicationInitializer instances.

Spring MVC 3.2 provides such an implementation – AbstractContextLoaderInitializer, to programmatically register the DispatcherServlet. This means that as soon as the spring-webmvc jar is in the WEB-INF/lib folder of the webapp, you’ve got the Dispatcher servlet up and ready.

This replaces both the servlet and servlet mapping and the context listener declarations in the web.xml.

Sweetness #2: Easy Java configuration integration

Java configuration is the way to configure Spring injection explicitly in a typesafe way. I won’t go into the full demonstration of it, as I already wrote about that some time ago.

Earlier Spring versions provided a way to use Java configuration classes instead of XML files in the web deployment descriptor. Spring 3.2 offers AbstractAnnotationConfigDispatcherServletInitializer, a AbstractContextLoaderInitializer subclass with hooks for Java configuration classes.

Your own concrete subclass has to implement methods to define servlet mappings, as well as root and web Java configuration classes:

public class SugarSpringWebInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {

    @Override
    protected Class<?>[] getRootConfigClasses() {

        return new Class[] { JavaConfig.class };
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {

        return new Class[] { WebConfig.class };
    }

    @Override
    protected String[] getServletMappings() {

        return new String[] { "/" };
    }
}

At this point, you just need to create those configuration classes.

Sweetness #3: integration testing at the mapping level

Your code should be unit-tested, that is tested in isolation to ensure that each method is bug-free, and integration-tested to ensure that collaboration between classes yield expected results.

Before v. 3.2, the Spring test framework let you assemble your configuration classes / files easily enough. The problem lay in the way you would call entry-points – the controllers. You could call methods of those controllers, but not the mappings, leaving those untested.

With v. 3.2, Spring Test brings a whole MVC testing framework which entry-points are mappings. This way, instead of testing method x() of controller C, you would test a request to /z, letting Spring MVC handle it so we can check for expected results.

The framework also provide expectations for view returning, forwarding, redirecting, and model attribute setting, all with the help of a specific DSL:

public class SayHelloControllerIT extends AbstractTestNGSpringContextTests {

    private MockMvc mockMvc;

    @BeforeMethod
    public void setUp() {

        mockMvc = webAppContextSetup((WebApplicationContext) applicationContext).build();
    }

    @Test(dataProvider = "pathParameterAndExpectedModelValue")
    public void accessingSayhelloWithSubpathShouldForwardToSayHelloJspWithModelFilled(String path, String value) throws Exception {

        mockMvc.perform(get("/sayHello/Jo")).andExpect(view().name("sayHello")).andExpect(model().attribute("name", "Jo"));
    }
}

The project for this article can be downloaded in Eclipse/Maven format.

To go further:

  • The entire set of new features is available here
Send to Kindle