Java SpringMVC、空SpringBeans、servlet和Apache Thrift
我有一个web应用程序,它有一个Java SpringMVC、空SpringBeans、servlet和Apache Thrift,java,spring,servlets,thrift,Java,Spring,Servlets,Thrift,我有一个web应用程序,它有一个UserService,允许进行与用户相关的操作 我可以在我的@Controller类中自动连接UserServicebean,它工作正常 如果我添加第二个类型为ThriftServlet的servlet,如下所示: //register the thrift API servlet ServletRegistration.Dynamic thrift = servletContext.addServlet("thriftapi", new ThriftServl
UserService
,允许进行与用户相关的操作
我可以在我的@Controller
类中自动连接UserService
bean,它工作正常
如果我添加第二个类型为ThriftServlet
的servlet,如下所示:
//register the thrift API servlet
ServletRegistration.Dynamic thrift = servletContext.addServlet("thriftapi", new ThriftServlet());
thrift.setLoadOnStartup(2);
thrift.addMapping("/api/*");
ThriftServlet
如下所示:
public class ThriftServlet extends TServlet {
// constructor
public ThriftServlet() {
super(new MyService.Processor<ThriftApiHandler>(
new ThriftApiHandler()), new TBinaryProtocol.Factory());
}
}
@Component
public class ThriftApiHandler implements MyService.Iface {
@Autowired
UserService userService;
@Override
public String myServiceMethod(String someParam) throws SomeException, TException {
// userService is null when this is called by a client application
}
}
我可以在调试日志中看到,自动连接确实发生了(时间戳和类被截断):
-创建singleton bean“thriftApiHandler”的共享实例
-正在创建bean“thriftApiHandler”的实例
-类[my.package.api.ThriftApiHandler]上注册的注入元素:my.package.service.UserService的AutoWiredFeldElement my.package.api.ThriftApiHandler.UserService
-急切地缓存bean“thriftApiHandler”,以允许解析潜在的循环引用
-bean“thriftApiHandler”的处理注入方法:my.package.service.UserService的AutoWiredFeldElement my.package.api.thriftApiHandler.UserService
但是userService
(以及我尝试注入的任何其他bean)在任何thrift api方法中都始终为空
也许这与TServlet
类如何从HttpServlet
继承而不“知道”spring上下文有关
我觉得我缺少了一些与servlet上下文和共享bean等相关的东西,但我对SpringMVC还是相当陌生的。如果发布更多代码可以让这个问题更容易回答,请告诉我。如果Spring无法解析@Autowired
目标,它将始终失败(抛出异常)。如果您得到null
,那么Spring实际上并没有管理您的对象,因此无法注入任何内容。这里就是这样
public ThriftServlet() {
super(new MyService.Processor<ThriftApiHandler>(
new ThriftApiHandler()), new TBinaryProtocol.Factory()); // here
}
公共储蓄服务(){
超级(新MyService.Processor)(
新ThriftApiHandler()),新TBinaryProtocol.Factory();//此处
}
您正在自己实例化您的ThriftApiHandler
,而不是从Spring获得它
如果您想从Spring获取它,您需要从
ServlectContext
属性或您放置它的任何地方访问ApplicationContext
。我最终找到了它
@组件
添加到ThriftServlet
类ThriftProcessor
(见下文)的新类,它也是一个@组件
ThriftServlet
构造函数(见下文)更改为@Autowired
,并接受处理器
参数ThriftServlet
,而不是自己实例化它(注意:必须让ApplicationContext
刷新自己,然后才能工作)ThriftProcessor
类:
@Component
public class ThriftProcessor extends MyService.Processor<ThriftApiHandler> {
@Autowired
public ThriftProcessor(ThriftApiHandler iface) {
super(iface);
}
}
@Component
public class ThriftServlet extends TServlet {
@Autowired
public ThriftServlet(Processor<ThriftApiHandler> p) {
super(p, new TBinaryProtocol.Factory());
}
}
Initializer中的新servlet配置:
//register the thrift API servlet using a spring bean
ServletRegistration.Dynamic thrift = servletContext.addServlet("thriftapi", (ThriftServlet) ctx.getBean("thriftServlet")); // get thriftServlet from springbeans!
thrift.setLoadOnStartup(2);
thrift.addMapping("/api/*");
如果有更好的方法,请说出来 如果我将
@组件添加到ThriftServlet
,我是否能够@Autowire
一个ThriftApiHandler
?即使这样,我也不能在新的MyService.Processor(thriftApiHandler)
构造函数中引用它,因为它不是静态的…@wwarren您不应该在构造函数中添加处理程序。servlet是在init
方法中进行配置的,您可以在该方法中访问ServletContext
<代码>制作你的
ThrifServlet`a@组件
如果不是由Spring管理的话,它不会改变任何东西。我想我已经解决了——看看下面的答案,并提出任何改进建议?是的,正如我所说,如果你想让Spring管理它们,你需要从Spring上下文中创建bean。你所做的似乎很好。我只需将ThriftProcessor
构造函数更改为只包含ThriftApiHandler
参数,noApplicationContext
(除非您有多个ThriftApiHandler
bean。哦,是的,谢谢您-将其编辑到我的答案中!
//register the thrift API servlet using a spring bean
ServletRegistration.Dynamic thrift = servletContext.addServlet("thriftapi", (ThriftServlet) ctx.getBean("thriftServlet")); // get thriftServlet from springbeans!
thrift.setLoadOnStartup(2);
thrift.addMapping("/api/*");