我正在尝试在我的 OSGi 包中加载 spring dm。我遵循了一个教程。我的目标是,对于特定的 URL,URL 应该由 spring 处理,而不是默认的 sling servlet。我部分成功地实现了这一目标。
有时,它不起作用。我的 globaldispatcher servlet 没有被初始化。问题是间歇性的。有时我的 spring servlet 被初始化得很好。但有时我会收到此错误:
[SpringOsgiExtenderThread-2] net.jasonday.examples.sling.spring.mvc.sling.SlingDispatcherServlet FrameworkServlet 'globaldispatcher': initialization started
[SpringOsgiExtenderThread-2] net.jasonday.examples.sling.spring.mvc.sling.SlingDispatcherServlet Context initialization failed
java.lang.IllegalArgumentException: bundle context should be set before refreshing the application context
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.normalRefresh(AbstractDelegatedExecutionApplicationContext.java:179)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext$NoDependenciesWaitRefreshExecutor.refresh(AbstractDelegatedExecutionApplicationContext.java:89)
at org.springframework.osgi.context.support.AbstractDelegatedExecutionApplicationContext.refresh(AbstractDelegatedExecutionApplicationContext.java:175)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:467)
at org.springframework.web.servlet.FrameworkServlet.createWebApplicationContext(FrameworkServlet.java:483)
at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:358)
at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:325)
at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:127)
at javax.servlet.GenericServlet.init(GenericServlet.java:158)
at org.apache.sling.servlets.resolver.internal.SlingServletResolver.createServlet(SlingServletResolver.java:988)
at org.apache.sling.servlets.resolver.internal.SlingServletResolver.bindServlet(SlingServletResolver.java:936)
at sun.reflect.GeneratedMethodAccessor36.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
Java版本:1.7.0_45
我正在使用教程中提到的以下依赖项:(都是 OSGi 包)
Spring AOP v3.0.6.RELEASE
Spring ASM v3.0.6.RELEASE
Spring Aspects v3.0.6.RELEASE
Spring Beans v3.0.6.RELEASE
Spring Context v3.0.6.RELEASE
Spring Context Support v3.0.6.RELEASE
Spring Core v3.0.6.RELEASE
Spring Expression v3.0.6.RELEASE
Spring Web v3.0.6.RELEASE
Spring Web Servlet v3.0.6.RELEASE
Spring OSGi IO v1.2.1
Spring OSGi Core v1.2.1
Spring OSGi Extender v1.2.1
Spring OSGi Annotation v1.2.1
Spring OSGi Web v1.2.1
AOP Alliance v1.0.0
CGLib 2.2.0
Commons Lang v2.6
Commons Codec v1.5
Commons Logging v1.1.1
ASM v3.2.0
JSR 330 (javax.inject) v1.0.0
JSR 250 (javax.annotation) v1.0.0
以下是我的 spring-osgi.xml 中的代码,它位于 META-INF/spring/ 文件夹中
<osgi:service ref="globalSlingDispatcherServlet">
<osgi:interfaces>
<value>javax.servlet.Servlet</value>
</osgi:interfaces>
<osgi:service-properties>
<entry key="sling.servlet.resourceTypes" value="examples/sling/spring/mvc/dispatcher/global" />
<entry key="sling.servlet.extensions">
<array>
<value>json</value>
<value>html</value>
</array>
</entry>
<entry key="sling.servlet.methods">
<array>
<value>GET</value>
<value>POST</value>
</array>
</entry>
<entry key="contextClass" value="org.springframework.osgi.web.context.support.OsgiBundleXmlWebApplicationContext"/>
<entry key="sling.core.servletName" value="globaldispatcher" />
</osgi:service-properties>
下面是来自 META-INF\spring\spring.xml 的代码
<context:annotation-config />
<context:component-scan base-package="net.jasonday.examples.sling.spring.mvc.sling" />
<aop:aspectj-autoproxy />
<bean class="org.springframework.osgi.extensions.annotation.ServiceReferenceInjectionBeanPostProcessor" />
以下是来自 WEB-INF/globaldispatcher 的代码
<context:annotation-config />
<context:component-scan base-package="net.jasonday.examples.sling.spring.mvc">
<context:exclude-filter type="regex"
expression="net\.jasonday\.examples\.sling\.spring\.mvc\.sling\..*" />
</context:component-scan>
<aop:aspectj-autoproxy />
<bean class="org.springframework.osgi.extensions.annotation.ServiceReferenceInjectionBeanPostProcessor" />
SlingConfiguration.java:
@Configuration
public class SlingConfiguration {
@Bean
@DependsOn("slingContextLoader")
public SlingDispatcherServlet globalSlingDispatcherServlet() {
return new SlingDispatcherServlet();
}
}
SlingContextLoader.java:
@Component
public class SlingContextLoader extends ContextLoader {
private ServletContext servletContext;
private ApplicationContext applicationContext;
public ApplicationContext getApplicationContext() {
return applicationContext;
}
@Inject
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = applicationContext;
}
public ServletContext getServletContext() {
return servletContext;
}
@ServiceReference
public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}
@Override
protected Class<?> determineContextClass(
ServletContext currentServletContext) {
return OsgiBundleXmlWebApplicationContext.class;
}
@Override
protected ApplicationContext loadParentContext(
ServletContext currentServletContext) {
return applicationContext;
}
@PostConstruct
public void init() {
initWebApplicationContext(servletContext);
}
@PreDestroy
public void destroy() {
closeWebApplicationContext(servletContext);
}
}
我的 SlingDispatcherServlet.java
public class SlingDispatcherServlet extends DispatcherServlet implements Servlet {
@PreDestroy
@Override
public void destroy() {
super.destroy();
String attrName = getServletContextAttributeName();
getServletContext().removeAttribute(attrName);
}
}