Избавьтесь от * -portlet.xml, используя аннотации.Возможный?Как? - PullRequest
3 голосов
/ 13 июля 2011

Документация здесь гласит:

При инициализации DispatcherPortlet платформа будет искать файл с именем [portlet-name] -portlet.xml в WEB-INF каталога вашего веб-приложения и создайте определенные bean-компоненты (переопределяя определения любых bean-компонентов, определенных с тем же именем в глобальной области видимости).

Я выполняю настройку, используя аннотации, если могу,потому что легче поддерживать синхронизацию конфигурации и фактического кода.Итак, этот [portlet-name] -portlet.xml в моем проекте выглядит следующим образом (и этот файл существует раз в год ... Один для каждого портлета):

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:context="http://www.springframework.org/schema/context"
    xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">

    <context:annotation-config />
    <bean class="some.path.to.a.Class" />
</beans>

Это много XML только длямаленький кусочек информации: что some.path.to.a.Class должен использоваться для обработки запросов к [portlet-name].Было бы гораздо проще поместить аннотацию @ForPortlet ("[portlet-name]") или что-то в этом роде в some.path.to.a.Class и полностью забыть об этом XML-файле.Возможно ли что-нибудь подобное? Этот отчет об ошибке может намекнуть на "нет" / "еще нет"?

РЕШЕНИЕ

Благодаря супер полезным советам от OlliS (Большое спасибо!) Яразобрался, как это сделать.Я погрузился в моменты, которые OlliS дал мне в источник Spring, и, потратив много времени, чтобы выяснить, как все работает вместе, я написал следующий класс:

public class MyPortletContext extends
            AbstractRefreshablePortletApplicationContext
    {
        private static final String PORTLET_PACKAGE = "package.where.my.portlets.are.";
        private static final String REMOVE_FROM_NAMESPACE_FOR_PORTLETNAME = "-portlet";

    @Override
    protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
            throws BeansException, IOException
    {
        // The following line does the same thing as specifying
        // <context:annotation-config /> in the xml file:
        AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);

        // Figure out the portlet name:
        final String portletName = StringUtils.removeEnd(getNamespace(),
                REMOVE_FROM_NAMESPACE_FOR_PORTLETNAME);
        // Derive the controller from the portlet name:
        final String beanClassName = PORTLET_PACKAGE + portletName;

        // Tell spring about the bean:
        final GenericBeanDefinition beanDefinition = new GenericBeanDefinition();
        beanDefinition.setBeanClassName(beanClassName);

        final String beanName = BeanDefinitionReaderUtils.generateBeanName(
                beanDefinition, beanFactory);

        final BeanDefinitionHolder bdHolder = new BeanDefinitionHolder(
                beanDefinition, beanName, new String[] { beanClassName });

        BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, beanFactory);
    }

}

Затем я зарегистрировал этот класс как contextClass в портлете.XML-файл, использующий init-param, точно так же, как в своем ответе фигурировал OlliS.И это все.Файл * -portlet.xml больше не требуется.Всего один класс, настраивающий все мои портлеты.

Конечно, можно еще улучшить этот класс, сделав его более гибким, считывая пакет портлета откуда-то вместо константы.Может быть, init-param.Или можно искать аннотации, возможно, упомянутую аннотацию @ForPortlet, которая создаст возможность зарегистрировать более одного компонента.Но пока я счастлив: -).

1 Ответ

3 голосов
/ 14 июля 2011

Вы пытались использовать аннотированные классы @Configuration для настройки? Это особенность в весенних рамках начиная с версии 3.0

См. Справочную документацию здесь:

http://static.springsource.org/spring/docs/3.0.x/reference/beans.html#beans-java

Например, контекст: компонент-scan может быть расширен:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.acme");

Конфигурация на основе Java также может сочетаться с XML; упоминается в документации.

Надеюсь, это поможет.

EDIT: Таким образом, вы захотите заменить определенный контекст портлета на класс Java. Я не уверен, что DispatcherPortlet поддерживает настройку Java, хотя. Вы можете попробовать добавить что-то вроде этого, которое используется в обычных веб-приложениях:

<portlet>
    <portlet-name>portlet</portlet-name>
    <portlet-class>org.springframework.web.portlet.DispatcherPortlet</portlet-class>
<init-param>
 <!-- Configure DispatcherPortlet to use AnnotationConfigWebApplicationContext
       instead of the default XmlPortletApplicationContext ? -->
      <param-name>contextClass</param-name>
      <param-value>
          org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
</init-param>
<init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.acme.web.PortletConfig</param-value>
  </init-param>
<!-- ... -->
</portlet>

Некоторая документация по AnnotationConfigWebApplicationContext: http://static.springsource.org/spring/docs/3.0.x/javadoc-api/org/springframework/web/context/support/AnnotationConfigWebApplicationContext.html

Из справочных документов портлета:

Параметры инициализации DispatcherPortlet

contextClass

Класс, который реализует WebApplicationContext, который будет использоваться для создания экземпляра контекст, используемый этим портлетом. Если этот параметр не указан, Будет использован XmlPortletApplicationContext.

Реализации WebApplicationContext можно найти в документации:

http://static.springsource.org/spring/docs/current/api/org/springframework/web/context/WebApplicationContext.html

Не похоже, что существует класс реализации WebApplicationContext для портлета, по крайней мере, я его не нашел. Всегда можно сделать один :)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...