Объясните поставщикам, ресурсам и синглтонам RestEasy по отношению к классам и экземплярам?

Я создаю приложение JAX-RS, состоящее из склада и рабочего места. На складе хранится набор классов Java, экземпляры которых можно создавать (через AJAX) для создания именованных экземпляров этих классов на рабочем месте.

До сих пор я могу ссылаться на склад и рабочее место, объявляя их «одиночками» в приложении RestEasy.

    singletons.add(StockPlace.getInstance());
    singletons.add(WorkPlace.getInstance());

Я не могу понять, как понять, как следует обрабатывать классы содержимого складского помещения. Эффект, которого я пытаюсь добиться, заключается в том, что когда я динамически создаю экземпляр одного из классов хранилища, к этому экземпляру можно получить динамический доступ с помощью команд REST. Я пробовал различные перестановки:

    classes.add(SomeComponent.class);

Я думаю, что мне не хватает знаний о том, как понятие Java о том, как классы работают как фабрики для создания экземпляров, и как оба они связаны с тем, что RestEasy называет классами, синглтонами (одиночки ЯВЛЯЮТСЯ классами, но RestEasy регистрирует их как экземпляры) и ресурсы ( экземпляры?).

Я подозреваю, что мне придется динамически регистрировать новые экземпляры, но я не могу найти способ сделать это. Я нашел способ сделать это с учетом ServletContext, но я также не могу получить к нему доступ. Может ли кто-нибудь направить меня на правильный путь?


person Bradjcox    schedule 11.04.2012    source источник


Ответы (3)


В конечном итоге мы решили отказаться от RestEasy и перейти на DropWizard. Эта проблема и многие другие исчезли, и все снова стало легко.

person Bradjcox    schedule 24.12.2012

Кажется, я знаю, чего вы хотите, но я должен, по крайней мере, подтолкнуть вас в правильном направлении.

Вам нужно будет добавить аннотированные классы RESTEasy в реестр. Ниже приведен класс, который я использовал для недавнего проекта. Он добавляется к синглтонам (в зависимости от того, что вы сделали), но также добавляется в реестр.

public class RESTEasyServerApplication extends javax.ws.rs.core.Application
{
    // The RESTEasy registry
    @Autowired
    protected org.jboss.resteasy.spi.Registry registry;

    // The annotated RESTEasy handler classes
    private Set<Object>  singletons = new HashSet<Object>();
    private List<Object> handlers   = new ArrayList<Object>();

    public RESTEasyServerApplication()
    {}

    @Override
    public Set<Object> getSingletons()
    {
        return singletons;
    }

    // Spring injection support
    public void setHandlers( List<Object> handlers )
    {
        for( Object handler : handlers )
        {
            if( registry != null )
            {
                // Save a reference to the handler
                this.handlers.add( handler );

                // Register the handler with RESTEasy
                registry.addSingletonResource( handler );
            }

            singletons.add( handler );
        }
    }

    // Spring injection support
    public List<Object> getHandlers()
    {
        return handlers;
    }
}

Я использовал Spring, и вот соответствующая конфигурация:

<!-- RESTeasy/Spring integration -->
<import resource="classpath:springmvc-resteasy.xml" />

<!-- RESTeasy server application -->
<bean id="application" class="blah.blah.resteasy.RESTEasyServerApplication">
    <property name="handlers">
        <list>
            <!-- Application specific handler classes -->
            <ref bean="sample"/>
        </list>
    </property>
</bean>

Должно быть легко изменить/добавить метод, чтобы принять один аннотированный класс RESTEasy и заставить его работать динамически по мере необходимости. Реестр определяется в файле springmvc-resteasy.xml.

person Eric Thorbjornsen    schedule 12.04.2012
comment
Я не хочу вставлять еще одно неизвестное (Весна) в ситуацию, в которой я уже запутался. И мне не нужно внедрение зависимостей (пока), так как StockPlace уже знает набор классов, которые он содержит. Для этого у него есть Set‹Class›. Также не понимаю, что такое setHandlers() или что он делает. Класс Application имеет только getClasses() и getSingletons(). Вы имеете в виду один из тех? - person Bradjcox; 12.04.2012
comment
Извините, ответ был запутанным, поскольку я пытался включить все, что делал. Я считаю, что все, что вам нужно сделать, это: registry.addSingletonResource( handler ); где обработчик — это ваш аннотированный объект RESTEasy. - person Eric Thorbjornsen; 13.04.2012
comment
Итак, как мне найти реестр, если я не использую Spring. И мои объекты контента — это не синглтоны; они создают много экземпляров по запросу. И самое главное, как указать, что мои экземпляры сохраняются для многих запросов? Мне нужно что-то вроде области приложения, а не области запроса, и я действительно не понимаю, как ее получить. Не привязываясь к еще одной крупной технологии, которую я еще не до конца понимаю. - person Bradjcox; 13.04.2012
comment
Можете ли вы предоставить дополнительную информацию о вашей среде? Вы используете JBoss, Tomcat, что-то еще? Вы явно не используете Spring, вы пишете EJB? Надеюсь, с дополнительной информацией мы сможем определить, откуда вы можете взять реестр. - person Eric Thorbjornsen; 13.04.2012
comment
Томкэт + RestEasy. Нет EJB. Но я думаю, что знаю решение. Я знаю, что Stockroom и Workplace сохраняются между запросами (они синглтоны). RestEasy не сохранит классы в Stockroom, поскольку они не являются синглтонами. Таким образом, решение (не обязательно лучшее) состоит в том, чтобы вообще не регистрировать их в RestEasy и рассматривать их как простые POJO, управляемые/маршрутизируемые исключительно на рабочем месте. т.е. osint/rest/workplace/configure/part1 направляет на рабочее место, которое ищет part1 и вызывает его метод configure как POJO. Можете ли вы предложить лучший способ (который не включает Spring)? - person Bradjcox; 14.04.2012
comment
Эта статья должна ответить на ваш вопрос о среде, в которой вы работаете. класс динамически"> stackoverflow.com/questions/7018041/ - person Eric Thorbjornsen; 14.04.2012
comment
Да, это близко, но никогда не объяснялось, как получить ServletContext, когда вы не в сервлете. Предположительно, мне нужно заменить тот, который предоставляет RestEasy, или что-то в этом роде. - person Bradjcox; 14.04.2012

Поскольку я не нашел ответов, которые не включали бы привязку еще одного уровня сложности (Spring) к RestEasy, решение, которое я нашел приемлемым, изложено в последнем комментарии выше. То есть не полагайтесь на отправку удаленных сообщений экземплярам, ​​если приложение действительно не имеет состояния (например, экземпляры не сохраняются в сообщениях). Отправляйте удаленные сообщения только тем одиночкам, которые сохраняются между запросами. Каждое такое сообщение может идентифицировать нужный экземпляр (по идентификатору String в моем случае), а синглтон может пересылать указанный экземпляр как обычный POJO.

Я до сих пор не понимаю, почему RestEasy безоговорочно рассматривает несинглтоны (экземпляры) как эфемерные. Безгражданство не является ограничением для REST, а только ограничением на то, когда можно использовать методы GET (идемпотентные вызовы). Вызовы PUT и POST не являются ни апатридами, ни идемпотентными.

Как я это понимаю, конечно, и не стесняйтесь меня поправлять. Я сосредоточен на выпуске этого приложения в эфир, а не на изучении каждого уголка RestEasy, REST и, конечно же, Spring.

person Bradjcox    schedule 06.05.2012