Tag Archives: spring

JSR-330: Framework-Agnostic Dependency Injection

In your project, you may have worked with Spring or you may have worked with Dagger. There are other popular dependency injection (DI) frameworks out there, and you select one for your project (I don’t think it’s encouraged to mix-and-match in the same project).

But if you’re writing a library for other projects to use, which DI framework should you standardize on? If you establish Spring as your DI framework, you discourage Dagger DI users, and vice-versa.

This is JSR-330 comes in.

JSR-330 is basically a small set of annotations to standardize DI. It does not implement DI; you’ll still need a DI framework to that. But it defines what classes are injectable/providable/bean-ifiable and where. This allows other users of your library to bring their own DI implementations with your project.

Here are the set of annotations that JSR-330 provides

JSR-330SpringDagger
@Inject@Autowired
@Named@Component@Component
@Qualifier@Qualifier
@Scope@Scope
@Singleton@Scope(“singleton”)@Singleton
@Scope(“prototype”)

As a small example, here’s a typical Spring DI setup

@org.springframework.stereotype.Component
public class Foo {
}

public class Bar {
@Autowire
public Bar(Foo foo) {
}
}

This is the same using JSR-330

@javax.inject.Named
public class Foo {
}

public class Bar {
@Inject
public Bar(Foo far) {
}
}

Note that the JSR-330 example will work in a Spring and Dagger project. However, the Spring example will only work in a Spring project.

There will be components that you will not be able to automatically inject. This may be a third-party class that you cannot just add a DI annotation to or some class that needs to be initialized in some custom way. For these, you’ll need to provide them via methods and unfortunately, you’ll need to rely on specific DI frameworks to do that.

Your library could then provide a package that helps others automatically provide those components.

For example, if Bar also needed a third-party DatabaseHandler, then you could provide a Spring configuration like this

@Configuration
public class DatabaseModule {
@Bean
public DatabaseHandler databaseHandler() {
return …
}
}

You may also provide a Dagger-friendly module for them to depend on as well

@Module
public class DatabaseModule {
@Provides
@Singleton
static DatabaseHandler provideDatabaseHandler() {
return …
}
}

Tagged , , ,

Overriding GraphQL Java Kickstart

The GraphQL Java Kickstart library is a quick and easy way to get started with GraphQL. But it hides a lot of implementation details behind Spring beans making it not that intuitive to override with your custom needs. I don’t think it’s very well documented so here’s some info

The library contains a bunch of Auto Configurations, basically beans automatically injected to give you off-the-shelf functionality. Here’s a list of them.

We are using Spring Webflux so as an example, some of our Auto Configurations are in GraphQLSpringWebfluxAutoConfiguration. Notice it provides a GraphQLObjectMapper but also has the @ConditionalOnMissingBean annotation. So we could replace it with our own GraphQLObjectMapper.

Tagged ,

Use a Supplier to provide stateful beans

Sometimes you have a bean that holds state, so you’d like a different instance of it upon each request. That seems easy, you say. Just call the instantiation method every time like so

public StatefulBean getStatefulBean() {
  return new StatefulBean();
}

That wasn’t so bad, right? But what if the thing that calls it is a singleton? In Spring, for example, @Component‘s like @RestController are singletons by default. So let’s consider this example

@RestController
public class MyController {
    @Autowired StatefulBean aStateFulBean;
}

@Configuration
public class BeanModule {

  @Bean
  @Scope(scopeName = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
  public StatefulBean getStatefulBean() {
    return new StatefulBean();
  } 
}

Notice I changed the default scope of the StatefulBean to PROTOTYPE which means don’t cache this bean and call it every time. Unfortunately, the @RestController that needs the bean is a singleton so it will only call it once and keep using the same bean.

You can, of course, change the @RestController’s scope as well, but that’s ill-advised (google it). It also doesn’t prevent something else that’s a singleton from calling that bean. It’s just a generally unsafe pattern, and someone who doesn’t understand bean scope or that your bean needs to be stateful, will do something bad and the bug will be very, very subtle and indeterministic.

So what you can do instead is only provide a Supplier to your bean like so

@RestController
public class MyController {
  @Autowired Supplier<StatefulBean> aStateFulBeanSupplier;

  ... StatefulBean aStatefulBean = aStateFulBeanSupplier.get();
}

@Configuration
public class BeanModule {

  @Bean
  public Supplier<StatefulBean> getStatefulBean() {
    return () -> new StatefulBean();
  } 
}

The () -> new StatefulBean() is just short-hand for creating an anonymous class. We could also have written out the boiler plate

@Bean
public Supplier<StatefulBean> getStatefulBean() {
  return new Supplier<StatefulBean>() {
    @Override
    public StatefulBean get() {
      return new StatefulBean();
    }
  };
}

Notice that we dropped the Scope because it’s fine for the @RestController to hold a singleton reference to it. It’s just a singleton class that “supplies” a new instance of a StatefulBean whenever it needs one.

This pattern prevents you or anyone else from accidentally using the same `StatefulBean`. Future indeterministic bug avoided.

Tagged , , ,