Как стать автором
Обновить

@Inject на серверной части GWT

Методов реализации injection на серверной стороне GWT на самом деле много. Я решил освятить один из них, который недавно использовал для своего проекта. Далее речь пойдет о Guice и GWT.

И так, нам понадобится Guice подключенный как servlet (ServletModule ) для того, что бы загрузить наш модуль, и что-то за-inject-ить. Так как мне нужно было использовать Mongodb, то подключать я буду MongoConnection. Конечно же тут может быть что угодно, в том числе Hibernate, JDBС или любые другие сервисы, которые вам нужны.

final public class GuiceMongo extends ServletModule {

    @Override
    protected void configureServlets() {
        if (currentStage() == Stage.DEVELOPMENT) {
            bind(MongoConfiguration.class).to(MongoConfiguration.QaMongoConfiguraiton.class);
        }

        bind(MongoConnection.class).in(Singleton.class);

        bind(ExceptionHandler.class).to(DefaultExceptionHandler.class);
        bind(ServiceLayerDecorator.class).to(InjectedServiceLayerDecorator.class);


        serve("/gwtRequest").with(InjectedRequestFactoryServlet.class);
    }
}


Так как я собираюсь использовать подключение к базе данных в своих DAO, то сервлет нужно биндить и подгружать из конфигурации <сode>ServletModule.

Теперь опишем RequestFactoryServlet, который будет наследовать функциональность обычной RequestFactoryServlet

@Singleton
final class InjectedRequestFactoryServlet extends RequestFactoryServlet  {

    InjectedRequestFactoryServlet() {

    }

    @Inject
    InjectedRequestFactoryServlet(ExceptionHandler exceptionHandler, ServiceLayerDecorator serviceDecorator) {
        super(exceptionHandler, serviceDecorator);
    }
}


Важно то, что все сервлеты должны быть Singleton.

Тут по моему и так все понятно и описывать особо нечего. Это нужно только для того, что бы пробросить Inection далее в DAO.

Опишем еще один класс, который мы инджектим в фабрику запросов:

final class InjectedServiceLayerDecorator extends ServiceLayerDecorator {

    private final Injector injector;

    @Inject
    public InjectedServiceLayerDecorator(final Injector injector) {
        this.injector = injector;
    }

    @Override
    public <T extends Locator<?, ?>> T createLocator(Class<T> clazz) {
        return injector.getInstance(clazz);
    }

    @Override
    public Object createServiceInstance(Class<? extends RequestContext> requestContext) {
        Class<? extends ServiceLocator> serviceLocatorClass;
        if ((serviceLocatorClass = getTop().resolveServiceLocator(requestContext)) != null) {
            final Class<?> daoClazzDeclaration = requestContext.getAnnotation(Service.class).value();
            return injector.getInstance(serviceLocatorClass).getInstance(daoClazzDeclaration);
        } else {
            return null;
        }
    }
}


Вся магия происходит вот этой строке:
injector.getInstance(serviceLocatorClass).getInstance(daoClazzDeclaration);


Тут DAO создается не через как обычный инстанс класса, а используя Guice Injector. Следовательно: все dependency injection в DAO будут корректно отрабатывать.

Так же нам еще понадобится ServiceLocator. Выглядеть он будет так:
public class MongoServiceLocator implements ServiceLocator {
    private final Injector injector;

    @Inject
    protected MongoServiceLocator(final Injector injector) {
        super();
        this.injector = injector;
    }

    @Override
    public Object getInstance(Class<?> aClass) {
        return injector.getInstance(aClass);
    }
}


Ну а далее можете создавать DAO классы используя уже MongoConnection. Например так:

abstract class AbstractMongoDao implements MongoDao {
    private MongoOperations mongoOperations;

    @Inject
    private MongoConnection mongoConnection;

    AbstractMongoDao() {

    }

    protected MongoOperations getMongoOperations() {
        if (mongoOperations == null) {
            mongoOperations = new MongoTemplate(mongoConnection.getMongoDbFactory());
        }

        return mongoOperations;
    }
}


Эта схема позволяет легко управлять DAO через привычный Dependency Injection, в том числе можно использовать и Spring Beans, и возможно EJB дергать (но я не пробовал).
Статься была написана на основе этого кода.
Теги:
Хабы:
Данная статья не подлежит комментированию, поскольку её автор ещё не является полноправным участником сообщества. Вы сможете связаться с автором только после того, как он получит приглашение от кого-либо из участников сообщества. До этого момента его username будет скрыт псевдонимом.