SpringMVC工程之非web部分代码复用,并独立运行

news2024/12/24 21:48:09

文章目录

  • 概述
    • 一、独立运行前提
    • 二、实现步骤
      • 1. WebApplicationContext上下文配置文件定义
      • 2.servletContext上下文配置文件
      • 3. 定义独立运行的类main方法
      • 4. 开发环境运行main结果
      • 5. class文件运行
      • 6. jar运行(推荐)

概述

springMVC是位于spring web端的一个框架,是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦。

下面我们以 https://gitee.com/00fly/java-code-frame/tree/master/springmvc-dbutils 为例来说明:
如何复用此SpringMVC工程的非web部分代码,并脱离web环境使之独立运行。

一、独立运行前提

  1. WebApplicationContext上下文、servletContext上下文配置文件分别定义
  2. 在非web应用程序中定义一个定时任务

二、实现步骤

1. WebApplicationContext上下文配置文件定义

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:cache="http://www.springframework.org/schema/cache"
	xmlns:task="http://www.springframework.org/schema/task"
	xsi:schemaLocation="http://www.springframework.org/schema/aop 
					    http://www.springframework.org/schema/aop/spring-aop.xsd
						http://www.springframework.org/schema/beans 
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/context 
						http://www.springframework.org/schema/context/spring-context.xsd
						http://www.springframework.org/schema/cache 
						http://www.springframework.org/schema/cache/spring-cache.xsd
						http://www.springframework.org/schema/tx 
						http://www.springframework.org/schema/tx/spring-tx.xsd
						http://www.springframework.org/schema/task
						http://www.springframework.org/schema/task/spring-task.xsd">

	<!-- 使用默认扫描方式, 排除controller类注解 -->
	<context:component-scan base-package="com.fly" use-default-filters="true">
		<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
		<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController" />
		<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
		<context:exclude-filter type="assignable" expression="com.fly.core.config.SwaggerConfig" />
	</context:component-scan>

	<!-- 配置 读取properties文件 jdbc.properties -->
	<context:property-placeholder location="classpath:jdbc.properties" />

	<!-- 数据库连接池 -->
	<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
		<!-- 基本属性 url username password driverClassName -->
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="driverClassName" value="${jdbc.driver}" />

		<!--配置初始化大小、最小、最多连接数 -->
		<property name="initialSize" value="1" />
		<property name="maxActive" value="100" />
		<property name="minIdle" value="5" />

		<!--配置获取连接等待超时时间 -->
		<property name="maxWait" value="3000" />

		<!--配置间隔多久进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
		<property name="timeBetweenEvictionRunsMillis" value="6000" />

		<!--配置一个连接在连接池中,最小生存的时间,单位是毫秒 -->
		<property name="minEvictableIdleTimeMillis" value="30000" />
		<property name="validationQuery" value="SELECT 'x'" />
		<property name="testWhileIdle" value="true" />
		<property name="testOnBorrow" value="false" />
		<property name="testOnReturn" value="false" />

		<!--打开PSCache,并且指定每个连接上的PSCache的大小 -->
		<property name="poolPreparedStatements" value="false" />
		<property name="maxPoolPreparedStatementPerConnectionSize" value="0" />

		<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
		<property name="filters" value="stat,wall,log4j2" />
	</bean>

	<!-- 事务管理 -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<!-- 启用定时任务扫描 -->
	<task:annotation-driven />
	
	<!-- queryRunner注入 -->
	<bean id="queryRunner" class="org.apache.commons.dbutils.QueryRunner">
		<constructor-arg ref="dataSource" />
	</bean>

	<!-- 定义jdbcTemplate -->
	<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
		<property name="dataSource" ref="dataSource" />
	</bean>
	
	<!-- 开启aop -->
	<aop:aspectj-autoproxy proxy-target-class="true" />
	
	<!-- 配置 Annotation 驱动,扫描@Transactional注解的类定义事务 -->
	<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
