001/* 002 * Copyright 2012-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.web.embedded.jetty; 018 019import javax.servlet.ServletException; 020 021import org.eclipse.jetty.util.component.AbstractLifeCycle; 022import org.eclipse.jetty.webapp.AbstractConfiguration; 023import org.eclipse.jetty.webapp.Configuration; 024import org.eclipse.jetty.webapp.WebAppContext; 025 026import org.springframework.boot.web.servlet.ServletContextInitializer; 027import org.springframework.util.Assert; 028 029/** 030 * Jetty {@link Configuration} that calls {@link ServletContextInitializer}s. 031 * 032 * @author Phillip Webb 033 * @author Andy Wilkinson 034 * @since 2.0.0 035 */ 036public class ServletContextInitializerConfiguration extends AbstractConfiguration { 037 038 private final ServletContextInitializer[] initializers; 039 040 /** 041 * Create a new {@link ServletContextInitializerConfiguration}. 042 * @param initializers the initializers that should be invoked 043 * @since 1.2.1 044 */ 045 public ServletContextInitializerConfiguration( 046 ServletContextInitializer... initializers) { 047 Assert.notNull(initializers, "Initializers must not be null"); 048 this.initializers = initializers; 049 } 050 051 @Override 052 public void configure(WebAppContext context) throws Exception { 053 context.addBean(new Initializer(context), true); 054 } 055 056 /** 057 * Jetty {@link AbstractLifeCycle} to call the {@link ServletContextInitializer 058 * ServletContextInitializers}. 059 */ 060 private class Initializer extends AbstractLifeCycle { 061 062 private final WebAppContext context; 063 064 Initializer(WebAppContext context) { 065 this.context = context; 066 } 067 068 @Override 069 protected void doStart() throws Exception { 070 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 071 Thread.currentThread().setContextClassLoader(this.context.getClassLoader()); 072 try { 073 callInitializers(); 074 } 075 finally { 076 Thread.currentThread().setContextClassLoader(classLoader); 077 } 078 } 079 080 private void callInitializers() throws ServletException { 081 try { 082 setExtendedListenerTypes(true); 083 for (ServletContextInitializer initializer : ServletContextInitializerConfiguration.this.initializers) { 084 initializer.onStartup(this.context.getServletContext()); 085 } 086 } 087 finally { 088 setExtendedListenerTypes(false); 089 } 090 } 091 092 private void setExtendedListenerTypes(boolean extended) { 093 try { 094 this.context.getServletContext().setExtendedListenerTypes(extended); 095 } 096 catch (NoSuchMethodError ex) { 097 // Not available on Jetty 8 098 } 099 } 100 101 } 102 103}