Spring 使用注释除去*-portlet.xml。可能的怎么用?

Spring 使用注释除去*-portlet.xml。可能的怎么用?,spring,configuration,portlet,Spring,Configuration,Portlet,文件说: 框架将在DispatcherPortlet初始化时查找 的WEB-INF目录中名为[portlet name]-portlet.xml的文件 您的web应用程序并创建在其中定义的bean(覆盖 在全局域中使用相同名称定义的任何bean的定义 范围) 如果可以的话,我会使用注释进行配置,因为让配置和实际代码保持同步感觉更容易。因此,我的项目中的[portlet name]-portlet.xml如下所示(该文件随时存在……每个portlet一个): 这是很多XML,只是为了一小部分信

文件说:

框架将在DispatcherPortlet初始化时查找 的WEB-INF目录中名为[portlet name]-portlet.xml的文件 您的web应用程序并创建在其中定义的bean(覆盖 在全局域中使用相同名称定义的任何bean的定义 范围)

如果可以的话,我会使用注释进行配置,因为让配置和实际代码保持同步感觉更容易。因此,我的项目中的[portlet name]-portlet.xml如下所示(该文件随时存在……每个portlet一个):


这是很多XML,只是为了一小部分信息:应该使用some.path.to.a.Class来处理对[portlet name]的请求。在some.path.to.a.Class上放置@ForPortlet(“[portlet name]”)注释或类似的东西,并完全忘记这个XML文件会容易得多。有可能吗?可能暗示“否”/“尚未”

解决方案 多亏了奥利斯提供的超级有用的提示(非常感谢!),我想出了一个方法。我在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);
    }

}
公共类MyPortletContext扩展
AbstractRefreshablePortletApplicationContext
{
私有静态最终字符串PORTLET\u PACKAGE=“PACKAGE.where.my.portlets.are。”;
私有静态最终字符串从\u PORTLETNAME=“-portlet”的\u名称空间\u中删除\u;
@凌驾
受保护的无效加载BeanDefinitions(DefaultListableBeanFactory beanFactory)
抛出BeanException、IOException
{
//下一行的作用与指定相同
//在xml文件中:
AnnotationConfigUtils.registerAnnotationConfigProcessors(beanFactory);
//找出portlet名称:
最终字符串portletName=StringUtils.removeEnd(getNamespace(),
从\u名称空间中删除\u(对于\u PORTLETNAME);
//从portlet名称派生控制器:
最终字符串beanClassName=PORTLET\u包+portletName;
//告诉spring关于bean的事情:
最终GenericBeanDefinition beanDefinition=新的GenericBeanDefinition();
beanDefinition.setBeanClassName(beanClassName);
最后一个字符串beanName=BeanDefinitionReaderUtils.generateBeanName(
Bean定义,Bean工厂);
最终BeanDefinitionHolder bdHolder=新BeanDefinitionHolder(
beanDefinition,beanName,新字符串[]{beanClassName});
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder,beanFactory);
}
}
然后我使用init参数在portlet.xml文件中将这个类注册为contextClass,就像OlliS在回答中所描述的那样。就这样。不再需要*-portlet.xml文件。只有一个类配置我的所有portlet


当然,我们仍然可以改进这个类,使它更加灵活,从某处而不是常量读取portlet包。也许是初始化参数。或者可以扫描注释,可能是提到的@ForPortlet注释,这将创建注册多个bean的可能性。但现在我很高兴:-)。

您是否尝试过使用@Configuration注释类进行配置?从3.0版开始,它是spring框架中的一项功能

请参见此处的参考文档:

例如,上下文:可以启用组件扫描:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.scan("com.acme");
基于Java的配置也可以与XML相结合;文件中提到

希望能有帮助

编辑: 因此,您希望用java类替换特定于portlet的上下文。不过,我不确定DispatcherPortlet是否支持java配置。 您可以尝试添加在普通Web应用程序中使用的类似内容:

<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>

门户组件
org.springframework.web.portlet.DispatcherPortlet
上下文类
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
上下文配置位置
com.acme.web.PortletConfig
有关AnnotationConfigWebApplicationContext的一些文档:

从portlet参考文档:

DispatcherPortlet初始化参数 上下文类 类,该类实现WebApplicationContext,将用于实例化 此portlet使用的上下文。如果未指定此参数,则 将使用XmlPortletApplicationContext

WebApplicationContext的实现可以在以下文档中找到:


但似乎没有特定于portlet的WebApplicationContext实现类,至少我没有找到。人们总是可以这样做:)

我仔细阅读了您提供的链接,虽然这听起来是个好主意,但我只能看到它如何替换applicationContext.xml,而不能看到它如何替换[portlet name].xml。我把上面的问题完全改写为a)包括我最近的一些发现,b)让我的问题更清楚。非常有用的提示。我可以根据你的想法得出一个解决方案(见上面我修改过的问题)。谢谢很高兴听到你的工作顺利!=)