Search code examples
javadependency-injectionguice

Can I use already bound instances in Guice's Module.configure()?


I'd like to bind a MethodInterceptor in my module's configure() method, like this:

public class DataModule implements Module {

    @Override
    public void configure(Binder binder) {
        MethodInterceptor transactionInterceptor = ...;
        binder.bindInterceptor(Matchers.any(), Matchers.annotatedWith(Transactional.class), null);
    }

    @Provides
    public DataSource dataSource() {
        JdbcDataSource dataSource = new JdbcDataSource();
        dataSource.setURL("jdbc:h2:test");
        return dataSource;
    }

    @Provides
    public PlatformTransactionManager transactionManager(DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Provides
    public TransactionInterceptor transactionInterceptor(PlatformTransactionManager transactionManager) {
        return new TransactionInterceptor(transactionManager, new AnnotationTransactionAttributeSource());
    }
}

Is there a way to get the transactionInterceptor with the help of Guice, or do I need to create all objects required for my interceptor manually?


Solution

  • This is covered in the Guice FAQ. From that document:

    In order to inject dependencies in an AOP MethodInterceptor, use requestInjection() alongside the standard bindInterceptor() call.

    public class NotOnWeekendsModule extends AbstractModule {
      protected void configure() {
        MethodInterceptor interceptor = new WeekendBlocker();
        requestInjection(interceptor);
        bindInterceptor(any(), annotatedWith(NotOnWeekends.class), interceptor);
      }
    }
    

    Another option is to use Binder.getProvider and pass the dependency in the constructor of the interceptor.

    public class NotOnWeekendsModule extends AbstractModule {
      protected void configure() {
        bindInterceptor(any(),
                    annotatedWith(NotOnWeekends.class),
                    new WeekendBlocker(getProvider(Calendar.class)));
      }
    }