java - SpringMVC线程池问题
高洛峰
高洛峰 2017-04-17 17:39:45
0
3
472

大家好我又来问问题了。。。

事情是这样的。

现在的项目使用了Hessian。

在Commander 项目中调用 Spider 项目中的一个service

这个Service中使用了线程池。

然而问题来了。当在Spider项目中自己调用自己的Service的时候,一切正常。

但是通过Hessian调用Spider的Service的时候,线程池却是空指针的。

代码如下:
这是Spider(被调用)项目中的配置:

<?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:aop="http://www.springframework.org/schema/aop"  
    xmlns:tx="http://www.springframework.org/schema/tx"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd  
           http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd  
           http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"  
    default-autowire="byName">    

<bean id="impl" class="com.whr.Service.Impl.WorkServiceImpl" />      
<!-- 远程服务 -->  
<bean name="/workService" class="org.springframework.remoting.caucho.HessianServiceExporter">  
     
    <property name="service" ref="impl" />  
    <property name="serviceInterface">  
        <value>
            com.whr.Service.WorkService
        </value>  
    </property>
</bean> 
</beans>

这是Spider(被调用)项目中的Service 实现:

package com.whr.Service.Impl;

import java.sql.Date;
import java.util.List;

import javax.annotation.Resource;

import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.task.TaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.whr.Dao.WorkDao;
import com.whr.Entity.Work;
import com.whr.Service.WorkService;
import com.whr.Spiders.Spider_ZhiLian;

@Service("workService")
public class WorkServiceImpl implements WorkService {

    @Autowired
    private WorkDao workDao;
    @Resource(name = "taskExecutor_Spider") 
    private TaskExecutor taskExecutor;// 线程池
    
    @Autowired
    private Spider_ZhiLian spider_ZhiLian;
    
    public List<Work> getAllWork() {
        return workDao.getAllWork();
        
    }

    
    public void saveWork()
    {
        System.out.println("Commander 调用  Spider");
        TaskExecutor teExecutor = this.taskExecutor;
        teExecutor.execute(new Spider_ZhiLian(workDao));
    }


    public void updateWork(Work work) 
    {
        workDao.updateWork(work);
    }


    public void deleteWork(Work work) 
    {
        workDao.deleteWork(work);
    }
}

结果:

Commander 调用  Spider
2016-04-13 10:15:49 [org.springframework.remoting.support.RemoteInvocationTraceInterceptor]-[WARN] Processing of HessianServiceExporter remote call resulted in fatal exception: com.whr.Service.WorkService.saveWork
java.lang.NullPointerException
    at com.whr.Service.Impl.WorkServiceImpl.saveWork(WorkServiceImpl.java:42)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:302)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157)
    at org.springframework.remoting.support.RemoteInvocationTraceInterceptor.invoke(RemoteInvocationTraceInterceptor.java:78)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:207)
    at $Proxy38.saveWork(Unknown Source)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:306)
    at com.caucho.hessian.server.HessianSkeleton.invoke(HessianSkeleton.java:221)
    at org.springframework.remoting.caucho.HessianExporter.doInvoke(HessianExporter.java:223)
    at org.springframework.remoting.caucho.HessianExporter.invoke(HessianExporter.java:138)
    at org.springframework.remoting.caucho.HessianServiceExporter.handleRequest(HessianServiceExporter.java:66)
    at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:51)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:959)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:893)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
    at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:647)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:728)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.springframework.orm.hibernate4.support.OpenSessionInViewFilter.doFilterInternal(OpenSessionInViewFilter.java:151)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    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:953)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:1852)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:619)

Commander调用的过程(部分):

public class UserController {

    @Autowired
    private UserService userService;
    @Autowired
    private WorkService workService;
    @Autowired
    private HessianService testHessianService;
    
    private static Logger logger = Logger.getLogger(UserController.class);
    
