我在应用程序中自动装配Spring bean时遇到问题。这是我之前在其他应用程序中成功完成的事情,但由于某种原因,我感到难过。我已经用Google搜索了,并且发现很多人遇到了同样的问题,而且警告也伴随着使用getApplicationContext()方法而没有帮助我的答案。我理解这些警告,并且仍然有一个我希望这样做的情况,然后我可能会使用AspectJ并编译时编织。
这是我的设置:
的applicationContext.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:oxm="http://www.springframework.org/schema/oxm"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/oxm
http://www.springframework.org/schema/oxm/spring-oxm-3.0.xsd
http://www.springframework.org/schema/util
http://www.springframework.org/schema/util/spring-util-3.0.xsd">
<context:property-placeholder location="classpath:widgetClient.properties"/>
<context:component-scan base-package="com.myCompany.widget.domain" />
<context:component-scan base-package="com.myCompany.widget.services" />
<context:annotation-config />
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource">
<property name="basename" value="messages" />
</bean>
<bean id="heartbeat" class="com.company.widget.domain.CheckWidgetServerHeartbeat" destroy-method="destroy">
<constructor-arg type="java.lang.Integer" name="interval" value="${heartbeat.interval}"/>
<constructor-arg type="java.lang.Integer" name="timeout" value="${heartbeat.timeout}"/>
<constructor-arg type="java.lang.Integer" name="unhealthyThreshold" value="${unhealthy.threshold}"/>
<constructor-arg type="java.lang.Integer" name="healthyThreshold" value="${healthy.threshold}"/>
<constructor-arg type="java.lang.Integer" name="backupVerifyTime" value="${backup.verify.time}"/>
<constructor-arg type="java.lang.String" name="apiServerUrl" value="${api.server.url}" />
</bean>
</beans>
BaseService.java
package com.company.widget.services;
import com.company.widget.domain.CheckWidgetServerHeartbeat;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class BaseService{
@Autowired
private ApplicationContext appContext;
public BaseService(){}
public CheckWidgetServerHeartbeat getHeartbeat(){
return (CheckWidgetServerHeartbeat) appContext.getBean("heartbeat");
}
}
Heartbeatservice.java
package com.company.widget.services;
import org.springframework.stereotype.Service;
import org.apache.log4j.Logger;
@Service
public class HeartbeatService extends BaseService{
private static final Logger logger = Logger.getLogger(HeartbeatService.class);
public HeartbeatService(){}
public Boolean isHealthy(){
return getHeartbeat().check();
}
}
CompanyWidgetClient.java
package com.company.widget.domain;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.util.Locale;
import java.util.ResourceBundle;
import java.net.HttpURLConnection;
import java.net.InetAddress;
import java.net.URI;
import java.net.URL;
import java.net.URLConnection;
import java.net.UnknownHostException;
import java.util.*;
import com.company.widget.services.HeartbeatService;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
@Component
public class CompanyWidgetClient{
@Autowired
private HeartbeatService heartbeatService;
public CompanyWidgetClient(String settingsXmlFilePath, HttpServletRequest request){
if(settingsXmlFilePath != null){
configuration = new CompanyWidgetConfiguration(settingsXmlFilePath, request);
}
if(request != null){
this.request = request;
}
//Use API server URL from settings file if it is present
if (configuration.getProperty("api_server_url") != null) {
this.apiServerUrl = configuration.getProperty("api_server_url");
log.debug("Set api_server_url to " + this.apiServerUrl + " which was found in settings.xml");
}
}
public CompanyWidgetClient(CompanyWidgetConfiguration configuration, HttpServletRequest request){
if(configuration != null){
this.configuration=configuration;
}
if(request != null){
this.request = request;
}
//Use API server URL from settings file if it is present
if (configuration.getProperty("api_server_url") != null) {
this.apiServerUrl = configuration.getProperty("api_server_url");
log.debug("Set api_server_url to " + this.apiServerUrl + " which was found in settings.xml");
}
}
public CompanyWidgetClient(){}
private CompanyWidgetResponse requestWidget(){
if(heartbeatService.isHealthy()){
do stuff...
}
的index.jsp
<%@ page import="com.company.widget.domain.*" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
CompanyWidgetClient widgetClient = new CompanyWidgetClient("/WEB-INF/settings.xml", request);
String companyWidgetComponent = widgetClient.createWidget();
%>
...
HTML stuff
...
<div id="widget">
<%=companyWidgetComponent%>
</div>
...
错误:
500
org.apache.jasper.JasperException: An exception occurred processing JSP page /index.jsp at line 5
2: <%@ page contentType="text/html;charset=UTF-8" language="java" %> 3: <% 4: CompanyWidgetClient widgetClient = new CompanyWidgetClient("/WEB-INF/settings.xml", request); 5: String companyWidgetComponent = widgetClient.createWidget(); 6: %> 7: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 8: "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
Stacktrace:
org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:568)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:470)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
root cause
java.lang.NullPointerException
com.company.widget.domain.CompanyWidgetClient.requestWidget(CompanyWidgetClient.java:553)
com.company.widget.domain.CompanyWidgetClient.createWidget(CompanyWidgetClient.java:603)
org.apache.jsp.index_jsp._jspService(index_jsp.java:67)
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
观察:
我知道我错过了一些东西,因为它需要默认构造函数出现在CompanyClient对象上,并且它记录它在部署时构建了一个CompanyClient对象。在Spring应用程序上下文中,我想我的范围不是很清楚。我的理解是,无论调用bean的范围如何,都应该使用应用程序上下文来使用单例bean。非常感谢任何和所有的帮助!
答案 0 :(得分:0)
直接实例化CompanyWidgetClient时:
new CompanyWidgetClient(...)
你没有给spring DI容器注入一个HeartbeatService实例 - 所以它是null。
获取CompanyWidgetClient的实例时 - 从Spring Applicaiton Context(通过getBean()或类似方法)检索实例 - 因此HeartbeatService将自动连接。