Unstable Terrain

Software development in the real world

Converting Strings to Class files in Spring

with 2 comments

Today I integrated Spiros Tzavellas‘ neat implementation of the circuit breaker pattern into an app at work. I looked at other implementations but Spiros’ code is the cleanest (and actually threadsafe – a definite plus).

One neat thing about the CircuitBreaker class is that it can ignore certain exception classes. However, the code is written as

public void setIgnoredExceptions(Set<Class<? extends Throwable>> ignored) {
    if (ignored != null) {
        ignoredExceptions.clear();
        ignoredExceptions.addAll(ignored);
    }
}

Which is fine, except that Spring has some difficulty providing a Set of Class objects. How do you convert it?

PropertyEditor to the rescue

Turns out that hooks to do this conversion already exist. All we have to do is create the property editor, register that editor with Spring, and from then on, Spring will convert Strings to Class objects whenever it has to wire things up.

For reference, the code to do this is:

import java.beans.PropertyEditorSupport;

import org.springframework.beans.BeansException;
import org.springframework.beans.PropertyEditorRegistrar;
import org.springframework.beans.PropertyEditorRegistry;
import org.springframework.beans.factory.config.BeanFactoryPostProcessor;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.stereotype.Component;

/**
 * A {@link BeanFactoryPostProcessor} that registers a property editor for {@link Class} objects.
 */
@Component
public class ClassProcessor implements BeanFactoryPostProcessor {

    private static final PropertyEditorRegistrar REGISTRAR = new PropertyEditorRegistrar() {

        public void registerCustomEditors(PropertyEditorRegistry registry) {
            registry.registerCustomEditor(Class.class, new Editor());
        }
    };

    public void postProcessBeanFactory(ConfigurableListableBeanFactory bf) throws BeansException {
        bf.addPropertyEditorRegistrar(REGISTRAR);
    }

    /** A {@code PropertyEditor} for {@code Class} objects. */
    public static class Editor extends PropertyEditorSupport {

        /** {@inheritDoc} */
        @Override
        public String getAsText() {
            return getValue().getClass().toString();
        }

        /** {@inheritDoc} */
        @Override
        public void setAsText(String text) throws IllegalArgumentException {
            try {
                setValue(Class.forName(text));
            } catch (ClassNotFoundException e) {
                throw new IllegalArgumentException("Cannot set <" + text + ">", e);
            }
        }
    }
}

Update

Turns out Spiros has already blogged about this before, except for java.util.Date instead. Oh well, only three years late…

Update 2

See how to do it properly.

Advertisements

Written by Trent

December 24, 2009 at 5:14 pm

2 Responses

Subscribe to comments with RSS.

  1. Hi Trent,

    I am really glad to read that you found my project useful. I will integrate your requested features in the next few days.

    Spiros Tzavellas

    December 24, 2009 at 8:45 pm


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: