基于纯Java代码的Spring容器和Web容器零配置的思考和实现(3) - 使用配置

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 经过《基于纯Java代码的Spring容器和Web容器零配置的思考和实现(1) - 数据源与事务管理》和《基于纯Java代码的Spring容器和Web容器零配置的思考和实现(2) - 静态资源、视图和消息器》两篇博文的介绍,我们已经配置好了Spring所需的基本配置。

经过《基于纯Java代码的Spring容器和Web容器零配置的思考和实现(1) - 数据源与事务管理》《基于纯Java代码的Spring容器和Web容器零配置的思考和实现(2) - 静态资源、视图和消息器》两篇博文的介绍,我们已经配置好了Spring所需的基本配置。在这边博文中,我们将介绍怎么使用这些配置到实际项目中,并将web.xml文件替换为一个Java类。

我们使用Java代码来配置Spring,目的就是使我们的这些配置能够复用,对于这些配置的复用,我们采用继承和引入来实现。我们同样提供两个类在项目中配置Spring容器。首先提供一个AppConfig类来配置Spring容器,源码如下:

package com.kiiwow;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.PropertySource;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import com.kiiwow.framework.config.context.spring.rest.RestSpringContextConfig;
import com.kiiwow.framework.config.context.spring.rest.dbconfig.C3p0DataSourceDBConfig;

@Configuration
@EnableAspectJAutoProxy
@EnableTransactionManagement
@ComponentScan(basePackages = {"com.kiiwow.*"})
@Import({SpringContextConfig.class, C3p0DataSourceDBConfig.class})
@PropertySource({"classpath:kiiwow.properties"})
public class AppConfig {

}

 

 

上面的代码使用到了很多注解,我们逐一解释其作用:

  • @Configuration,用于表示这个类是一个配置类,用于配置Spring的相关信息

  • @EnableAspectJAutoProxy,启用切面自动代理,用于AOP

  • @EnableTransactionManagement,启用注解事务,即可以使用@Transactional注解来控制事务

  • @ComponentScan,组件扫描,在basePackages指定的目录下扫描被@Controller、@Service、@Component等注解注册的组件

  • @Import,引入指定的配置类,我们引入了Spring容器配置类和数据源事务配置类

  • @PropertySource,加载指定的配置文件,配置文件内容会加载入Environment中等待调用

这样我们就把Spring容器所需要的配置完成了,接下来我们提供一个WebConfig类来配置Web子容器的相关内容,源码如下:

package com.kiiwow;

import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;

import com.kiiwow.framework.config.context.spring.WebContextConfig;

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"com.kiiwow.*"})
@PropertySource({"classpath:kiiwow.properties"})
public class WebConfig extends WebContextConfig {

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //注册自定义监听器
    }

}

 

 

@EnableWebMvc注解用于启用SpringMVC,我们让WebConfig继承自我们已经设计好的Web子容器配置类WebContextConfig,这样WebConfig就已经拥有了所需要的基本配置。

 

由于WebContextConfig本身继承了org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter,所以我们可以直接重写void addInterceptors(InterceptorRegistry registry)方法来注册自定义的监听器。

至此,我们基于Java代码对于Spring的基本配置就全部完成了。

 



但是我们知道,SpringMVC要运行起来还需要在web.xml中配置相关的Servlet,不过既然我们对Spring都采用了全Java配置,那我们也不妨用Java代码来代替web.xml配置。我们提供一个KiiwowInitializer类来替代web.xml,这个类实现了org.springframework.web.WebApplicationInitializer接口,接口中有一个方法void onStartup(ServletContext container) throws ServletException,这个方法的方法体就是web容器启动时需要做的动作,也就是我们以前在web.xml中配置的信息。源码如下:

package com.kiiwow;

import java.util.EnumSet;

import javax.servlet.DispatcherType;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration.Dynamic;

import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.DispatcherServlet;

import com.kiiwow.framework.platform.sqlmapping.SQLMappingInitListener;

/**
 * 用于替代web.xml的web容器配置类
 * 在这里配置过滤器、监听器、Servlet
 *
 * @author leon.gan
 *
 */
public class KiiwowInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext container) throws ServletException {
        //配置Spring提供的字符编码过滤器
        javax.servlet.FilterRegistration.Dynamic filter = container.addFilter("encoding", new CharacterEncodingFilter());
        //配置过滤器的过滤路径
        filter.addMappingForUrlPatterns(EnumSet.of(DispatcherType.REQUEST), true, "/");
        
        //基于注解配置的Spring容器上下文
        AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
        //注册Spring容器配置类
        rootContext.register(AppConfig.class);
        container.addListener(new ContextLoaderListener(rootContext));
        //SQL配置文件监听器
        container.addListener(new SQLMappingInitListener());
        
        //基于注解配置的Web容器上下文
        AnnotationConfigWebApplicationContext context = new AnnotationConfigWebApplicationContext();
        //注册Web容器配置类
        context.register(WebConfig.class);
        Dynamic servlet = container.addServlet("dispatcher", new DispatcherServlet(context));
        //配置映射路径
        servlet.addMapping("/");
        //启动顺序
        servlet.setLoadOnStartup(1);
    }

}

 

 

