spring 3以及servlet 3以后的版本都支持javaConfig技术以及注解技术,可以抛弃web.xml以及spring的xml配置了。
不用学习xml配置的知识,直接通过注解和硬编码方式去理解,对于开发人员来说是极好的。
替代web.xml
通过实现WebApplicationInitializer接口就可以了
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
XmlWebApplicationContext appContext = new XmlWebApplicationContext();
appContext.setConfigLocation("/WEB-INF/spring/spring-mvc.xml");
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(appContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
上面相当于如下:
<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
就是一个springmvc的实现,但spring bean还是配置在xml文件中。
先直观理解web.xml写法与javaConfig区别:
javaConfig的代码实现先创建好需要加载的配置对象,然后再创建mvc关键的DispatcherServlet对象,把DispatcherServlet需要的配置构造函数传参进去,再把DispatcherServlet对象添加到servlet的上下文中完成注册,使用注册的对象完成其他配置,例如映射的uri等。
替代xml
使用AnnotationConfigWebApplicationContext以及@Configuration、@Bean等注解方式自定义AppConfig、DispatcherConfig等的spring bean。
@Configuration
public class AppConfig {
@Bean(name="helloBean")
public HelloWorld helloWorld() {
return new HelloWorldImpl();
}
}
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = "com.xxx.springmvc")
public class DispatcherConfig{
@Bean
public ViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
// Create the 'root' Spring application context
AnnotationConfigWebApplicationContext rootContext =
new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
// Manage the lifecycle of the root application context
container.addListener(new ContextLoaderListener(rootContext));
// Create the dispatcher servlet's Spring application context
AnnotationConfigWebApplicationContext dispatcherContext =
new AnnotationConfigWebApplicationContext();
dispatcherContext.register(DispatcherConfig.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
没有spring的servlet实现
有些时候不需要经过spring框架去实现servlet
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = 577211309543842236L;
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.print("doGet");
/**
* todo
*/
out.close();
out = null;
}
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
request.setCharacterEncoding("UTF-8");
response.setCharacterEncoding("UTF-8");
PrintWriter out = response.getWriter();
out.print("doPost");
/**
* todo
*/
out.close();
out = null;
}
}
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
ServletRegistration.Dynamic myServlet=
servletContext.addServlet("myServlet", new MyServlet());
myServlet.addMapping("/myServlet");
}
}
filter以及listener的javaConfig
public class TestFilter implements Filter {
private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(
Arrays.asList( "/login", "/logout", "/register")));
@Override
public void init(FilterConfig filterConfig) throws ServletException {
System.out.println("init-----------filter");
}
@Override
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
boolean allowedPath = ALLOWED_PATHS.contains(path);
if (allowedPath) {
System.out.println("这里是不需要处理的url进入的方法");
chain.doFilter(req, res);
} else {
System.out.println("这里是需要处理的url进入的方法");
System.out.println(((HttpServletRequest) req).getRequestURI());
//chain.doFilter(req, res);
}
}
@Override
public void destroy() {
System.out.println("destroy----------filter");
}
}
public class MyListener implements ServletContextListener {
@Override
public final void contextInitialized(ServletContextEvent sce) {
//执行初始化操作
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
//执行销毁操作
}
}
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
/**编码过滤器*/
FilterRegistration.Dynamic characterEncodingFilter = container
.addFilter("encodingFilter", new CharacterEncodingFilter());
characterEncodingFilter.setInitParameter("encoding", "UTF-8");
characterEncodingFilter.setInitParameter("forceEncoding", "true");
characterEncodingFilter.addMappingForUrlPatterns(null, false, "/*");
/**自定义过滤器*/
FilterRegistration.Dynamic testFilter = container
.addFilter("testFilter", new TestFilter());
testFilter.addMappingForUrlPatterns(null, false, "/*");
/**监听器*/
container.addListener(ConfigListener.class);
}
}
servlet、filter、listener需要使用springbean
上面的情况都是没有使用springbean的,当需要的时候,直接注解注入会有问题。
需要实现两个WebApplicationInitializer,并先启动springbean配置的WebApplicationInitializer,
再自动自定义相关的WebApplicationInitializer,即可实现。
/**首先启动*/
@Order(1)
public class SpringInitializer extends
AbstractAnnotationConfigDispatcherServletInitializer {
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { WebMvcConfiguration.class, SpringConfiguration.class};
}
@Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
}
@Order(2)
public class MyWebAppInitializer implements WebApplicationInitializer {
@Override
public void onStartup(ServletContext container) {
ServletRegistration.Dynamic myServlet=
servletContext.addServlet("myServlet", new MyServlet());
myServlet.addMapping("/myServlet");
}
}
public class MyServlet extends HttpServlet {
private static final long serialVersionUID = -4081955072339096256L;
@Autowired
ISystemService systemService;
@Override
public void init() throws ServletException {
super.init();
WebApplicationContextUtils
.getWebApplicationContext(getServletContext())
.getAutowireCapableBeanFactory().autowireBean(this);
}
@Override
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
System.out.print(systemService.select(null));
}
@Override
public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
}
}
filter以及listener也是一样的配置到MyWebAppInitializer即可,使用注解注入的springbean。