2013-03-23 238 views
1

我从 http://blog.springsource.org/2012/05/16/spring-mvc-3-2-preview-chat-sample/弹簧xml配置基于Java配置

做使用弹簧MVC和redis的服务器通过以下步骤样品的聊天应用程序给定有一个由基于java的弹簧结构的示例。我想用基于xml的配置。但它不适合我。

我通过将以下配置类

package org.springframework.samples.async.config; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.context.annotation.PropertySource; 
import org.springframework.core.env.Environment; 
import org.springframework.data.redis.connection.RedisConnectionFactory; 
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; 
import org.springframework.data.redis.core.StringRedisTemplate; 
import org.springframework.data.redis.listener.PatternTopic; 
import org.springframework.data.redis.listener.RedisMessageListenerContainer; 
import org.springframework.samples.async.chat.ChatController; 

@Configuration 
@PropertySource("classpath:redis.properties") 
public class RootConfig { 

    @Autowired 
    Environment env; 

    @Autowired 
    ChatController chatController; 

    @Bean 
    public RedisConnectionFactory redisConnectionFactory() { 
     JedisConnectionFactory cf = new JedisConnectionFactory(); 
     cf.setHostName(this.env.getProperty("redis.host")); 
     cf.setPort(this.env.getProperty("redis.port", int.class)); 
     cf.setPassword(this.env.getProperty("redis.password")); 
     return cf; 
    } 

    @Bean 
    public StringRedisTemplate redisTemplate() { 
     return new StringRedisTemplate(redisConnectionFactory()); 
    } 

    @Bean 
    public RedisMessageListenerContainer redisMessageListenerContainer() { 
     RedisMessageListenerContainer mlc = new RedisMessageListenerContainer(); 
     mlc.setConnectionFactory(redisConnectionFactory()); 
     mlc.addMessageListener(this.chatController , new PatternTopic("chat")); 
     return mlc; 
    } 

} 

下获得的一个问题是基于XML的配置我想使用的,而不是上述基于Java的配置。

<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
     p:host-name="localhost" p:port="9994" p:password=""/> 
<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter"> 
    <constructor-arg> 
     <bean class="org.springframework.samples.async.chat.ChatController"/> 
    </constructor-arg> 
</bean> 
<bean id="redisMessageListenerContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer"> 
    <property name="connectionFactory" ref="redisConnectionFactory"/> 
    <property name="messageListeners">s   
     <map> 
     <entry key-ref="messageListener"> 
      <bean class="org.springframework.data.redis.listener.PatternTopic"> 
       <constructor-arg value="chat"/> 
      </bean> 
     </entry> 
     </map> 
    </property> 
</bean> 

我收到的例外是

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'messageListener' defined in ServletContext resource [/WEB-INF/spring/mvc-config.xml]: Cannot create inner bean 'org.springframework.samples.async.chat.ChatController#74b70648' of type [org.springframework.samples.async.chat.ChatController] while setting constructor argument; nested exception is org.springframework.beans.factory.CannotLoadBeanClassException: Cannot find class [org.springframework.samples.async.chat.ChatController] for bean with name 'org.springframework.samples.async.chat.ChatController#74b70648' defined in ServletContext resource [/WEB-INF/spring/mvc-config.xml]; nested exception is java.lang.ClassNotFoundException: org.springframework.samples.async.chat.ChatController 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:282) 
    at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:121) 
    at org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:629) 
    at org.springframework.beans.factory.support.ConstructorResolver.autowireConstructor(ConstructorResolver.java:148) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireConstructor(AbstractAutowireCapableBeanFactory.java:1049) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:953) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:490) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:461) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:295) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:223) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:292) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:194) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:626) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:932) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:479) 
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:652) 
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:600) 
    at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:666) 
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:519) 
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:460) 
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) 
    at javax.servlet.GenericServlet.init(GenericServlet.java:160) 
    at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1280) 
    at org.apache.catalina.core.StandardWrapper.loadServlet(StandardWrapper.java:1193) 
    at org.apache.catalina.core.StandardWrapper.allocate(StandardWrapper.java:865) 
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:136) 
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123) 
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472) 
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171) 
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99) 
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:936) 
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118) 
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407) 
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1004) 
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589) 
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886) 
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908) 
    at jav 

a.lang.Thread.run(Thread.java:662)

ChatController.java

package org.springframework.samples.async.chat; 

import java.util.Collections; 
import java.util.List; 
import java.util.Map; 
import java.util.Map.Entry; 
import java.util.concurrent.ConcurrentHashMap; 

import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.data.redis.connection.Message; 
import org.springframework.data.redis.connection.MessageListener; 
import org.springframework.stereotype.Controller; 
import org.springframework.web.bind.annotation.RequestMapping; 
import org.springframework.web.bind.annotation.RequestMethod; 
import org.springframework.web.bind.annotation.RequestParam; 
import org.springframework.web.bind.annotation.ResponseBody; 
import org.springframework.web.context.request.async.DeferredResult; 

@Controller 
@RequestMapping("/mvc/chat") 
public class ChatController implements MessageListener { 

    private final Map<DeferredResult<List<String>>, Integer> chatRequests = 
      new ConcurrentHashMap<DeferredResult<List<String>>, Integer>(); 

    private final ChatRepository chatRepository; 


    @Autowired 
    public ChatController(ChatRepository chatRepository) { 
     this.chatRepository = chatRepository; 
    } 