我们首先将Spring提供的字符编码过滤器注册进容器,然后创建基于注解配置的Spring容器上下文,这个context用于注册对Spring容器进行配置的配置类,即刚才我们配置的AppConfig,然后将这个context加入容器的监听器中,使其生命周期与web容器的生命周期一致,然后添加一系列自定义的监听器。接着我们创建基于注解配置的Web容器上下文,这个上下文用于注册对SpringWeb容器进行配置的配置类,即我们刚才定义的WebConfig,然后基于这个上下文创建org.springframework.web.servlet.DispatcherServlet.DispatcherServlet用于拦截和转发请求。

至此,我们所有的配置都已经完成,这个时候我们项目中对于配置这一块就不会再存在XML文件了。另外,如果我们是使用Maven管理项目,这个时候Maven找不到我们项目中的web.xml文件就会在POM文件报错,并且也无法进行打包操作。这时我们需要在POM文件中添加一个WAR包插件用于抑制这个错误,源码如下:

<plugin>
	<groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.2</version> <configuration> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin>

 

经过三篇博文,我们介绍了基于纯Java代码的Spring容器和Web容器零配置的方法,希望能够在Spring的使用

http://my.oschina.net/devleon/blog/530953

 

相关文章
|
1月前
|
Java 开发工具
【Azure Storage Account】Java Code访问Storage Account File Share的上传和下载代码示例
本文介绍如何使用Java通过azure-storage-file-share SDK实现Azure文件共享的上传下载。包含依赖引入、客户端创建及完整示例代码,助你快速集成Azure File Share功能。
335 4
|
1月前
|
安全 Java 测试技术
《深入理解Spring》单元测试——高质量代码的守护神
Spring测试框架提供全面的单元与集成测试支持,通过`@SpringBootTest`、`@WebMvcTest`等注解实现分层测试,结合Mockito、Testcontainers和Jacoco,保障代码质量,提升开发效率与系统稳定性。
|
1月前
|
缓存 安全 Java
《深入理解Spring》过滤器(Filter)——Web请求的第一道防线
Servlet过滤器是Java Web核心组件,可在请求进入容器时进行预处理与响应后处理,适用于日志、认证、安全、跨域等全局性功能,具有比Spring拦截器更早的执行时机和更广的覆盖范围。
|
1月前
|
安全 前端开发 Java
《深入理解Spring》:现代Java开发的核心框架
Spring自2003年诞生以来,已成为Java企业级开发的基石,凭借IoC、AOP、声明式编程等核心特性,极大简化了开发复杂度。本系列将深入解析Spring框架核心原理及Spring Boot、Cloud、Security等生态组件,助力开发者构建高效、可扩展的应用体系。(238字)
|
1月前
|
Java 数据处理 API
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
为什么你的Java代码应该多用Stream?从循环到声明式的思维转变
234 115
|
1月前
|
安全 Java 编译器
为什么你的Java代码需要泛型?类型安全的艺术
为什么你的Java代码需要泛型?类型安全的艺术
171 98
|
1月前
|
Java 编译器 API
java最新版和java8的区别,用代码展示
java最新版和java8的区别,用代码展示
240 43
|
1月前
|
人工智能 监控 Java
零代码改造 + 全链路追踪!Spring AI 最新可观测性详细解读
Spring AI Alibaba 通过集成 OpenTelemetry 实现可观测性,支持框架原生和无侵入探针两种方式。原生方案依赖 Micrometer 自动埋点,适用于快速接入;无侵入探针基于 LoongSuite 商业版,无需修改代码即可采集标准 OTLP 数据,解决了原生方案扩展性差、调用链易断链等问题。未来将开源无侵入探针方案,整合至 AgentScope Studio,并进一步增强多 Agent 场景下的观测能力。
1364 34
|
1月前
|
Java 虚拟化 容器
(Java)Java里JFrame窗体的基本操作(容器布局篇-1)
容器 容器,我的理解是可以包容其他东西的玩意。它可以是一个盒子,可以是一个虚拟化的物品,可只要能包裹住其他存在质体的东西,那么都可以称作是容器。例如:JPanel组件和JScollPane组件两者都是容器也是组件。 既然有容器,那么容器中的布局就必不可少了。不然不规矩的摆放物品,人类看不习惯,我也看不习惯 ???? 本篇内容,将说明java JFrame窗体里容器中几类布局。 说明:所有在JFrame窗体里的容器布局都会使用setLayout()方法,采用的布局参数都将放进这个方法里 绝对布局 调用窗体容器
91 1
|
1月前
|
消息中间件 缓存 Java
Spring框架优化:提高Java应用的性能与适应性
以上方法均旨在综合考虑Java Spring 应该程序设计原则, 数据库交互, 编码实践和系统架构布局等多角度因素, 旨在达到高效稳定运转目标同时也易于未来扩展.
121 8
下一篇
oss云网关配置