【问题标题】:Cannot inject Solr Server into app using Spring through @Autowired无法通过 @Autowired 使用 Spring 将 Solr Server 注入应用程序
【发布时间】:2012-06-28 17:36:02
【问题描述】:

我目前在尝试将 solr 服务器实例从 bean 注入我的代码时遇到问题。我得到一个NullPointerException 并检查了服务器实例本身并验证它为空。我可以创建服务器而不注入它就好了。

我的 spring.xml 文件这样声明 bean:

<bean id="solrServer" class="org.apache.solr.client.solrj.impl.HttpSolrServer">`
     <constructor-arg index="0" value="${solr.serverUrl}" />
</bean>

<context:annotation-config />
<context:component-scan base-package="my.base.package" />

${solr.serverUrl} 的值已被确认为正确。

web.xml 文件中包含上下文侦听器:

<context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring.xml</param-value>
</context-param> 

<listener>
    <listener-class>
        org.springframework.web.context.ContextLoaderListener
    </listener-class>
</listener>     

<servlet>
    .
    <servlet-class>
        com.sun.jersey.spi.spring.container.servlet.SpringServlet
    </servlet-class>
    .
</servlet>

我试图注入这个bean的代码是@Autowired,如下所示:

34    @Component
35    public class GenericClassImpl implements GenericClass{
36  
37        @Autowired
38        private SolrServer solrServer;
39  
40        public String doQuery(String query){
41            try{          
42                    SolrQuery solrQuery = new SolrQuery(query);           
43                    QueryResponse rsp = solrServer.query(solrQuery);
44                    SolrDocumentList docs = rsp.getResults();
45          
46                    return docs.toString();
47            }catch(Exception e){
48                e.printStackTrace();
49            }
50        }
51    }

我曾尝试将@Qualifier("solrServer")@Autowired 一起使用,但这也不起作用。

这一切都是使用 maven 完成的,它本身似乎没有任何问题。我得到的输出是

java.lang.NullPointerException
    at ...GenericClassImpl.doQuery(GenericClassImpl.java:43)
    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.sun.jersey.spi.container.JavaMethodInvokerFactory$1.invoke(JavaMethodInvokerFactory.java:60)
    at com.sun.jersey.server.impl.model.method.dispatch.AbstractResourceMethodDispatchProvider$TypeOutInvoker._dispatch(AbstractResourceMethodDispatchProvider.java:185)
    at com.sun.jersey.server.impl.model.method.dispatch.ResourceJavaMethodDispatcher.dispatch(ResourceJavaMethodDispatcher.java:75)
    at com.sun.jersey.server.impl.uri.rules.HttpMethodRule.accept(HttpMethodRule.java:288)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.ResourceClassRule.accept(ResourceClassRule.java:108)
    at com.sun.jersey.server.impl.uri.rules.RightHandPathRule.accept(RightHandPathRule.java:147)
    at com.sun.jersey.server.impl.uri.rules.RootResourceClassesRule.accept(RootResourceClassesRule.java:84)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1483)
    at com.sun.jersey.server.impl.application.WebApplicationImpl._handleRequest(WebApplicationImpl.java:1414)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1363)
    at com.sun.jersey.server.impl.application.WebApplicationImpl.handleRequest(WebApplicationImpl.java:1353)
    at com.sun.jersey.spi.container.servlet.WebComponent.service(WebComponent.java:414)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:537)
    at com.sun.jersey.spi.container.servlet.ServletContainer.service(ServletContainer.java:708)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:717)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:233)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293)
    at org.apache.coyote.http11.Http11AprProcessor.process(Http11AprProcessor.java:877)
    at org.apache.coyote.http11.Http11AprProtocol$Http11ConnectionHandler.process(Http11AprProtocol.java:594)
    at org.apache.tomcat.util.net.AprEndpoint$Worker.run(AprEndpoint.java:1675)
    at java.lang.Thread.run(Thread.java:662)

再次,如果我这样做了

SolrServer solrServer = new HttpSolrServer(serverUrl);

代码运行良好,我可以在 solr 服务器上执行查询。 关于我做错了什么这不会注入的任何想法?

获取GenericClassImpl实例的代码是

public class GenericServiceImpl implements GenericService{

    protected GenericClass gc;

    @GET
    @Path({pathParam})
    public String doGet(@PathParam({pathParam}) String pathParam, 
                        @DefaultValue("*:*") @QueryParam("q") String query){

            gc = SearchFactory.getInstance().getGenericClass(pathParam);        
            return gc.doQuery(query);
        }
    }

SearchFactory

public class SearchFactory{

    private static SearchFactory instance;

    private SearchFactory(){}

    public static SearchFactory getInstance() {
        if (instance == null)
            instance = new SearchFactory();
        return instance;
    }

    public GenericClass getGenericClass(String type){

        GenericClass result = null;

        if(type.toLowerCase().equals("case1")){
            result = new GenericClassImpl1();
            return result;
        }
        else if(type.toLowerCase().equals("case2")){
            result = new GenericClassImpl2();
            return result;
        }
        else throw new Exception();
    }
}

GenericClassImpl1GenericClassImpl2 都扩展了 GenericClassImpl 并且当前为空。

【问题讨论】:

  • 你能告诉我们你获得GenericClassImpl实例的代码吗?
  • 我刚刚添加了获取它实例的代码。谢谢!

标签: spring maven solr jersey autowired


【解决方案1】:

为了使 @Autowired 工作,您需要从 Spring 获取您的 GenericClassImpl 实例。如果你不这样做,Spring 将不会自动装配依赖项。

您不能使用 new 关键字来实例化它们并使用依赖注入技术。

您可以做的是保持对您的 ApplicationContext 的静态引用,然后在您的 getGenericClass 方法中从它们中提取相关 bean 的实例。

这实际上是 ServiceLocator 模式的一个很好的用例,正如 Spring 文档中所讨论的那样。

【讨论】:

  • 我最终只是在做并且效果很好的是在 SearchFactory、GenericClassImpl1 和 GenericClassImpl2 类上抛出一个组件,并在其中的新实例变量上使用 Autowired,然后只返回这些私有变量,让 spring 处理他们的建设,并能够管理他们的生命周期
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多