Maison > Questions et réponses > le corps du texte
大家好我又来问问题了。。。
事情是这样的。
现在的项目使用了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调用的时候所有的注入都失效了。。。
黄舟2017-04-17 17:41:45
Tout d'abord, merci beaucoup @Kavlez pour votre aide, qui m'a incité à savoir s'il y a un problème de configuration des annotations.
Après avoir vérifié les données et analysé ce problème, bien qu'il ait été résolu, le principe n'est pas clair. J'espère toujours des conseils d'experts. Ce qui suit est le Hessian-servlet.xml modifié
<?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>
Un autre détail est d'écrire ce qui suit sur Service :
@Service("workService")
Il n'est pas permis d'écrire ainsi :
@Service
Mais dans d’autres endroits, les deux sont possibles. C'est aussi un endroit qui n'est pas très connu.
Quant à la modification, la configuration <context:annotation-config />
Étant donné que les beans injectés par diverses méthodes d'annotation après les tests n'étaient pas disponibles, cela signifie qu'il y a un problème avec la méthode d'injection d'annotation.
Après avoir vérifié quelques informations, j'ai vu que quelqu'un avait ajouté cette configuration, alors je l'ai essayé.
Ensuite, j'ai ajouté d'autres configurations selon les invites, et le résultat final est comme ci-dessus.
Ci-dessus.
Merci encore à ceux qui ont aidé.
阿神2017-04-17 17:41:45
Je ne suis pas sûr que ma méthode fonctionne, mais autant l'essayer :
dans WorkServiceImpl est remplacé par @Service("workService")
@Service
<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>
PHP中文网2017-04-17 17:41:45
@Service par défaut, l'identifiant du bean généré est la première lettre du nom de classe par défaut en minuscule, qui est workServiceImpl, mais vous faites référence à workService, vous devez donc écrire @Service("workService") pour spécifier l'identifiant du bean généré