    @RequestMapping("/test")
    public ModelAndView getStudent(HttpServletRequest request,HttpServletResponse response,ModelMap modelMap) throws MalformedURLException
    {
        
        /*HessianModel model = testHessianService.getHessianModel("uid", "pwd");   
        logger.info("username: " + model.getUsername());*/
        testHessianService.saveWork();
        
        
        List<User> list = userService.getAllUser();
        modelMap.put("students", list);
        logger.info("Log4测试");
        return new ModelAndView("test", modelMap); 
    }

调用方的Spring配置:

<bean id="testHessianService" class="org.springframework.remoting.caucho.HessianProxyFactoryBean">  
        <property name="serviceUrl" value="http://localhost:8080/Spider/hessian/workService"/>  
        <property name="serviceInterface" value="com.whr.Hessian.HessianService"/>  
    </bean>

调用方的Hessian接口:

package com.whr.Hessian;

public interface HessianService {
    public String sayHello(String username);  
    public void saveWork();
    public HessianModel getHessianModel(String username, String password);
}

以上。

问题简述就是一个在本项目中可以调用的Service经过Hessian调用后线程池缺空指针了。但是明确可以调用到的。

求大神解答。谢谢!

刚才尝试了一下不使用线程池,通过Hessian调用服务然后在服务中直接操作Dao层,也是不好使的,一样的空指针。
但是在服务端自己调用服务端的Service却好使。
貌似Hessian调用的时候所有的注入都失效了。。。

高洛峰
高洛峰

拥有18年软件开发和IT教学经验。曾任多家上市公司技术总监、架构师、项目经理、高级软件工程师等职务。 网络人气名人讲师,...

reply all(3)
黄舟

First of all, thank you very much @Kavlez for your help, prompting me to find out whether the annotation configuration is a problem.

I checked the information and analyzed this problem. Although it was solved, the principle is not clear. Still hoping for expert guidance. The following is the modified Hessian-servlet.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:jee="http://www.springframework.org/schema/jee"  
    xmlns:tx="http://www.springframework.org/schema/tx"   
    xmlns:context="http://www.springframework.org/schema/context"  
    xmlns:aop="http://www.springframework.org/schema/aop"  
    xmlns:p="http://www.springframework.org/schema/p"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans  
     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd  
     http://www.springframework.org/schema/tx  
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd  
     http://www.springframework.org/schema/jee  
     http://www.springframework.org/schema/jee/spring-jee-3.0.xsd  
     http://www.springframework.org/schema/aop  
     http://www.springframework.org/schema/aop/spring-aop-3.0.xsd  
     http://www.springframework.org/schema/context  
     http://www.springframework.org/schema/context/spring-context-3.0.xsd  
     http://activemq.apache.org/schema/core  
     http://activemq.apache.org/schema/core/activemq-core.xsd"  
    >   
      
    <context:annotation-config />  
    <!-- 组件扫描,使用annotation 自动注册bean,并检查@Required,@Autowired的属性已被注入 -->  
    <context:component-scan base-package="com.whr" />  
      
      <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" />  
      
    <!-- 异步线程池 -->
    <bean id="taskExecutor_Spider"
        class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
        <!-- 核心线程数 -->
        <property name="corePoolSize" value="10" />
        <!-- 最大线程数 -->
        <property name="maxPoolSize" value="100" />
        <!-- 队列最大长度 >=mainExecutor.maxSize -->
        <property name="queueCapacity" value="1000" />
        <!-- 线程池维护线程所允许的空闲时间 -->
        <property name="keepAliveSeconds" value="300" />
        <!-- 线程池对拒绝任务(无线程可用)的处理策略 -->
        <property name="rejectedExecutionHandler">
            <bean class="java.util.concurrent.ThreadPoolExecutor$CallerRunsPolicy" />
        </property>
    </bean>
      
    <bean name="/workService"    
        class="org.springframework.remoting.caucho.HessianServiceExporter">    
        <!-- service的ref与HelloServiceImpl中@Service中配置的一致 -->    
        <property name="service" ref="workService" />    
        <!-- 接口的路径 -->    
        <property name="serviceInterface"    
            value="com.whr.Service.WorkService" />    
    </bean>    
</beans>

Another detail is that the Service should be written as follows:

@Service("workService")

cannot be written like this:

@Service

But in other places, both are possible. This is also a place that is not very understood.

As for the modification, the <context:annotation-config /> configuration has been added.
Since the beans injected by various annotation methods after testing were not available, it means that there is a problem with the annotation injection method.

I checked some information and saw that someone has added this configuration, so I tried it.
Then I added other configurations according to the prompts, and the final result is as above.

and above.
Thank you again to those who helped.

阿神

I’m not sure if my method works, but you might as well give it a try:


@Service("workService")改为@Service in

WorkServiceImpl

The server configuration is changed to:

<bean name="/workService" class="org.springframework.remoting.caucho.HessianServiceExporter">  
     
    <property name="service" ref="workServiceImpl" />  
    <property name="serviceInterface">  
        <value>
            com.whr.Service.WorkService
        </value>  
    </property>
</bean>     
Ty80

@Service defaults to the id of the generated bean being the first letter of the default class name in lowercase, which is workServiceImpl, but you are referring to workService, so you must write @Service("workService") to specify the id of the generated bean

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template