Archive

Posts Tagged ‘spring’

Metrics, metrics everywhere

November 16th, 2014 No comments

With DevOps, metrics are starting to be among the non-functional requirements any application has to bring into scope. Before going further, there are several comments I’d like to make:

  1. Metrics are not only about non-functional stuff. Many metrics represent very important KPI for the business. For example, for an e-commerce shop, the business needs to know how many customers leave the checkout process, and in which screen. True, there are several solutions to achieve this, though they are all web-based (Google Analytics comes to mind) and metrics might also be required for different architectures. And having all metrics in the same backend mean they can be correlated easily.
  2. Metrics, as any other NFR (e.g. logging and exception handling) should be designed and managed upfront and not pushed in as an afterthought. How do I know that? Well, one of my last project focused on functional requirement only, and only in the end did project management realized NFR were important. Trust me when I say it was gory – and it has cost much more than if designed in the early phases of the project.
  3. Metrics have an overhead. However, without metrics, it’s not possible to increase performance. Just accept that and live with it.

The inputs are the following: the application is Spring MVC-based and metrics have to be aggregated in Graphite. We will start by using the excellent Metrics project: not only does it get the job done, its documentation is of very high quality and it’s available under the friendly OpenSource Apache v2.0 license.

That said, let’s imagine a “standard” base architecture to manage those components.

First, though Metrics offer a Graphite endpoint, this requires configuration in each environment and this makes it harder, especially on developers workstations. To manage this, we’ll send metrics to JMX and introduce jmxtrans as a middle component between JMX and graphite. As every JVM provides JMX services, this requires no configuration when there’s none needed – and has no impact on performance.

Second, as developers, we usually enjoy develop everything from scratch in order to show off how good we are – or sometimes because they didn’t browse the documentation. My point of view as a software engineer is that I’d rather not reinvent the wheel and focus on the task at end. Actually, Spring Boot already integrates with Metrics through the Actuator component. However, it only provides GaugeService – to send unique values, and CounterService – to increment/decrement values. This might be good enough for FR but not for NFR so we might want to tweak things a little.

The flow would be designed like this: Code > Spring Boot > Metrics > JMX > Graphite

The starting point is to create an aspect, as performance metric is a cross-cutting concern:

@Aspect
public class MetricAspect {

    private final MetricSender metricSender;

    @Autowired
    public MetricAspect(MetricSender metricSender) {
        this.metricSender = metricSender;
    }

    @Around("execution(* ch.frankel.blog.metrics.ping..*(..)) ||execution(* ch.frankel.blog.metrics.dice..*(..))")
    public Object doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable {
        StopWatch stopWatch = metricSender.getStartedStopWatch();
        try {
            return pjp.proceed();
        } finally {
            Class<?> clazz = pjp.getTarget().getClass();
            String methodName = pjp.getSignature().getName();
            metricSender.stopAndSend(stopWatch, clazz, methodName);
        }
    }
}

The only thing outside of the ordinary is the usage of autowiring as aspects don’t seem to be able to be the target of explicit wiring (yet?). Also notice the aspect itself doesn’t interact with the Metrics API, it only delegates to a dedicated component:

public class MetricSender {

    private final MetricRegistry registry;

    public MetricSender(MetricRegistry registry) {
        this.registry = registry;
    }

    private Histogram getOrAdd(String metricsName) {
        Map<String, Histogram> registeredHistograms = registry.getHistograms();
        Histogram registeredHistogram = registeredHistograms.get(metricsName);
        if (registeredHistogram == null) {
            Reservoir reservoir = new ExponentiallyDecayingReservoir();
            registeredHistogram = new Histogram(reservoir);
            registry.register(metricsName, registeredHistogram);
        }
        return registeredHistogram;
    }

    public StopWatch getStartedStopWatch() {
        StopWatch stopWatch = new StopWatch();
        stopWatch.start();
        return stopWatch;
    }

    private String computeMetricName(Class<?> clazz, String methodName) {
        return clazz.getName() + '.' + methodName;
    }

    public void stopAndSend(StopWatch stopWatch, Class<?> clazz, String methodName) {
        stopWatch.stop();
        String metricName = computeMetricName(clazz, methodName);
        getOrAdd(metricName).update(stopWatch.getTotalTimeMillis());
    }
}

The sender does several interesting things (but with no state):

  • It returns a new StopWatch for the aspect to pass back after method execution
  • It computes the metric name depending on the class and the method
  • It stops the StopWatch and sends the time to the MetricRegistry
  • Note it also lazily creates and registers a new Histogram with an ExponentiallyDecayingReservoir instance. The default behavior is to provide an UniformReservoir, which keeps data forever and is not suitable for our need.

The final step is to tell the Metrics API to send data to JMX. This can be done in one of the configuration classes, preferably the one dedicated to metrics, using the @PostConstruct annotation on the desired method.

@Configuration
public class MetricsConfiguration {

    @Autowired
    private MetricRegistry metricRegistry;

    @Bean
    public MetricSender metricSender() {
        return new MetricSender(metricRegistry);
    }

    @PostConstruct
    public void connectRegistryToJmx() {
        JmxReporter reporter = JmxReporter.forRegistry(metricRegistry).build();
        reporter.start();
    }
}

The JConsole should look like the following. Icing on the cake, all default Spring Boot metrics are also available:

Sources for this article are available in Maven “format”.

To go further:

Send to Kindle

Using exceptions when designing an API

August 31st, 2014 2 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 10 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