</beans>

2.servletContext上下文配置文件

spring-mvc.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc"
	xsi:schemaLocation="http://www.springframework.org/schema/aop 
						http://www.springframework.org/schema/aop/spring-aop.xsd
						http://www.springframework.org/schema/beans 
						http://www.springframework.org/schema/beans/spring-beans.xsd
						http://www.springframework.org/schema/context 
						http://www.springframework.org/schema/context/spring-context.xsd
						http://www.springframework.org/schema/mvc 
						http://www.springframework.org/schema/mvc/spring-mvc.xsd
						http://www.springframework.org/schema/tx 
						http://www.springframework.org/schema/tx/spring-tx.xsd">

	<!-- 仅扫描controller类注解,不使用默认扫描方式(默认方式会扫描类上的全部注解) -->
	<context:component-scan base-package="com.fly.**.controller" use-default-filters="false">
		<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
		<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.RestController" />
		<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice" />
	</context:component-scan>

	<context:component-scan base-package="com.fly.core.config" />

	<!-- 打开 JSR 303 -->
	<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
	<mvc:annotation-driven />
	
	<!-- 开启aop -->
	<aop:aspectj-autoproxy proxy-target-class="true" />

	<!-- 写法1:处理静态文件 -->
	<mvc:default-servlet-handler/>
	
	<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/views" />
		<property name="suffix" value=".jsp" />
	</bean>
</beans>

springmvc工程运行结果
在这里插入图片描述
在这里插入图片描述

3. 定义独立运行的类main方法

@Slf4j
public class MainRun
{
    /**
     * Main
     * 
     * @param args
     * @see [类、类#方法、类#成员]
     */
    public static void main(String[] args)
    {
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        Assert.notNull(context, "context is null");
        log.info("###### Application Started Success ######");
        Arrays.stream(context.getBeanDefinitionNames()).forEach(log::info);
    }
}

4. 开发环境运行main结果

在这里插入图片描述
至此可以看到,此代码至加载WebApplicationContext上下文完全可以脱离web环境运行。

5. class文件运行

在项目根目录下执行 mvn clean package会在target文件夹下生成如下文件:
在这里插入图片描述
进入target\classes文件

java -Djava.ext.dirs=../lib com.fly.MainRun

6. jar运行(推荐)

借助maven-shade-plugin插件(推荐)
pom-jar-extract.xml 插件部分配置


			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-shade-plugin</artifactId>
				<version>3.4.0</version>
				<executions>
					<execution>
						<phase>package</phase>
						<goals>
							<goal>shade</goal>
						</goals>
						<configuration>
							<minimizeJar>false</minimizeJar>
							<filters>
								<filter>
									<artifact>*:*</artifact>
								</filter>
							</filters>
							<transformers>
								<!-- 往MANIFEST文件中写入Main-Class是可执行包的必要条件。ManifestResourceTransformer可以轻松实现。 -->
								<transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
									<mainClass>com.fly.MainRun</mainClass>
								</transformer>
								<!-- AppendingTransformer 用来处理多个jar包中存在重名的配置文件的合并,尤其是spring -->
								<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
									<resource>META-INF/spring.handlers</resource>
								</transformer>
								<transformer implementation="org.apache.maven.plugins.shade.resource.AppendingTransformer">
									<resource>META-INF/spring.schemas</resource>
								</transformer>
							</transformers>
						</configuration>
					</execution>
				</executions>
			</plugin>
mvn clean package -f pom-jar-extract.xml

进入target执行

java -jar springmvc-dbutils.jar

运行结果
在这里插入图片描述
至此,我们已经实现了SpringMVC工程之非web部分代码复用,并借助插件打成Jar,实现独立运行!

有任何问题和建议,都可以向我提问讨论,大家一起进步,谢谢!

-over-

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1015650.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

BeanFactory和ApplicationContext功能