    @RequestMapping(method=RequestMethod.GET, produces="application/json") 
    @ResponseBody 
    public DeferredResult<List<String>> getMessages(@RequestParam int messageIndex) { 

     final DeferredResult<List<String>> deferredResult = new DeferredResult<List<String>>(null, Collections.emptyList()); 
     this.chatRequests.put(deferredResult, messageIndex); 

     deferredResult.onCompletion(new Runnable() { 
      @Override 
      public void run() { 
       chatRequests.remove(deferredResult); 
      } 
     }); 

     List<String> messages = this.chatRepository.getMessages(messageIndex); 
     if (!messages.isEmpty()) { 
      deferredResult.setResult(messages); 
     } 

     return deferredResult; 
    } 

    @RequestMapping(method=RequestMethod.POST) 
    @ResponseBody 
    public void postMessage(@RequestParam String message) { 
     this.chatRepository.addMessage(message); 
    } 

    // Redis MessageListener contract 

    @Override 
    public void onMessage(Message message, byte[] pattern) { 
     for (Entry<DeferredResult<List<String>>, Integer> entry : this.chatRequests.entrySet()) { 
      List<String> messages = this.chatRepository.getMessages(entry.getValue()); 
      entry.getKey().setResult(messages); 
     } 
    } 

}

完整的MVC-config.xml中

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:context="http://www.springframework.org/schema/context" 
xsi:schemaLocation=" 
http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/context 
http://www.springframework.org/schema/context/spring-context-3.0.xsd 
http://www.springframework.org/schema/mvc 
http://www.springframework.org/schema/mvc/spring-mvc.xsd"> 
<mvc:annotation-driven> 
<mvc:async-support default-timeout="30000" /> 
</mvc:annotation-driven> 
<mvc:view-controller path="/" view-name="chat"/> 
<mvc:resources mapping="/resources/**" location="resources"/> 
<context:component-scan base-package="org.springframework.samples.async.chat" /> 
<bean id="templateResolver" class="org.thymeleaf.templateresolver.ServletContextTemplateResolver"> 
     <property name="prefix" value="/WEB-INF/templates/" /> 
     <property name="suffix" value=".html" /> 
     <property name="templateMode" value="HTML5" /> 
     <property name="cacheable" value="true" /> 
    </bean> 

    <bean id="templateEngine" class="org.thymeleaf.spring3.SpringTemplateEngine"> 
     <property name="templateResolver" ref="templateResolver" /> 
    </bean> 

    <bean id="viewResolver" class="org.thymeleaf.spring3.view.ThymeleafViewResolver"> 
     <property name="templateEngine" ref="templateEngine" /> 
     <property name="order" value="1" /> 
     <property name="viewNames" value="*.html"/> 
    </bean> 

    <bean id="stringRedisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate" 
    p:connection-factory-ref="redisConnectionFactory"/> 

<bean id="redisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" 
     p:host-name="localhost" p:port="9994" p:password=""/> 
<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter"> 
    <constructor-arg> 
     <bean class="org.springframework.samples.async.chat.ChatController"/> 
    </constructor-arg> 
</bean> 
<bean id="redisMessageListenerContainer" class="org.springframework.data.redis.listener.RedisMessageListenerContainer"> 
    <property name="connectionFactory" ref="redisConnectionFactory"/> 
    <property name="messageListeners"> 
     <!-- map of listeners and their associated topics (channels or/and patterns) --> 
     <map> 
     <entry key-ref="messageListener"> 
      <bean class="org.springframework.data.redis.listener.PatternTopic"> 
       <constructor-arg value="chat"/> 
      </bean> 
     </entry> 
     </map> 
    </property> 
</bean> 


</beans> 

请帮助我。

回答

1

我认为这个问题是,你正在试图通过类的东西做一些自动装配在XML与本部分(我假设):

<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter"> 
    <constructor-arg> 
     <bean class="org.springframework.samples.async.chat.ChatController"/> 
    </constructor-arg> 
</bean> 

但是,这并不是多么XML配置工程。 xml在这里做的是试图创建一个ChatController的新实例,并将其用作MessageListenerAdapter的构造函数参数。显然这不起作用,因为您的ChatController没有0参数构造函数。你想要做的是在构造函数参数中引用现有的ChatController(它被标记为@Controller,因此将被component-scan自动拾取)。事情是这样的:

<bean id="messageListener" class="org.springframework.data.redis.listener.adapter.MessageListenerAdapter"> 
    <constructor-arg> 
     <ref bean="chatController"/> 
    </constructor-arg> 
</bean> 

这个bean通过“chatController”被引用为您的组件扫描ChatController(它是默认的bean的名字时,通过典型化注解或@Qualifier注解没有提供)。

+0

感谢您的快速response.Still一些issues.Can请你告诉我下面的代码究竟如何转换成XML @Bean 公共RedisMessageListenerContainer redisMessageListenerContainer(){ \t \t RedisMessageListenerContainer MLC =新RedisMessageListenerContainer(); \t \t mlc.setConnectionFactory(redisConnectionFactory()); \t \t mlc.addMessageListener(this。chatController,新的PatternTopic(“聊天”)); \t \t return mlc; \t} – 2013-03-24 06:29:39

+0

也许你应该编辑你的问题来问这些特定的部分,或者你应该问一个新的问题。否则,任何人都不会看到这一点。 – 2013-03-24 13:52:21

+0

当然我会这样做 – 2013-03-24 17:39:30