Servlet3.0容器启动,会扫描当前每一个jar包中的ServletContainerInitializer的实现类(例如MyServletContainerInitializer),这个实现类必须指定在META-INF/services/javax.servlet.ServletContainerInitialzer的文件中,文件中的内容就是ServletContainerInitializer的实现类的全类名。
ServletContainerInitializer中的注解@HandlesType(value={xxx.class}),这个注解会在servletcontext启动的时候加载指定类型下面的所有实现,包括子接口,子类,实现类。
ServletContainerInitializer中方法onStartup(Set<Class<?>> set, ServletContext servletContext)方法,这个方法在容器启动的时候就会首先运行,其中参数set指的是@HandlesType中加载的所有类型,servletContext指的是servlet的context,代表当前web应用的servletcontxt,一个web应用只有一个servletcontext.
以下是加载实现的顺序:
一、创建一个接口Helloservice及三个实现类
package com.sgx.service;
public interface HelloService {
public void say();
}
package com.sgx.service;
public abstract class HelloServiceAbstract implements HelloService {
@Override
public void say() {
System.out.println("HelloServiceAbstract");
}
}
package com.sgx.service;
public class HelloServiceImpl implements HelloService {
@Override
public void say() {
System.out.println("HelloServiceImpl");
}
}
package com.sgx.service;
public interface HelloServiceSun extends HelloService {
public void sunSay();
}
二、创建ServletContainerInitializer的实现类MyServletContainerInitializer,@HandlesTypes指定servletContext容器加载时候的加载类Helloservice
package com.sgx.config;
import java.util.EnumSet;
import java.util.Set;
import javax.servlet.DispatcherType;
import javax.servlet.FilterRegistration;
import javax.servlet.ServletContainerInitializer;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;
import javax.servlet.annotation.HandlesTypes;
import com.sgx.filter.UserFilter;
import com.sgx.listener.UserListener;
import com.sgx.service.HelloService;
import com.xiao.servlet.UserServlet;
/**
* 容器启动的时候会将@HandlesTypes指定的类型下面的所有实现类,子接口加载进来<br>
* HandlesTypes 的值是类<br>
*/
@HandlesTypes(value = { HelloService.class })
public class MyServletContainerInitializer implements ServletContainerInitializer {
/**
* 应用启动的时候,会运行onStartup方法
*
* @param set
* HandlesTypes加载进来的所有类及其实现的子类
* @param servletContext
* 代表当前web应用的ServletContext,一个web应用一个ServletContext
* @Author xxx
*/
@Override
public void onStartup(Set<Class<?>> set, ServletContext servletContext) throws ServletException {
// 启动的时候加载servletcontext所有默认的加载类
for (Class<?> class1 : set) {
System.out.println(class1);
}
}
}
三、在src下面创建META-INF/services/目录,在里面创建文件javax.servlet.ServletContainerInitialzer,在文件中写入要加载的ServletContainerInitializer实现类全类名(com.sgx.config.MyServletContainerInitializer)
启动tomcat容器,打印如下
可以我们自己写的接口及实现类都在窗口启动的时候已经加载了