2013-03-23 320 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