service privider interface及servlet容器初始化回调——ServletContainerInitializer@HandlesTypes

1、spi简单说明
spi,即service privider interface,是jdk为厂商和插件提供的一种解耦机制。
spi的具体规范为:当服务的提供者,提供了服务接口的一种实现之后,在jar包的META-INF/services/目录里同时创建一个以服务接口命名的文件。该文件里就是实现该服务接口的具体实现类。而当外部程序装配这个模块的时候,就能通过该jar包META-INF/services/里的配置文件找到具体的实现类名,并通过反射机制实例化,完成模块的注入。 基于这样一个约定就能很好的找到服务接口的实现类,而不需要再代码里制定。jdk提供服务实现查找的一个工具类:java.util.ServiceLoader

2、spring-web中的具体应用
从servlet3.0开始,web容器启动时为提供给第三方组件机会做一些初始化的工作,例如注册servlet或者filtes等,servlet规范中通过ServletContainerInitializer实现此功能。每个框架要使用ServletContainerInitializer就必须在对应的jar包的META-INF/services 目录创建一个名为javax.servlet.ServletContainerInitializer的文件,文件内容指定具体的ServletContainerInitializer实现类,那么,当web容器启动时就会运行这个初始化器做一些组件内的初始化工作。

一般伴随着ServletContainerInitializer一起使用的还有HandlesTypes注解,通过HandlesTypes可以将感兴趣的一些类注入到ServletContainerInitializerde的onStartup方法作为参数传入。

spring-web的jar定义了一个具体的实现类,SpringServletContainerInitializer,并且在META-INF/services/目录下定义了如下文件:

这里写图片描述

文件的具体的内容为:org.springframework.web.SpringServletContainerInitializer。

3、SpringServletContainerInitializer
通过源码发现,配合注解@HandlesTypes它可以将其指定的Class对象作为参数传递到onStartup方法中。进而在onStartup方法中获取Class对象的具体实现类,进而调用实现类中的具体方法。SpringServletContainerInitializer类中@HandlesTypes指定的是Class对象是WebApplicationInitializer.Class。

利用这个机制,若实现WebApplicationInitializer这个接口,我们就可以自定义的注入Servlet,或者Filter,即可以不再依赖web.xml的配置。

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,您可以使用Python的Tkinter模块来设计这个界面,使用pymysql来连接MySQL数据库。以下是一个实现的示例代码: ```python import tkinter as tk import pymysql # 连接MySQL数据库 conn = pymysql.connect( host="localhost", user="root", password="password", database="database_name" ) # 创建一个窗口 root = tk.Tk() # 创建一个下拉选框 provider_list = [] cursor = conn.cursor() cursor.execute("SELECT providerID FROM provider") for row in cursor.fetchall(): provider_list.append(row[0]) cursor.close() provider_var = tk.StringVar(root) provider_option = tk.OptionMenu(root, provider_var, *provider_list) provider_option.pack() # 创建一个输入框 input_var = tk.StringVar(root) input_entry = tk.Entry(root, textvariable=input_var) input_entry.pack() # 创建一个提交按钮 def submit(): if input_var.get() == "": tk.messagebox.showerror("错误", "输入框不能为空!") else: cursor = conn.cursor() cursor.execute("INSERT INTO luru (providerID, value) VALUES (%s, %s)", (provider_var.get(), input_var.get())) conn.commit() cursor.close() tk.messagebox.showinfo("成功", "数据已成功录入!") submit_button = tk.Button(root, text="提交", command=submit) submit_button.pack() root.mainloop() # 关闭MySQL数据库连接 conn.close() ``` 您需要将`host`、`user`、`password`和`database`替换为您的MySQL连接信息和数据库名称。同时,您需要在MySQL中创建`provider`和`luru`表,并将`providerID`和`value`列设置为整型类型。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值