両方のコンテキストは、同じサーブレットコンテキストに格納されます。
あなたが気付いた場合、AbstractDispatcherServletInitializer
、AbstractAnnotationConfigDispatcherServletInitializer
の親クラスは、最初にによって作成され、それは最初rootApplicationContextを追加し、その親onStartupメソッドを呼び出し、それを行うにはonStartup
方法
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
super.onStartup(servletContext);
registerDispatcherServlet(servletContext);
}
に登録を行います最後にcreateRootApplicationContext
AbstractAnnotationConfigDispatcherServletInitializer
クラスのメソッドとはのServletContextに追加onStartup法に受信:
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
registerContextLoaderListener(servletContext);
}
/**
* Register a {@link ContextLoaderListener} against the given servlet context. The
* {@code ContextLoaderListener} is initialized with the application context returned
* from the {@link #createRootApplicationContext()} template method.
* @param servletContext the servlet context to register the listener against
*/
protected void registerContextLoaderListener(ServletContext servletContext) {
WebApplicationContext rootAppContext = createRootApplicationContext();
if (rootAppContext != null) {
ContextLoaderListener listener = new ContextLoaderListener(rootAppContext);
listener.setContextInitializers(getRootApplicationContextInitializers());
servletContext.addListener(listener);
}
else {
logger.debug("No ContextLoaderListener registered, as " +
"createRootApplicationContext() did not return an application context");
}
}
そして、
/**
* Register a {@link DispatcherServlet} against the given servlet context.
* <p>This method will create a {@code DispatcherServlet} with the name returned by
* {@link #getServletName()}, initializing it with the application context returned
* from {@link #createServletApplicationContext()}, and mapping it to the patterns
* returned from {@link #getServletMappings()}.
* <p>Further customization can be achieved by overriding {@link
* #customizeRegistration(ServletRegistration.Dynamic)} or
* {@link #createDispatcherServlet(WebApplicationContext)}.
* @param servletContext the context to register the servlet against
*/
protected void registerDispatcherServlet(ServletContext servletContext) {
String servletName = getServletName();
Assert.hasLength(servletName, "getServletName() must not return empty or null");
WebApplicationContext servletAppContext = createServletApplicationContext();
Assert.notNull(servletAppContext,
"createServletApplicationContext() did not return an application " +
"context for servlet [" + servletName + "]");
FrameworkServlet dispatcherServlet = createDispatcherServlet(servletAppContext);
dispatcherServlet.setContextInitializers(getServletApplicationContextInitializers());
ServletRegistration.Dynamic registration = servletContext.addServlet(servletName, dispatcherServlet);
Assert.notNull(registration,
"Failed to register servlet with name '" + servletName + "'." +
"Check if there is another servlet registered under the same name.");
registration.setLoadOnStartup(1);
registration.addMapping(getServletMappings());
registration.setAsyncSupported(isAsyncSupported());
Filter[] filters = getServletFilters();
if (!ObjectUtils.isEmpty(filters)) {
for (Filter filter : filters) {
registerServletFilter(servletContext, filter);
}
}
customizeRegistration(registration);
}
あなたがリポジトリを注入することができ理由です:その後、AbstractDispatcherServletInitializer
は、それがAbstractAnnotationConfigDispatcherServletInitializer
クラスである抽象メソッドcreateServletApplicationContext
を呼び出した後、同じのServletContextに追加されdispatcherServlet
を作成し、そのregisterDispatcherServlet
メソッドを呼び出します2つのコンテキストが同じServletContext内にあるためです。
出典
2017-01-09 16:32:24
mlg
web.xmlファイルを投稿できますか? – mlg
私はweb.xmlを持たず、初期化はサブクラス –