IDEA中双击shift&#xff0c;搜索一切 使用ctrl f12打开当前文件的结构图&#xff0c;显示了当前文件的层次结构&#xff0c;包括类、方法、变量等。 BeanFactory接口功能 表面上只有getBean实际上IOC、DI、以及Bean的生命周期的各种功能&#xff0c;都有其实现类&#xff08…

视频讲解|1033含sop的配电网重构(含风光可多时段拓展)

目录 1 主要内容 程序特点 讲解重点 2 视频链接 1 主要内容 该视频为含sop的配电网重构matlab代码讲解&#xff0c;对应资源下载链接为含sop的配电网重构&#xff08;含风光|可多时段拓展&#xff09;&#xff0c;程序主要内容是&#xff1a;针对含sop的配电网重构模型&…

【AI】推理引擎的模型转换模块

在推理引擎架构中&#xff0c;API 接口下来就是模型转换&#xff0c;狭义的模型转换是指将各种框架的模型转换为统一的格式&#xff0c;即模型格式转换&#xff1b;广义的模型转换则还包括图优化部分&#xff0c;因为不同的框架提供的算子不同&#xff0c;且类型太多&#xff0…

强大的 HTTP 请求工具:axios 打造前后端通信利器 | 开源日报 0916

axios/axios Stars: 101.2k License: MIT axios 是一个基于 Promise 的 HTTP 客户端&#xff0c;适用于浏览器和 node.js。 它具有以下核心优势&#xff1a; 支持在浏览器中进行 XMLHttpRequest在 node.js 中发起 http 请求支持 Promise API拦截请求和响应&#xff0c;并对数…

rust String 和 str 区别

1 String / &String String 类型的变量本质是一个存放在栈上的胖指针&#xff08;当然调用过程中&#xff0c;不用显示地按指针那样处理&#xff09;&#xff0c;共有三个字段&#xff1a; 1 pointer: 指向实际字符串值的地址&#xff0c;值是存放在堆上可变字节缓冲区&a…

驱动开发,stm32mp157a开发板的led灯控制实验(优化),使用ioctl函数,让write/read函数的专注读写功能

1.实验目的 编写LED灯的驱动&#xff0c;在应用程序中编写控制LED灯亮灭的代码逻辑实现LED灯功能的控制&#xff1b; 2.LED灯相关寄存器分析 LED1->PE10 LED1亮灭&#xff1a; RCC寄存器[4]->1 0X50000A28 GPIOE_MODER[21:20]->01 (输出) 0X50006000 GPIOE_ODR[10]-&g…

【Redis7】--3.Redis持久化

Redis持久化 Redis持久化(Redis persistence)是指将数据写入持久化存储&#xff0c;如固态硬盘(SSD) Redis提供了一系列持久化选项&#xff0c;这些包括&#xff1a; RDB(redis数据库)&#xff1a;RDB持久化方式能够在指定的时间间隔对数据进行快照存储AOF(追加文件)&#x…

java写一个用于生成雪花id的工具类

