今天,我在spring-boot项目中遇到了一个错误。
在我的代码中,我想获得ApplicationContext
,但它是null
,因此我无法使用getBean()
。
这是Application.java
的配置:
@SpringBootApplication
@EnableAspectJAutoProxy
public class Application extends SpringBootServletInitializer {
@Override
protected SpringApplicationBuilder configure(
SpringApplicationBuilder application) {
return application.sources(Application.class);
}
@Bean
public ServletRegistrationBean readHitchEventServletBean() {
ServletRegistrationBean readHitchEventServletBean =
new ServletRegistrationBean();
readHitchEventServletBean.setServlet(new ReadHitchEventServlet());
readHitchEventServletBean.setLoadOnStartup(5);
return readHitchEventServletBean;
}
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
}
然后是servlet:
@Component
public class ReadHitchEventServlet extends HttpServlet implements ApplicationContextAware {
private static final long serialVersionUID = 1L;
private static ApplicationContext applicationContext;
@SuppressWarnings("static-access")
@Override
public void setApplicationContext(ApplicationContext applicationContext)
throws BeansException {
// TODO Auto-generated method stub
this.applicationContext = applicationContext;
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
@Override
public void init() {
getBean("heheda");
}
}
我收到以下错误:
java.lang.NullPointerException: null
at com.gdut.dongjun.ActiveSwitchThread.getBean(ReadHitchEventServlet.java:126) ~[classes/:na]
at com.gdut.dongjun.ActiveSwitchThread.<init>(ReadHitchEventServlet.java:66) ~[classes/:na]
at com.gdut.dongjun.ReadHitchEventServlet.init(ReadHitchEventServlet.java:56) ~[classes/:na]
at javax.servlet.GenericServlet.init(GenericServlet.java:158) ~[tomcat-embed-core-8.0.23.jar:8.0.23]
at org.apache.catalina.core.StandardWrapper.initServlet(StandardWrapper.java:1231) [tomcat-embed-core-8.0.23.jar:8.0.23]
at org.apache.catalina.core.StandardWrapper.load(StandardWrapper.java:1034) [tomcat-embed-core-8.0.23.jar:8.0.23]
at org.apache.catalina.core.StandardContext.loadOnStartup(StandardContext.java:4914) [tomcat-embed-core-8.0.23.jar:8.0.23]
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedContext.deferredLoadOnStartup(TomcatEmbeddedContext.java:66) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.startConnector(TomcatEmbeddedServletContainer.java:209) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainer.start(TomcatEmbeddedServletContainer.java:152) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.startEmbeddedServletContainer(EmbeddedWebApplicationContext.java:288) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.finishRefresh(EmbeddedWebApplicationContext.java:141) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.__refresh(AbstractApplicationContext.java:483) [spring-context-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.jrLockAndRefresh(AbstractApplicationContext.java) [spring-context-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java) [spring-context-4.1.7.RELEASE.jar:4.1.7.RELEASE]
at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:118) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:686) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:320) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:957) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:946) [spring-boot-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at com.gdut.dongjun.Application.main(Application.java:282) [classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.7.0_79]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) ~[na:1.7.0_79]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.7.0_79]
at java.lang.reflect.Method.invoke(Method.java:606) ~[na:1.7.0_79]
at org.springframework.boot.maven.RunMojo$LaunchRunner.run(RunMojo.java:418) [spring-boot-maven-plugin-1.2.5.RELEASE.jar:1.2.5.RELEASE]
at java.lang.Thread.run(Thread.java:745) [na:na]
我该如何解决?
答案 0 :(得分:2)
最好有一个单独的类来实现ApplicationContextAware,以便为所需的类提供应用程序上下文。这里的问题似乎是Spean bean生命周期和servlet容器生命周期执行不同的操作。
即init可以在spring设置上下文之前调用。
答案 1 :(得分:0)
在线:
readHitchEventServletBean.setServlet(new ReadHitchEventServlet());
您正在创建一个不是Spring Bean的servlet对象的新实例,因此它没有正确连接。如果您想这样做,请考虑执行以下操作:
Application.java:
@Bean
public ServletRegistrationBean readHitchEventServletBean(ApplicationContext applicationContext) {
ServletRegistrationBean readHitchEventServletBean = new ServletRegistrationBean();
readHitchEventServletBean.setServlet(new ReadHitchEventServlet(applicationContext));
readHitchEventServletBean.setLoadOnStartup(5);
return readHitchEventServletBean;
}
ReadHitchEventServlet.java:
public class ReadHitchEventServlet extends HttpServlet {
private final ApplicationContext applicationContext;
ReadHitchEventServlet(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
@Override
public void init() {
applicationContext.getBean("heheda");
}
}
或者更好的方法是完全省略ApplicationContext,只需连接你最想要的bean。
Application.java:
@Bean
public ServletRegistrationBean readHitchEventServletBean(Heheda heheda) {
ServletRegistrationBean readHitchEventServletBean = new ServletRegistrationBean();
readHitchEventServletBean.setServlet(new ReadHitchEventServlet(heheda));
readHitchEventServletBean.setLoadOnStartup(5);
return readHitchEventServletBean;
}
ReadHitchEventServlet.java:
public class ReadHitchEventServlet extends HttpServlet {
private final Heheda heheda;
ReadHitchEventServlet(Heheda heheda) {
this.heheda = heheda;
}
@Override
public void init() {
// do something with heheda
}
}
答案 2 :(得分:0)
public List<ISurvey> getActiveSurveysWithRespondents(String userId) throws MCBusinessException {
List<ISurvey> surveyList = null;
List<ISurvey> activeSurveys = surveyRepo.getActiveSurveysList(userId, OTellerConstants.Pollster_Active_Survey);
if (activeSurveys != null && !activeSurveys.isEmpty()) {
Comparator<ISurvey> compareByDate = (ISurvey o1, ISurvey o2) -> (o1.getCreatedDate())
.compareTo(o2.getCreatedDate());
activeSurveys.sort(compareByDate.reversed());
Comparator<ISurvey> compareByTime = (ISurvey o1, ISurvey o2) -> (o1.getLastChgTs())
.compareTo(o2.getLastChgTs());
activeSurveys.sort(compareByTime.reversed());
surveyList = new ArrayList<>();
ISurvey surveyD = null;
if (!CollectionUtils.isEmpty(activeSurveys)) {
for (ISurvey survey : activeSurveys) {
if (survey.getStatus() == OTellerConstants.Live_Survey_status) {
Integer taggedRespondents = surveyRepo.getRespondents(survey.getId());
Integer answeredRespondents = surveyRepo.getAnsweredRespondents(survey.getId());
surveyD = new SurveyD();
surveyD.setId(survey.getId());
surveyD.setSurveyName(survey.getSurveyName());
surveyD.setStatus(survey.getStatus());
BeanUtils.copyProperties(survey, surveyD);
surveyD.setRespondentCount(taggedRespondents);
surveyD.setAnsweredRespondent(answeredRespondents);
surveyList.add(surveyD);
} else {
surveyD = new SurveyD();
surveyD.setId(survey.getId());
surveyD.setSurveyName(survey.getSurveyName());
surveyD.setStatus(survey.getStatus());
BeanUtils.copyProperties(survey, surveyD);
surveyList.add(surveyD);
}
}
我正在null
如何解决??