![](/img/trans.png)
[英]Filters - Servlets and Spring beans integration NullPointerException
[英]SpringMVC, null spring beans, servlets and Apache Thrift
我有一個具有UserService
的Web應用程序,以允許進行與用戶相關的操作。
我可以將UserService
bean自動連接到任何@Controller
類中,並且工作正常。
如果我像這樣添加第二個類型為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
裝飾了ThriftApiHandler
以便進行bean注入(或者我認為),使其看起來像這樣:
@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
}
}
我可以在調試日志中看到確實在進行自動裝配(時間戳和類已被刪除):
<snip> - Creating shared instance of singleton bean 'thriftApiHandler'
<snip> - Creating instance of bean 'thriftApiHandler'
<snip> - Registered injected element on class [my.package.api.ThriftApiHandler]: AutowiredFieldElement for my.package.service.UserService my.package.api.ThriftApiHandler.userService
<snip> - Eagerly caching bean 'thriftApiHandler' to allow for resolving potential circular references
<snip> - Processing injected method of bean 'thriftApiHandler': AutowiredFieldElement for my.package.service.UserService my.package.api.ThriftApiHandler.userService
但是在任何節儉的api方法中, userService
(以及我嘗試插入的任何其他bean)始終為null。
也許與TServlet
類是如何從HttpServlet
繼承而來的,並且不“了解” spring上下文有關?
我覺得我缺少與servlet上下文和共享bean等有關的東西,但是對於SpringMVC來說我還是很陌生。 如果發布更多代碼會使此問題更易於回答,請告訴我。
如果Spring無法解析@Autowired
目標,它將始終失敗(引發異常)。 如果您得到null
,那么Spring實際上並沒有管理您的對象,因此無法注入任何東西。 就是這種情況。
public ThriftServlet() {
super(new MyService.Processor<ThriftApiHandler>(
new ThriftApiHandler()), new TBinaryProtocol.Factory()); // here
}
您將自己實例化ThriftApiHandler
,而不是從Spring獲取它。
如果要從Spring獲取它,則需要從ServlectContext
屬性或放置在其他任何位置的ApplicationContext
訪問ApplicationContext
。
我終於弄清楚了...
ThriftServlet
類中添加了@Component
ThriftProcessor
的新類(參見下文),它也是一個@Component
ThriftServlet
構造函數(請參見下文)更改為@Autowired
並接受Processor
參數 ThriftServlet
而不是自己實例化(注意:必須告訴ApplicationContext
刷新自身,然后才能起作用) ThriftProcessor
類:
@Component
public class ThriftProcessor extends MyService.Processor<ThriftApiHandler> {
@Autowired
public ThriftProcessor(ThriftApiHandler iface) {
super(iface);
}
}
ThriftServlet
類:
@Component
public class ThriftServlet extends TServlet {
@Autowired
public ThriftServlet(Processor<ThriftApiHandler> p) {
super(p, new TBinaryProtocol.Factory());
}
}
初始化器中的新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/*");
如果有“更好”的方法,請這樣說!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.