我们创建一个类 叫 SnowflakeIdGenerator 作为生成雪花id的工具类 然后 编写代码如下 public class SnowflakeIdGenerator {private static final long START_TIMESTAMP 1609459200000L; // 设置起始时间戳&#xff0c;可以根据需要进行调整private static final long WORKER…

助力新消费行业“三品”战略,从构建企业身份基础设施开始|身份云研究院

随着工业和信息化部、商务部等五部门联合发布《数字化助力消费品工业“三品”行动方案&#xff08;2022-2025年&#xff09;》&#xff08;以下简称《方案》&#xff09;逐步推行&#xff0c;加速实施数字化助力消费品工业“三品”战略成为消费行业重点任务&#xff0c;其中三品…

基于SpringbootShiro实现的CAS单点登录

概述 单点登录&#xff08;Single Sign On,SSO&#xff09;是一种登录管理机制&#xff0c;主要用于多系统集成&#xff0c;即在多个系统中&#xff0c;用户只需要到一个中央服务器登录一次即可访问这些系统中的任何一个&#xff0c;无须多次登录。常见的例子就是&#xff0c;…

java 封装一个将String类型转Long类型的函数

Long是一种超大类型的数字变量类型 但java无法直接生成这种数据 但我们可以封装一个函数 public Long getuniid(String number) {Long longNumber Long.parseLong(number);return longNumber; }这样 我们就可以传入一个字符串 然后将其转换为 long 然后我们调用这个函数 Sys…

Linux之ASCII码表查询tools(五十九)

简介&#xff1a; CSDN博客专家&#xff0c;专注Android/Linux系统&#xff0c;分享多mic语音方案、音视频、编解码等技术&#xff0c;与大家一起成长&#xff01; 优质专栏&#xff1a;Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 人生格言&#xff1a; 人生…

浅谈C++|类的成员

一.类对象作为类成员 类可以作为另一个类的成员 代码&#xff1a; #include <iostream> using namespace std; class phone { public:string shouji;phone(string shouji1) :shouji(shouji1) {cout << "phone的构造函数调用" << endl;}~phone() …

Obsidian配置

插件 1&#xff1a;Annotator pdf批注插件&#xff0c;使用方法&#xff1a;新建一个markdown文件&#xff0c;在文件的头部必须时开头添加以下内容&#xff1a; --- annotation-target: xxx.pdf ---2&#xff1a;Hidden Folder 用正则表达式隐藏文件夹的&#xff0c;我的设…

Spring实例化源码解析(一)

invokeBeanFactoryPostProcessors 前言 AbstractApplicationContext类的refresh方法是spring实例化流程的开始。本章主要是介绍invokeBeanFactoryPostProcessors(beanFactory)方法&#xff0c;对其内部源码进行详细分析。接下来就来看看这句简单的代码后面具体做了什么。Spri…

SpringSecurity学习 - 认证和授权

一般来说中大型的项目都是使用SpringSecurity 来做安全框架。小项目有Shiro的比较多&#xff0c;因为相比与SpringSecurity&#xff0c;Shiro的上手更加的简单。 一般Web应用的需要进行认证和授权。 认证&#xff1a;验证当前访问系统的是不是本系统的用户&#xff0c;并且要…

C语言实现通讯录 (附完整代码)

C语言实现通讯录 &#x1f340;实现一个通讯录&#xff1a;&#x1f340;通讯录的功能&#xff1a;&#x1f340;多文件实现&#x1f4ae;设计结构体——保存人的信息&#x1f4ae;初始通讯录&#x1f4ae;封装通讯录&#x1f4ae;define宏定义修改通讯录的最大容量初始化通讯录…

【机器学习】文本多分类

声明&#xff1a;这只是浅显的一个小试验&#xff0c;且借助了AI。使用的是jupyter notebook,所以代码是一块一块&#xff0c;从上往下执行的 知识点&#xff1a;正则删除除数字和字母外的所有字符、高频词云、混淆矩阵 参考&#xff1a;使用python和sklearn的中文文本多分类…

JDK9特性——语法、API的改变

文章目录 语法层次改变钻石操作符号语法升级try结构语法升级下划线命名标识符的使用限制 API层次的改变接口中的私有方法String底层存储结构变化Stream新增4个APIInputStream新增transferTo方法只读集合创建 语法层次改变 钻石操作符号语法升级 钻石操作符&#xff0c;就是我…

LeetCode(力扣)738. 单调递增的数字Python

LeetCode738. 单调递增的数字 题目链接代码 题目链接 https://leetcode.cn/problems/monotone-increasing-digits/description/ 代码 class Solution:def monotoneIncreasingDigits(self, n: int) -> int:strNum str(n)flag len(strNum)for i in range(len(strNum) - …