Wrapper做成服务
JavaServiceWrapper将java程序设置为服务
JavaServiceWrapper将java程序设置为服务 有时候我们希望我们java写的程序作为服务注册到系统中,Java Service Wrapper(下⾯简称wrapper)是⽬前较为流⾏的将Java程序部署成Windows服务的解决⽅案,本⽂将讨论如何使⽤wrapper把我们的程序打包成WIN服务! 主要作⽤有: 1.打包服务 2.设置JVM参数 3.所有的⽇志可以输出到指定⽂件0.准备需要注册为服务的程序public class MapTest {private static int i;public static void main(String[] args) {while (true) {try {System.out.println("访问次数:" + i++);HttpUtil.doGet("/qlqwjy/");Thread.sleep(2 * 1000);} catch (InterruptedException e) {e.printStackTrace();}}}}上⾯程序依赖的jar包:将上⾯程序也打成包:(使⽤eclipse打包或者直接Jdk⾃带的jar打包)1.下载serviceWrapper包下载后是⼀个压缩包,解压⽬录如下:2.开始注册⼀个简单的服务:1. 准备⼀个⽬录,例如我在桌⾯建了⼀个SW⽬录,并在⾥⾯新建如下结构的⽬录: 接下来全⽂的%EXAMPLE_HOME% 就是我新建的SW⽬录名称%EXAMPLE_HOME%\%EXAMPLE_HOME%\bin\%EXAMPLE_HOME%\conf\%EXAMPLE_HOME%\lang\%EXAMPLE_HOME%\lib\%EXAMPLE_HOME%\mylib\%EXAMPLE_HOME%\logs\如下:lang⽬录是存放⽀持其他语⾔的语⾔包,⼀般⽤不到2. 然后将我们下载的wrapper⽬录下的⽂件拷贝到我们上⾯建的⽬录:%WRAPPER_HOME%\bin\wrapper.exe -> %EXAMPLE_HOME%\bin\wrapper.exe%WRAPPER_HOME%\lib\wrapper.jar -> %EXAMPLE_HOME%\lib\wrapper.jar%WRAPPER_HOME%\lib\wrapper.dll -> %EXAMPLE_HOME%\lib\wrapper.dll%WRAPPER_HOME%\conf\wrapper.conf -> %EXAMPLE_HOME%\conf\wrapper.conf将⾃⼰程序打成的包以及⾃⼰程序依赖的包放到mylib:3.修改配置⽂件 %EXAMPLE_HOME%\conf\wrapper.conf#java.exe所在位置mand=C:\Program Files\Java\jdk1.7.0_80\bin\java.exe#⽇志级别mand.loglevel=INFO#主类⼊⼝,第⼀个mainClass是固定写法,是wrapper⾃带的,不可以写成⾃⼰的,如果写成⾃⼰的⼊⼝程序⾃⼰的程序需要实现wrapper的WrapperListener接⼝#parameter.1是⾃⼰的主程序⼊⼝所在类(从包名开始)wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleAppwrapper.app.parameter.1=MapTest#依赖的包,第⼀个是wrapper包,第⼆个是⾃⼰打的包以及程序依赖包wrapper.java.classpath.1=../lib/wrapper.jarwrapper.java.classpath.2=../mylib/*.jar#固定写法,依赖的wrapper的包wrapper.java.library.path.1=../lib#⽇志⽂件位置wrapper.logfile=../logs/wrapper.log#服务名称以及描述信息wrapper.console.title=Hello World Server=helloworldserverwrapper.displayname=Hello World Serverwrapper.description=Hello World Server注意: (1)上⾯的主类实际是:org.tanukisoftware.wrapper.WrapperSimpleApp,此类实现了WrapperListener接⼝。
Java_Service_Wrapper_代码部署
部署方法介绍一、前言该部署方法暂时没有考虑Web代码的部署,Web代码部署有更常用的方法,比如Tomcat、Apache等等。
本部署方法基于开源软件Java Service Wrapper,这是由一群人开发的Java虚拟机监控程序,并且提供了主流的操作系统下不同版本的Wrapper程序。
Wrapper运行只需要wrapper本身一个可执行程序(Windows下是PE文件、Linux下。
是各自不同的格式)和一个配置文件。
二、如何部署1.System Requirement①JRE (Java Runtime Environment)需要安装好Java运行环境,或者将安装好的JRE打包到Wrapper中(具体见示例)。
要求JRE1.5以上,并且支持要发布的代码版本(代码开发用的JRE是1.5则用1.5的JRE,1.6的则用1.6的JRE)2.Configuration配置Wrapper是一件比较简单的事情,大家不需要太担心。
这里只有一个文件需要配置,默认是conf/wrapper.conf文件。
在配置前,我们先准备点基础知识,然后看看配置好以后的好处,大家看到好处应该就不会惧怕了 。
开玩笑的啦。
图1是一个干净的wrapper目录结构图。
图 1 Wrapper目录结构图从图1中可以看到,wrapper结构很清晰,就是执行程序(bin/*)、配置文件(conf/wrapper.conf)和运行时支持库(lib/wrapper.dll, lib/wrapper.jar, lib/wrappertest.jar,其中wrappertest.jar是测试用的,真正发布时不需要,但是在部署时建议保留,以便测试排除是否是wrapper本身的问题)。
这里我们发布数据分拣中心的代码。
数据分拣中心代码打包成DataSorter.jar,该包要用到ant.jar等包(见图2),这里为了简单行事,将发布代码包以及运行时支持包(非JRE包)放入classes文件夹中。
Wrapper简介
Wrapper简介在实际开发过程中很多模块需要独⽴运⾏,他们并不会以web形式发布,传统的做法是将其压缩为jar包独⽴运⾏,这种形式简单易⾏也⽐较利于维护,但是⼀旦服务器重启或出现异常时,程序往往⽆法⾃⾏修复或重启。
解决服务器重启的传统做法是编写⼀段shell脚本随服务器启动⽽运⾏,但是这样做只是治标,那么我们想寻求⼀种“治本”的⽅式该怎么办呢?Java Service Wrapper就轻松⽽简单的为我们解决了这些问题。
"Java Service Wrapper"顾名思义,将我们的Java程序包装成系统服务,这样就可以随着系统的运⾏⽽⾃动运⾏,当然Java Service Wrapper(下⾯简称Wrapper)的功能绝不仅于此。
通过下载页⾯我们可以看到Wrapper⼏乎⽀持所有的系统环境,说明Wrapper在这⽅⾯还是很下⼯夫的,⽬前最新版本为3.5.20,我们选择Linux x86版本下载,解压后⽬录组成如下图所⽰:为了更直观的了解Wrapper的⽬录及⽂件结构,可以通过"tree"命令列出Wrapper的所有⽂件树,cmd控制台下输⼊命令:Cmd代码1. tree /f2.3. 显⽰⽬录结构如下:4. wrapper-linux-x86.5. │ jdoc.tar.gz //javadoc⽂件6. │ README_de.txt //说明7. │ README_en.txt //说明8. │ README_es.txt //说明9. │ README_ja.txt //说明10. │11. ├─bin //执⾏⽂件⽬录12. │ demoapp //⽰例程序13. │ testwrapper //测试程序14. │★wrapper //主程序(重要)15. │16. ├─conf //配置⽂件⽬录17. │ demoapp.conf //⽰例配置⽂件18. │★wrapper.conf //主配置⽂件(重要,⽂件名可修改)19. │20. ├─doc //说明⽂档⽬录21. │ index.html //⾸页22. │ revisions.txt //版本说明23. │ wrapper-community-license-1.1.txt //许可协议24. │25. ├─jdoc //javadoc⽂档⽬录26. │ index.html //⾸页27. │28. ├─lib //依赖类库⽬录29. │★libwrapper.so //wrapper linux⽂件(.so:⽤户层的动态库)30. │★wrapper.jar //wrapper主程序(重要)31. │ wrapperdemo.jar //⽰例程序32. │ wrappertest.jar //测试程序33. │34. ├─logs //⽇志⽬录35. │ wrapper.log //⽇志⽂件36. │37. └─src //源代码⽬录38. ├─bin //执⾏程序⽬录39. │★sh.script.in //shell脚本源代码(重要)40. └─conf //配置⽬录41. wrapper.conf.in //原始配置以下是官⽅给出的⼀些Wrapper的优点:(1) 使⽤我们的产品⽆须在你的程序中添加任何额外的代码。
KARAF学习笔记
KARAF读书笔记目录KARAF读书笔记 (1)一序 (2)1.1序篇感言 (2)1.2名词解释 (2)二KARAF简介 (3)2.1概念 (3)2.1.1KARAF简介 (3)2.1.2WRAPPER简介 (3)2.1.3守护进程 (4)2.1.4作用 (4)2.2环境 (4)2.2.1下载地址 (4)2.3参考资料 (4)2.3.1网络参考 (4)2.3.2书籍参考 (5)三服务化配置 (5)3.1WINDOWS系统服务化配置 (5)3.1.1手动配置 (5)3.1.2自动配置 (7)3.2LINUX系统服务化配置 (10)3.2.1手动配置 (10)3.2.2自动配置 (10)四KARAF控制台使用 (10)4.1介绍 (10)4.2SHELL模块 (11)4.2.1介绍 (11)4.2.2指令介绍 (11)五SSHD模块 (14)5.1介绍 (14)5.2SSH容器跳转 (15)5.2.1KARAF间跳转 (15)六LOG模块 (15)6.1介绍 (15)6.2KARAF.LOG (15)七KARAF其他功能介绍 (15)7.1目录结构 (15)7.2KARAF重置 (16)八KARAF子实例 (16)8.1子实例作用 (16)一序1.1 序篇感言KARAF是APACHE开源项目,是一款非常优季的OSGI容器,内部集成了很多优秀的功能,通过调研,该项目很适合用作自动化采集客户端使用……耘刈2015-12-23 1.2 名词解释名词说明备注控制台全部指在BIN目录下启动的karaf.bat打开的控制界面,下文中所有控制台都表示该界面。
二KARAF简介2.1 概念2.1.1KARAF简介Karaf是Apache旗下的一个开源项目.Karaf同时也是一个基于OSGi的运行环境,Karaf提供了一个轻量级的OSGi容器,可以用于部署各种组件,应用程序.Karaf提供了很多特性用于帮助开发者和用户更加灵活的部署应用,例如:热部署,动态配置,几种日志处理系统,本地系统集成,可编程扩展控制台,ssh远程访问,内置安装认证机制等等.同时Karaf作为一款成熟而且优秀的OSGi运行环境以及容器已经被诸多Apache项目作为基础容器,例如:Apache Geronimo, ApacheServiceMix, Fuse ESB,由此可见Karaf在性能,功能和稳定性上都是个不错的选择。
linux tcp_wrapper配置详解 成功
linux tcp_wrapper配置详解tcp_wrapper的原理Telnet、SSH、FTP、POP和SMTP等很多网络服务都会用到TCP Wrapper,它被设计为一个介于外来服务请求和系统服务回应的中间处理软件。
基本处理过程当系统接收到一个外来服务请求的时候,先由TCP Wrapper处理这个请求TCP Wrapper根据这个请求所请求的服务和针对这个服务所定制的存取控制规则来判断对方是否有使用这个服务的权限,如果有,TCP Wrapper 将该请求按照配置文件定义的规则转交给相应的守护进程去处理同时记录这个请求动作,然后自己就等待下一个请求的处理。
如果外部还有防火墙,当然要先通过防火墙tcp_wrapper是基于主机与服务的使用简单的配置文件来设置访问限制/etc/hosts.allow /etc/hosts.deny配置一旦被改变,立刻生效tcp_wrapper的配置访问控制判断顺序:访问是否被明确许可否则,访问是否被明确禁止如果都没有,默认许可通常tcp_wrapper没有配置,就是第三条,如果都没有,默认许可的配置文件许可用:/etc/hosts.allow 禁止用:/etc/hosts.deny 我的配置比较很/etc/hosts.deny 里我加入 ALL : ALL 表示所有都禁止/etc/hosts.allow 里我加入 vsftpd:192.168.56.1 表示我只开放vsftpd能够在192.168.56.1这个IP上登录这个原理有点像ISA的配置 ISA在装好的时候就是全禁的需要你自己逐个的开放才可以使用,这两种情况都是白名单优先黑名单被动tcp_wrapper很简单,要服务的模块支持tcp_wrapper ,才可以使用tcp_wrapper大家看吧,vsftpd的配置文件最后,明确配置tcp_wrappers=yes vim /etc/vsftpd/vsftpd.conf查看一个服务是否支持tcp_wrapper可以用一下命令看某个服务的执行文件是否调用tcp——wrapperldd `which vsftpd` | grep wrap。
winsw用法 -回复
winsw用法-回复Winsw(Windows service wrapper)是一个用于将Java应用程序封装为Windows服务的工具。
它可以在Windows操作系统上以服务的形式运行Java应用程序,提供了更好的稳定性和可靠性。
本文将一步一步回答Winsw的使用方法。
Winsw的下载和安装步骤1:打开Winsw的GitHub存储库页面。
在页眉中,点击“Code”按钮,然后选择“Download ZIP”选项。
这将下载Winsw的最新版本压缩文件。
步骤2:解压缩下载的ZIP文件,将其中的"winsw.exe"和"winsw.xml"文件复制到您的Java应用程序所在的目录。
Winsw的配置步骤3:打开"winsw.xml"文件,这是Winsw的配置文件。
您可以使用任何文本编辑器(例如Notepad++)打开该文件。
步骤4:在文件的开头,设置您的应用程序的名称和描述。
找到值为"YOUR_APP_NAME"和"YOUR_APP_DESCRIPTION"的标签,并将其替换为适当的值。
步骤5:接下来,设置应用程序的工作目录。
找到标签"workingdirectory",将其值设置为您的应用程序所在的目录路径。
步骤6:然后,设置Java路径。
找到标签"executable",将其值设置为您的Java安装路径。
如果你的Java路径已经在系统变量中设置了,可以将该标签值留空。
步骤7:接下来,设置Java虚拟机选项。
找到标签"arguments",添加任何您需要的Java虚拟机选项。
例如,您可以添加"-Xmx512m"以设置最大堆内存为512MB。
步骤8:找到标签"startmode",将其值设置为"Automatic"以在系统启动时自动启动您的应用程序。
MyBatis-Plus条件构造器Wrapper的用法
MyBatis-Plus条件构造器Wrapper的⽤法前⾔接⼝⽅法的参数中,会出现各种 Wrapper,⽐如 queryWrapper、updateWrapper 等。
Wrapper 的作⽤就是⽤于定义各种各样的条件(where)。
所以不管是查询、更新、删除都会⽤到 Wrapper。
如 QueryWrapper 是 Mybatis Plus 中⼀个条件拼装查询器,作⽤是让我们以 Java 对象的⽅式构建 where 之后的查询条件,不⽤直接写 SQL。
1. Wrapper的继承关系:Wrapper 条件构造抽象类-- AbstractWrapper 查询条件封装,⽤于⽣成 sql 中的 where 语句。
-- QueryWrapper Entity 对象封装操作类,⽤于查询。
-- UpdateWrapper Update 条件封装操作类,⽤于更新。
-- AbstractLambdaWrapper 使⽤ Lambda 表达式封装 wrapper-- LambdaQueryWrapper 使⽤ Lambda 语法封装条件,⽤于查询。
-- LambdaUpdateWrapper 使⽤ Lambda 语法封装条件,⽤于更新。
2. 常⽤条件⽐较⼤⼩: ( =, <>, >, >=, <, <= )eq(R column, Object val); // 等价于 =,例: eq("name", "⽼王") ---> name = '⽼王'ne(R column, Object val); // 等价于 <>,例: ne("name", "⽼王") ---> name <> '⽼王'gt(R column, Object val); // 等价于 >,例: gt("name", "⽼王") ---> name > '⽼王'ge(R column, Object val); // 等价于 >=,例: ge("name", "⽼王") ---> name >= '⽼王'lt(R column, Object val); // 等价于 <,例: lt("name", "⽼王") ---> name < '⽼王'le(R column, Object val); // 等价于 <=,例: le("name", "⽼王") ---> name <= '⽼王'范围:(between、not between、in、not in)between(R column, Object val1, Object val2); // 等价于 between a and b, 例: between("age", 18, 30) ---> age between 18 and 30notBetween(R column, Object val1, Object val2); // 等价于 not between a and b, 例: notBetween("age", 18, 30) ---> age not between 18 and 30in(R column, Object... values); // 等价于字段 IN (v0, v1, ...),例: in("age",{1,2,3}) ---> age in (1,2,3)notIn(R column, Object... values); // 等价于字段 NOT IN (v0, v1, ...), 例: notIn("age",{1,2,3}) ---> age not in (1,2,3)inSql(R column, Object... values); // 等价于字段 IN (sql 语句), 例: inSql("id", "select id from table where id < 3") ---> id in (select id from table where id < 3)notInSql(R column, Object... values); // 等价于字段 NOT IN (sql 语句)模糊匹配:(like)like(R column, Object val); // 等价于 LIKE '%值%',例: like("name", "王") ---> name like '%王%'notLike(R column, Object val); // 等价于 NOT LIKE '%值%',例: notLike("name", "王") ---> name not like '%王%'likeLeft(R column, Object val); // 等价于 LIKE '%值',例: likeLeft("name", "王") ---> name like '%王'likeRight(R column, Object val); // 等价于 LIKE '值%',例: likeRight("name", "王") ---> name like '王%'空值⽐较:(isNull、isNotNull)isNull(R column); // 等价于 IS NULL,例: isNull("name") ---> name is nullisNotNull(R column); // 等价于 IS NOT NULL,例: isNotNull("name") ---> name is not null分组、排序:(group、having、order)groupBy(R... columns); // 等价于 GROUP BY 字段, ...,例: groupBy("id", "name") ---> group by id,nameorderByAsc(R... columns); // 等价于 ORDER BY 字段, ... ASC,例: orderByAsc("id", "name") ---> order by id ASC,name ASCorderByDesc(R... columns); // 等价于 ORDER BY 字段, ... DESC,例: orderByDesc("id", "name") ---> order by id DESC,name DESChaving(String sqlHaving, Object... params); // 等价于 HAVING ( sql语句 ),例: having("sum(age) > {0}", 11) ---> having sum(age) > 11拼接、嵌套 sql:(or、and、nested、apply)or(); // 等价于 a or b,例:eq("id",1).or().eq("name","⽼王") ---> id = 1 or name = '⽼王'or(Consumer<Param> consumer); // 等价于 or(a or/and b),or 嵌套。
将Java程序注册成系统服务javaservicewrapper详解
将Java程序注册成系统服务javaservicewrapper详解看完这个文章不用看下面了:自已的模块######设置路径,可不设置,主要是java_home,如你已经在环境变量中设置了就不用了。
set.JAVA_HOME=C:\Program Files\Java\jdk1.6.0_06###调用 java.exe来执行你的程序的,引入java.exemand=%JAVA_HOME%/bin/java###这个是帮助类方式实现的醳本,先加载帮助类,再在第一个参数这里加载自已类的MAIL方法。
这个参数在最后一行设置,请你跳到最后一行查看。
# Java Main class.wrapper.java.mainclass=org.tanukisoftware.wrapper.Wrappe rSimpleApp##程序运行使用的其它包# Java Classpath (include wrapper.jar)wrapper.java.classpath.1=%JBOSS_HOME%/bin/run.jarwrapper.java.classpath.2=%JAVA_HOME%/lib/tools.jarwrapper.java.classpath.3=%JBOSS_HOME%/lib/wrapper.jar##程序运行的库,其实就是那个dll。
这里有32和64版的注意一下就行# Java Library Path (location of Wrapper.DLL or libwrapper.so) #For 32-bit architectureswrapper.java.library.path.1=%JBOSS_HOME%/bin/native/lib#For 64-bit architectures#wrapper.java.library.path.1=%JBOSS_HOME%/bin/native/li b64# Java Bits. On applicable platforms, tells the JVM to run in 32 or 64-bit mode.wrapper.java.additional.auto_bits=TRUE##若你在运行之前要进行的参数,若没有请忽略。
mybatis-plus中wrapper的用法实例详解
mybatis-plus中wrapper的⽤法实例详解⽬录⼀、条件构造器关系介绍条件构造器关系介绍:wapper介绍:⼆、项⽬实例1、根据主键或者简单的查询条件进⾏查询2、MyBatis-Plus还提供了Wrapper条件构造器,具体使⽤看如下代码:三、具体使⽤操作1、ge、gt、le、lt、isNull、isNotNull2、eq、ne3、between、notBetween4、allEq5、like、notLike、likeLeft、likeRight6、in、notIn、inSql、notinSql、exists、notExists7、or、and8、嵌套or、嵌套and9、orderBy、orderByDesc、orderByAsc10、last11、指定要查询的列12、set、setSql⽤到了wrapper,整理资料记录⼀下,以备后续复习。
⼀、条件构造器关系介绍条件构造器关系介绍:上图绿⾊框为抽象类abstract蓝⾊框为正常class类,可new对象黄⾊箭头指向为⽗⼦类关系,箭头指向为⽗类wapper介绍:Wrapper :条件构造抽象类,最顶端⽗类AbstractWrapper :⽤于查询条件封装,⽣成 sql 的 where 条件QueryWrapper : Entity 对象封装操作类,不是⽤lambda语法UpdateWrapper : Update 条件封装,⽤于Entity对象更新操作AbstractLambdaWrapper : Lambda 语法使⽤ Wrapper统⼀处理解析 lambda 获取 column。
LambdaQueryWrapper :看名称也能明⽩就是⽤于Lambda语法使⽤的查询WrapperLambdaUpdateWrapper : Lambda 更新封装Wrapper⼆、项⽬实例1、根据主键或者简单的查询条件进⾏查询/*** 通过单个ID主键进⾏查询*/@Testpublic void selectById() {User user = userMapper.selectById(1094592041087729666L);System.out.println(user);}/*** 通过多个ID主键查询public void selectByList() {List<Long> longs = Arrays.asList(1094592041087729666L, 1094590409767661570L);List<User> users = userMapper.selectBatchIds(longs);users.forEach(System.out::println);* 通过Map参数进⾏查询public void selectByMap() {Map<String, Object> params = new HashMap<>();params.put("name", "张⾬琪");List<User> users = userMapper.selectByMap(params);2、MyBatis-Plus还提供了Wrapper条件构造器,具体使⽤看如下代码:/*** 名字包含⾬并且年龄⼩于40* <p>* WHERE name LIKE '%⾬%' AND age < 40*/@Testpublic void selectByWrapperOne() {QueryWrapper<User> wrapper = new QueryWrapper();wrapper.like("name", "⾬").lt("age", 40);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}/*** 名字包含⾬* 年龄⼤于20⼩于40* 邮箱不能为空* WHERE name LIKE '%⾬%' AND age BETWEEN 20 AND 40 AND email IS NOT NULLpublic void selectByWrapperTwo() {QueryWrapper<User> wrapper = Wrappers.query();wrapper.like("name", "⾬").between("age", 20, 40).isNotNull("email");* 名字为王性* 或者年龄⼤于等于25* 按照年龄降序排序,年龄相同按照id升序排序* WHERE name LIKE '王%' OR age >= 25 ORDER BY age DESC , id ASCpublic void selectByWrapperThree() {wrapper.likeRight("name", "王").or().ge("age", 25).orderByDesc("age").orderByAsc("id");* 查询创建时间为2019年2⽉14* 并且上级领导姓王* WHERE date_format(create_time,'%Y-%m-%d') = '2019-02-14' AND manager_id IN (select id from user where name like '王%')public void selectByWrapperFour() {wrapper.apply("date_format(create_time,'%Y-%m-%d') = {0}", "2019-02-14").inSql("manager_id", "select id from user where name like '王%'");* 查询王姓* 并且年龄⼩于40或者邮箱不为空* WHERE name LIKE '王%' AND ( age < 40 OR email IS NOT NULL )public void selectByWrapperFive() {wrapper.likeRight("name", "王").and(qw -> qw.lt("age", 40).or().isNotNull("email"));* 并且年龄⼤于20 、年龄⼩于40、邮箱不能为空* WHERE name LIKE ? OR ( age BETWEEN ? AND ? AND email IS NOT NULL )public void selectByWrapperSix() {wrapper.likeRight("name", "王").or(qw -> qw.between("age", 20, 40).isNotNull("email"));* (年龄⼩于40或者邮箱不为空) 并且名字姓王* WHERE ( age < 40 OR email IS NOT NULL ) AND name LIKE '王%'public void selectByWrapperSeven() {wrapper.nested(qw -> qw.lt("age", 40).or().isNotNull("email")).likeRight("name", "王");* 查询年龄为30、31、32* WHERE age IN (?,?,?)public void selectByWrapperEight() {wrapper.in("age", Arrays.asList(30, 31, 32));* 查询⼀条数据* limit 1public void selectByWrapperNine() {wrapper.in("age", Arrays.asList(30, 31, 32)).last("limit 1");三、具体使⽤操作注意:以下条件构造器的⽅法⼊参中的column 均表⽰数据库字段1、ge、gt、le、lt、isNull、isNotNull@Testpublic void testDelete() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.isNull("name").ge("age", 12).isNotNull("email");int result = userMapper.delete(queryWrapper);System.out.println("delete return count = " + result);}SQL:UPDATE user SET deleted=1 WHERE deleted=0 AND name IS NULL AND age >= ? AND email IS NOT NULL2、eq、ne注意:seletOne返回的是⼀条实体记录,当出现多条时会报错@Testpublic void testSelectOne() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.eq("name", "Tom");User user = userMapper.selectOne(queryWrapper);System.out.println(user);}3、between、notBetween包含⼤⼩边界@Testpublic void testSelectCount() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.between("age", 20, 30);Integer count = userMapper.selectCount(queryWrapper);System.out.println(count);}SELECT COUNT(1) FROM user WHERE deleted=0 AND age BETWEEN ? AND ?4、allEq@Testpublic void testSelectList() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();Map<String, Object> map = new HashMap<>();map.put("id", 2);map.put("name", "Jack");map.put("age", 20);9queryWrapper.allEq(map);List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND name = ? AND id = ? AND age = ?5、like、notLike、likeLeft、likeRightselectMaps返回Map集合列表@Testpublic void testSelectMaps() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.notLike("name", "e").likeRight("email", "t");List<Map<String, Object>> maps = userMapper.selectMaps(queryWrapper);//返回值是Map列表maps.forEach(System.out::println);}SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND name NOT LIKE ? AND email LIKE ?6、in、notIn、inSql、notinSql、exists、notExistsin、notIn:notIn("age",{1,2,3})--->age not in (1,2,3)notIn("age", 1, 2, 3)--->age not in (1,2,3)inSql、notinSql:可以实现⼦查询例: inSql("age", "1,2,3,4,5,6")--->age in (1,2,3,4,5,6)例: inSql("id", "select id from table where id < 3")--->id in (select id from table where id < 3)SELECT id,name,age,email,create_time,update_time,deleted,version FROM user WHERE deleted=0 AND id IN (select id from user where id < 3) 7、or、and注意:这⾥使⽤的是 UpdateWrapper 不调⽤or则默认为使⽤ and 连@Testpublic void testSelectObjs() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();//queryWrapper.in("id", 1, 2, 3);queryWrapper.inSql("id", "select id from user where id < 3");List<Object> objects = userMapper.selectObjs(queryWrapper);//返回值是Object列表objects.forEach(System.out::println);}UPDATE user SET name=?, age=?, update_time=? WHERE deleted=0 AND name LIKE ? OR age BETWEEN ? AND ?8、嵌套or、嵌套and这⾥使⽤了lambda表达式,or中的表达式最后翻译成sql时会被加上圆括号@Testpublic void testUpdate1() {//修改值User user = new User();user.setAge(99);user.setName("Andy");//修改条件UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();userUpdateWrapper.like("name", "h").or().between("age", 20, 30);int result = userMapper.update(user, userUpdateWrapper);System.out.println(result);}UPDATE user SET name=?, age=?, update_time=?WHERE deleted=0 AND name LIKE ?OR ( name = ? AND age <> ? )9、orderBy、orderByDesc、orderByAsc@Testpublic void testUpdate2() {//修改值User user = new User();user.setAge(99);user.setName("Andy");//修改条件UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();userUpdateWrapper.like("name", "h").or(i -> i.eq("name", "李⽩").ne("age", 20));int result = userMapper.update(user, userUpdateWrapper);System.out.println(result);}SELECT id,name,age,email,create_time,update_time,deleted,versionFROM user WHERE deleted=0 ORDER BY id DESC10、last直接拼接到 sql 的最后注意:只能调⽤⼀次,多次调⽤以最后⼀次为准有sql注⼊的风险,请谨慎使⽤@Testpublic void testSelectListLast() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();st("limit 1");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}SELECT id,name,age,email,create_time,update_time,deleted,versionFROM user WHERE deleted=0 limit 111、指定要查询的列@Testpublic void testSelectListColumn() {QueryWrapper<User> queryWrapper = new QueryWrapper<>();queryWrapper.select("id", "name", "age");List<User> users = userMapper.selectList(queryWrapper);users.forEach(System.out::println);}SELECT id,name,age FROM user WHERE deleted=012、set、setSql最终的sql会合并 user.setAge(),以及 userUpdateWrapper.set() 和 setSql() 中的字段@Testpublic void testUpdateSet() {//修改值User user = new User();user.setAge(99);//修改条件UpdateWrapper<User> userUpdateWrapper = new UpdateWrapper<>();userUpdateWrapper.like("name", "h").set("name", "⽼李头")//除了可以查询还可以使⽤set设置修改的字段.setSql(" email = '123@'");//可以有⼦查询int result = userMapper.update(user, userUpdateWrapper);}UPDATE user SET age=?, update_time=?, name=?, email = '123@' WHERE deleted=0 AND name LIKE ?参考⽂档到此这篇关于mybatis-plus中wrapper的⽤法(详细)的⽂章就介绍到这了,更多相关mybatis-plus中wrapper⽤法内容请搜索以前的⽂章或继续浏览下⾯的相关⽂章希望⼤家以后多多⽀持!。
wrapper用法
wrapper用法Wrapper一种用于包装函数、方法、类和服务的设计模式,它最主要的功能是修改和调整包装对象的行为,通过改变包装对象的内部实现和附加额外功能,从而实现针对这些包装对象的灵活、高效的调整。
为了更好地理解和实现Wrapper,我们首先要了解它的两个基本概念:包装对象和Wrapper。
一、包装对象包装对象就是要被Wrapper装的对象,它可以是函数、方法、类和服务等。
包装对象的行为可以通过在Wrapper中实现额外的功能来改变和调整。
二、WrapperWrapper就是用于实现Wrapper能的类,它的功能可以用于修改和调整包装对象的行为,从而达到灵活、高效的改变和调整。
Wrapper中的包装模式可以分为两种:装饰器模式和代理模式。
装饰器模式使用Wrapper来修饰和装饰包装对象,可以实现对包装对象的修改和调整;代理模式则是通过Wrapper来代理包装对象,从而实现对包装对象的行为控制和修改。
三、使用Wrapper优势1.一接口:使用Wrapper可以把多个不同的对象和服务统一成一个统一的接口,从而实现更加灵活的操作和控制;2.调性强:Wrapper可以很好地支持扩展和动态调整,因为它们可以通过增加新的Wrapper来改变和调整包装对象的行为,从而实现更加灵活的操作和控制;3.块化:使用Wrapper可以实现更加灵活的模块化,在不改变原有对象和服务的基础上,通过增加新的Wrapper来实现复杂的模块化操作,从而实现更加灵活的操作和控制;4.率高:Wrapper的使用可以提高程序的效率,因为它可以利用现有的对象和服务,从而把复杂的操作集中到Wrapper中,而不必重新实现复杂的操作,从而极大地提高效率;5.领域:Wrapper可以跨越不同领域之间的操作,因为它可以利用现有的类和服务,从而实现复杂的操作,从而实现跨领域的操作和控制。
总之,Wrapper法非常有用,它可以把多个不同的类和服务统一成一个统一的接口,可以有效地改变和调整包装对象的行为,从而实现更加灵活的操作和控制,而且可以跨越不同领域之间的操作,从而实现跨领域的操作和控制,为程序的实现提供了可能性和便利性。
Pure-ftpd服务安装设置
前言:FTP的工作方式FTP支持两种模式,一种方式叫做Standard (也就是PORT方式,主动方式),一种是Passive (也就是PASV,被动方式)。
Standard模式FTP的客户端发送PORT 命令到FTP服务器。
Passive模式FTP的客户端发送PASV命令到FTP Server。
下面介绍一个这两种方式的工作原理:Port模式FTP 客户端首先和FTP服务器的TCP 21端口建立连接,通过这个通道发送命令,客户端需要接收数据的时候在这个通道上发送PORT命令。
PORT命令包含了客户端用什么端口接收数据。
在传送数据的时候,服务器端通过自己的TCP 20端口连接至客户端的指定端口发送数据。
FTP server必须和客户端建立一个新的连接用来传送数据。
Passive模式在建立控制通道的时候和Standard模式类似,但建立连接后发送的不是Port命令,而是Pasv命令。
FTP服务器收到Pasv命令后,随机打开一个临时端口(也叫自由端口,端口号大于1023小于65535)并且通知客户端在这个端口上传送数据的请求,客户端连接FTP服务器此端口,然后FTP服务器将通过这个端口进行数据的传送,这个时候FTP server 不再需要建立一个新的和客户端之间的连接。
很多防火墙在设置的时候都是不允许接受外部发起的连接的,所以许多位于防火墙后或内网的FTP 服务器不支持PASV模式,因为客户端无法穿过防火墙打开FTP服务器的高端端口;而许多内网的客户端不能用PORT模式登陆FTP服务器,因为从服务器的TCP 20无法和内部网络的客户端建立一个新的连接,造成无法工作。
在Ubuntu中pure-ftpd是什么样Ubuntu/Debian 提供了三个不同的Pure-FTPd 的deb 安装包,分别是pure-ftpd、pure-ftpd-ldap 和pure- ftpd-mysql,其中ldap 和mysql 分别表示Pure-FTPd 跟ldap 和mysql 集成,另外这三个包都依赖于pure-ftpd-common。
Wrapper配置详解及高级应用
Wrapper配置详解及⾼级应⽤将⼀个简单的程度如HelloWorld 的应⽤包装秤Wrapper 服务并不复杂,甚⾄可以认为⾮常简单。
但是实际项⽬应⽤过程中我们的程序⼀般较庞⼤,运⾏环境也较复杂。
通过Wrapper 配置⽂件的分析与配置进⼀步了解构建Wrapper 服务需要注意的关键点及重要部分。
⾸先,打开conf ⽂件夹下的wrapper.conf配置⽂件,此配置⽂件时Wrapper 的主配置⽂件也是关键配置⽂件,下⾯开始⼀项⼀项的开始分析。
1.⽂件编码及⼦配置⽂件⽂件头部包含了配置⽂件编码格式,⼦配置⽂件等相关信息,如下所⽰:#⽂件编码,每个配置⽂件起始位置必须指定该⽂件的编码格式encoding=UTF-8# 如果包含配置⽂件出现问题可以使⽤debug调试模式,去掉⼀个"#",格式为#include.debug#include.debug# 包含⼦配置⽂件,可以是配置信息也可以是许可信息include ../conf/wrapper-license.confinclude ../conf/wrapper2.conf# 是否开启许可⽂件debug模式wrapper.license.debug=TRUE通过⼦配置⽂件的配置可以使主配置⽂件关联最多10级⼦配置,例如:wrapper.conf 包含 wrapper2.conf ,wrapper2.conf 包含wrapper3.conf ..... wrapper9.conf 包含wrapper10.conf,⽂件结构如下:wrapper.conf|-wrapper2.conf|-wrapper3.conf.....|-wrapper9.conf|-wrapper10.conf也就是说配置⽂件嵌套层级最⼤可达10级,引⽤⼀张官⽅图⽚可以很好的说明:如果⼦配置⽂件不存在时,那么它将被忽略,不会导致程序运⾏错误。
2.Wrapper 语⾔设置通过这两项的设置可以指定Wrapper 的语⾔种类,可以在Wrapper 官⽹下到这些语⾔包⽀持,⽬前不⽀持中⽂。
Java+Service+Wrapper使用说明
Java Service Wrapper使用说明具体的使用步骤:1. 将下载的Java Service Wrapper包解压到本地,目录为{WRAPPER_HOME};2. 服务应用程序名为[MyServApp],在目录C:\MyServApp下建立bin、conf、logs、lib目录;并把你的已有应用程序如NioBlockingServer.class拷贝到该目录下;3. 将{WRAPPER_HOME}\src\bin\下文件拷贝到MyServApp目录下,并重命名。
{WRAPPER_HOME}\bin\Wrapper.exe -> C:\ MyServApp \bin\Wrapper.exe {WRAPPER_HOME}\src\bin\App.bat.in -> C:\ MyServApp\bin\MyApp.bat {WRAPPER_HOME}\src\bin\InstallApp-NT.bat.in ->C:\MyServApp\bin\InstallMyApp-NT.bat{WRAPPER_HOME}\src\bin\UninstallApp-NT.bat.in -> C:\MyServApp\bin\UninstallMyApp-NT.bat4. 将{WRAPPER_HOME}\lib下的以下文件拷贝到C:\ MyServApp \lib目录下{WRAPPER_HOME}\lib\Wrapper.DLL{WRAPPER_HOME}\lib\wrapper.jar5. 将{WRAPPER_HOME}\src\conf\wrapper.conf.in拷贝到C:\ MyServApp\conf目录下并命名为wrapper.conf;并修改wrapper.conf文件,在其中配置您的应用服务。
主要修改以下几项即可:#你的JVM位置:mand=D:\Sun\j2sdk1.4.0_03\bin\java#运行参数:如:wrapper.java.additional.1==run.bat#classpath:wrapper.java.classpath.1=../lib/wrapper.jarwrapper.java.classpath.2=../bin/.# Java Library Path (location of Wrapper.DLL or libwrapper.so) wrapper.java.library.path.1=../lib#MAIN CLASS 此处决定了使用Java Service Wrapper的方式wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp#你的Java应用类wrapper.app.parameter.1= NonBlockingServer# 服务名=NB# Display name of the servicewrapper.ntservice.displayname=Nio Nonblocking Server# 服务描述wrapper.ntservice.description=Nio Nonblocking Server其他的配置根据你的需要改变即可6. 对以上配置的MyApp.bat进行测试,运行MyApp.bat,就像在Console窗口下运行Tomcat一样;7. 对以上配置的服务进行测试,运行C:\MyServApp\bin\InstallMyApp-NT.bat将把你的应用(此处为NioBlockingServer)安装到Win32系统服务中了。
H2数据库使用
H2数据库使用LifeBa文章如未注明转载均为原创。
转载请注明:转自LifeBa,谢谢合作:) 本文永久链接:/arch/h2_database_demo.htmlH2数据库介绍常用的开源数据库:H2,Derby,HSQLDB,MySQL,PostgreSQL。
其中H2,HSQLDB 类似,十分适合作为嵌入式数据库使用,其它的数据库大部分都需要安装独立的客户端和服务器端。
H2的优势:1、h2采用纯Java编写,因此不受平台的限制。
2、h2只有一个jar文件,十分适合作为嵌入式数据库试用。
3、性能和功能的优势H2比HSQLDB的最大的优势就是h2提供了一个十分方便的web控制台用于操作和管理数据库内容,这点比起HSQLDB的swing和awt控制台实在好用多了。
H2和各数据库特征比较。
准备工作1、h2-2011-04-04.zip 下载地址:/html/download.html2、解压文件,这里以%H2_HOME%表示为解压的文件目录。
运行%H2_HOME%/bin/h2.bat 将会自动打开下面网址。
(请确认是否安装了jdk,并设置了JAVA_HOME环境变量) http://192.168.140.1:8082/login.jsp?jsessionid=244e36a683f97f0d4f3b000f33530ed13、点击connect ,登录。
4、执行上图中红色部分sql语句,成功创建test表。
因为没有指定数据库文件位置,会自动输出到输出到C:/Users/Administrator下。
H2文件结构%H2_HOME%-h2-binh2-1.3.154.jar //jar包h2.bat //Windows控制台启动脚本h2.sh //Linux控制台启动脚本h2w.bat //Windows控制台启动脚本(不带黑屏窗口)+docs 帮助文档+service //通过wrapper包装成服务。
Request的包装类HttpServletRequestWrapper的使用说明
Request的包装类HttpServletRequestWrapper的使⽤说明⽬录Request的包装类HttpServletRequestWrapper使⽤⼤致的意思是:上述⽅案解决了HttpServletRequestWrapper和HttpServletResponseWrapper使⽤时的坑WrapperRequest和WrapperResponse的使⽤这⾥涉及到的坑坑1坑2解决问题问题延伸Request的包装类HttpServletRequestWrapper使⽤在使⽤zuul进⾏鉴权的时候,我们希望从请求Request中获取输⼊流,解析⾥⾯的内容,奈何InputStream只能被读取⼀次。
为啥呢?源码⾥是这样说的:public int read(byte[] b,int off, int len) Reads up to len bytes of data into an array of bytes from this input stream. Ifpos equals count, then -1 is returned to indicate end of file.Otherwise, the number k of bytes read is equal to the smaller of len and count-pos.If k is positive, then bytes buf[pos] through buf[pos+k-1] are copied into b[off] through b[off+k-1] in the manner performed by System.arraycopy. The value k is added into pos and k is returned. ⼤致的意思是:在InputStream读取的时候,会有⼀个pos指针,它指⽰每次读取之后下⼀次要读取的起始位置。
Dubbo扩展机制(三)Wrapper【代理】
Dubbo扩展机制(三)Wrapper【代理】⼀、前⾔Dubbo内核dubbo所有功能都是基于dubbo内核之上完成的,dubbo内核由四部分构成,分别为SPI、Adaptive、Wrapper、Activate。
⽽dubbo的内核设计原则,也是我们所熟悉的aop,ioc与动态编译compiler,这些称之为dubbo的内核原理。
Wrapper机制即扩展点⾃动包装。
Wrapper 类同样实现了扩展点接⼝,但是 Wrapper 不是扩展点的真正实现。
它的⽤途主要是⽤于从 ExtensionLoader 返回扩展点时,包装在真正的扩展点实现外。
即从 ExtensionLoader 中返回的实际上是 Wrapper 类的实例,Wrapper 持有了实际的扩展点实现类。
扩展点的 Wrapper 类可以有多个,也可以根据需要新增。
通过 Wrapper 类可以把所有扩展点公共逻辑移⾄ Wrapper 中。
新加的 Wrapper 在所有的扩展点上添加了逻辑,有些类似 AOP,即Wrapper 代理了扩展点。
Wrapper的规范Wrapper 机制不是通过注解实现的,⽽是通过⼀套 Wrapper 规范实现的。
Wrapper 类在定义时需要遵循如下规范:该类要实现 SPI 接⼝该类中要有 SPI 接⼝的引⽤该类中必须含有⼀个含参的构造⽅法且参数只能有⼀个类型为SPI借⼝在接⼝实现⽅法中要调⽤ SPI 接⼝引⽤对象的相应⽅法该类名称以 Wrapper 结尾⼆、使⽤⽰例未使⽤Wrapper之前:@SPI("ali") // 默认的值⽀付宝⽀付public interface Pay {// 接⼝的⽅法需要添加这个注解,在测试代码中,参数⾄少要有⼀个URL类型的参数@Adaptive({"paytype"}) // 付款⽅式void pay(URL url);}public class AliPay implements Pay {@Overridepublic void pay(URL url) {System.out.println("使⽤⽀付宝⽀付");}}public class WechatPay implements Pay {@Overridepublic void pay(URL url) {System.out.println("使⽤微信⽀付");}}在/dubbo-common/src/main/resources/META-INF/services/com.test.Pay⽂件下添加内容如下:wechat = com.test.WechatPayali = com.test.AliPaypublic static void main(String[] args) {ExtensionLoader<Pay> loader = ExtensionLoader.getExtensionLoader(Pay.class);Pay pay = loader.getAdaptiveExtension();pay.pay(URL.valueOf("http://localhost:9999/xxx")); // 使⽤⽀付宝⽀付pay.pay(URL.valueOf("http://localhost:9999/xxx?paytype=wechat")); // 使⽤微信⽀付}上述⽰例是原Adaptive使⽤⽰例,在使⽤Wrapper之后:⾸先要添加⼀个Wrapper类并在/dubbo-common/src/main/resources/META-INF/services/com.test.Pay⽂件下追加“xxx = com.test.PayWrapper1”(1)代理模式public class PayWrapper1 implements Pay {Pay pay;public PayWrapper1(Pay pay) {this.pay = pay;}@Overridepublic void pay(URL url) {System.out.println("pay before...");pay.pay(url);System.out.println("pay after...");}}执⾏上⾯main⽅法,得出如下结果:pay before...使⽤⽀付宝⽀付pay after...pay before...使⽤微信⽀付pay after...由此可见Wrapper是⼀个AOP功能(2)责任链模式我们还可以给它添加⼀个Wrapper2类,如下所⽰public class PayWrapper2 implements Pay {Pay pay;public PayWrapper2(Pay pay) {this.pay = pay;}@Overridepublic void pay(URL url) {System.out.println("-----pay before...");pay.pay(url);System.out.println("-----pay after...");}}并追加xxx2 = com.test.PayWrapper2输出的结果如下:-----pay before...pay before...使⽤⽀付宝⽀付pay after...-----pay after...执⾏顺序先执⾏2,再执⾏1三、源码分析上⾯main⽅法等同于public static void main(String[] args) {URL url = URL.valueOf("http://localhost:9999/xxx");String extName = url.getParameter("paytype", "ali");System.out.println(extName); // aliExtensionLoader<Pay> loader = ExtensionLoader.getExtensionLoader(Pay.class); Pay extension = (Pay) loader.getExtension(extName);// extension返回的结果为PayWrapper1extension.pay(url);}Wrapper功能实现分为两个部分⼀个是加载Extension时会把Wrapper类放⼊缓存中;另⼀部分取得服务提供者实例时,将装配过的Wrapper类返回我们先看第⼀部分,加载Wrapper类// 维护⼀个线程安全的HashSet来存放Wrappertry {// 尝试取得参数类型为SPI接⼝类型的构造函数,即判断该类是否是Wrapper类,如果不是会抛出异常;如果是,继续执⾏,并添加到cache中// 上⾯定义的Wrapper类如果有构造,则表⽰是⼀个真正的Wrapperclazz.getConstructor(type);Set<Class<?>> wrappers = cachedWrapperClasses;// 通过上⾯取得ExtensionLoader的代码你需要知道,每⼀个SPI接⼝都有⼀个ExtensionLoader,// 所以这⾥⾯的缓存也是每⼀个SPI接⼝都有他的Wrapper缓存,⽣命周期和loader的⽣命周期⼀致if (wrappers == null) {cachedWrapperClasses = new ConcurrentHashSet<Class<?>>();wrappers = cachedWrapperClasses;}// 这⾥cachedWrapperClasses和wrappers⽤的是同⼀个对象地址,所以相当于往cachedWrapperClasses添加元素wrappers.add(clazz);}第⼆部分则是组装Wrapper类通过getExtension⽅法中调⽤了createExtension⽅法,createExtension会循环遍历,通过wrapperClass.getConstructor(type).newInstance(instance) 将wrapper构造注⼊private T createExtension(String name) {Class<?> clazz = getExtensionClasses().get(name);if (clazz == null) {throw findException(name);}try {T instance = (T) EXTENSION_INSTANCES.get(clazz);if (instance == null) {EXTENSION_INSTANCES.putIfAbsent(clazz, (T) clazz.newInstance());instance = (T) EXTENSION_INSTANCES.get(clazz);}injectExtension(instance);Set<Class<?>> wrapperClasses = cachedWrapperClasses;// cache中是否存在wrapper类,如果存在,遍历,最后返回wrapper这个实例if (wrapperClasses != null && wrapperClasses.size() > 0) {for (Class<?> wrapperClass : wrapperClasses) {// 注册扩展,返回 wrapperClass.getConstructor(type).newInstance(instance) 实例instance = injectExtension((T) wrapperClass.getConstructor(type).newInstance(instance));}}return instance;} catch (Throwable t) {throw new IllegalStateException("Extension instance(name: " + name + ", class: " +type + ") could not be instantiated: " + t.getMessage(), t);}}injectExtension 只有⼀个逻辑,就是判断是否有set⽅法,然后属性注⼊private T injectExtension(T instance) {try {if (objectFactory != null) {for (Method method : instance.getClass().getMethods()) {if (method.getName().startsWith("set")&& method.getParameterTypes().length == 1&& Modifier.isPublic(method.getModifiers())) {Class<?> pt = method.getParameterTypes()[0];try {String property = method.getName().length() > 3 ? method.getName().substring(3, 4).toLowerCase() + method.getName().substring(4) : ""; Object object = objectFactory.getExtension(pt, property);if (object != null) {method.invoke(instance, object);}} catch (Exception e) {logger.error("fail to inject via method " + method.getName()+ " of interface " + type.getName() + ": " + e.getMessage(), e);}}}}} catch (Exception e) {logger.error(e.getMessage(), e);}return instance;}四、在Dubbo中的应⽤以 ProtocolFilterWrapper为例,在 dubbo-rpc/dubbo-rpc-api/src/main/resources/META-INF/dubbo/internal/org.apache.dubbo.rpc.Protocol filter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapperlistener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrappermock=com.alibaba.dubbo.rpc.support.MockProtocol当服务提供者启动时,ServiceConfig开始执⾏onApplicationEvent⽅法,并开始执⾏服务导出public class ServiceConfig<T> extends AbstractServiceConfig {private static final Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getAdaptiveExtension();@SuppressWarnings({"unchecked", "rawtypes"})private void exportLocal(URL url) {if (!Constants.LOCAL_PROTOCOL.equalsIgnoreCase(url.getProtocol())) {// 组装URLURL local = URL.valueOf(url.toFullString()) // 常量值为injvm,在执⾏wrapper链时⽤到.setProtocol(Constants.LOCAL_PROTOCOL).setHost(LOCALHOST).setPort(0);ServiceClassHolder.getInstance().pushServiceClass(getServiceClass(ref));// protocol,Protocol$AdaptiveExporter<?> exporter = protocol.export(proxyFactory.getInvoker(ref, (Class) interfaceClass, local));exporters.add(exporter);("Export dubbo service " + interfaceClass.getName() + " to local registry");}}}Protocol$Adaptive 类如下(简化版)import mon.extension.ExtensionLoader;public class Protocol$Adpative implements Protocol {public void destroy() {// throw Exception}public int getDefaultPort() {// throw Exception}public Invoker refer(Class arg0, URL arg1) throws RpcException {if (arg1 == null)throw new IllegalArgumentException("url == null");URL url = arg1;String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );if(extName == null)// throw ExceptionProtocol extension = (Protocol)ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);return extension.refer(arg0, arg1);}public Exporter export(Invoker arg0) throws RpcException {if (arg0 == null)// throw Exceptionif (arg0.getUrl() == null)// throw ExceptionURL url = arg0;String extName = ( url.getProtocol() == null ? "dubbo" : url.getProtocol() );if(extName == null)// throw ExceptionProtocol extension = (Protocol)ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);return extension.export(arg0);}}通过如下两⾏代码String extName = (url.getProtocol() == null ? "dubbo" : url.getProtocol()); // dubboProtocol extension = (Protocol) ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(extName);通过扩展名,我们可以在/META-INF/dubbo/internal/com.alibaba.dubbo.rpc.Protocol ⽂件分析出registry=com.alibaba.dubbo.registry.integration.RegistryProtocoldubbo=com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocolfilter=com.alibaba.dubbo.rpc.protocol.ProtocolFilterWrapper # Wrapperlistener=com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper # Wrappermock=com.alibaba.dubbo.rpc.support.MockProtocolinjvm=com.alibaba.dubbo.rpc.protocol.injvm.InjvmProtocol # 在ServiceConfig 组装过这个协议名称rmi=com.alibaba.dubbo.rpc.protocol.rmi.RmiProtocolhessian=com.alibaba.dubbo.rpc.protocol.hessian.HessianProtocolcom.alibaba.dubbo.rpc.protocol.http.HttpProtocolcom.alibaba.dubbo.rpc.protocol.webservice.WebServiceProtocolthrift=com.alibaba.dubbo.rpc.protocol.thrift.ThriftProtocolmemcached=com.alibaba.dubbo.rpc.protocol.memcached.MemcachedProtocolredis=com.alibaba.dubbo.rpc.protocol.redis.RedisProtocol在没有Wrapper的情况下,得到的扩展类为com.alibaba.dubbo.rpc.protocol.dubbo.DubboProtocol在有Wrarpper的情况下,得到的是最后的⼀个Wrapper,即com.alibaba.dubbo.rpc.protocol.ProtocolListenerWrapper 所以下⾯就调⽤ProtocolListenerWrapper中export⽅法public class ProtocolListenerWrapper implements Protocol {public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {return protocol.export(invoker);}return new ListenerExporterWrapper<T>(protocol.export(invoker),Collections.unmodifiableList(ExtensionLoader.getExtensionLoader(ExporterListener.class).getActivateExtension(invoker.getUrl(), Constants.EXPORTER_LISTENER_KEY)));}}根据Wrapper责任链模式的特点,接下来执⾏ ProtocolFilterWrapperpublic class ProtocolFilterWrapper implements Protocol {public <T> Exporter<T> export(Invoker<T> invoker) throws RpcException {if (Constants.REGISTRY_PROTOCOL.equals(invoker.getUrl().getProtocol())) {return protocol.export(invoker);}return protocol.export(buildInvokerChain(invoker, Constants.SERVICE_FILTER_KEY, Constants.PROVIDER));}}再接下来执⾏ injvm 对应的InjvmProtocol类中的export⽅法。
HttpServletRequestWrapper的应用(对所有请求进行处理例如编码去空格)
HttpServletRequestWrapper的应用(对所有请求进行处理例如编码去空格)public class ParameterRequestWrapper extends HttpServlet RequestWrapper {/*** 请求参数*/private Map<String, String[]> params = new HashMap<Stri ng, String[]>();/**** 构造函数:** @param request HttpServletRequest*/public ParameterRequestWrapper(HttpServletRequest requ est) {// 将request交给父类,以便于调用对应方法的时候,将其输出,其实父亲类的实现方式和第一种new的方式类似super(request);// 将参数表,赋予给当前的Map以便于持有request中的参数this.params.putAll(request.getParameterMap());}/**** 构造函数:重载一个构造方法** @param request HttpServletRequest* @param extendParams Map<String, Object>*/public ParameterRequestWrapper(HttpServletRequest requ est, Map<String, Object> extendParams) {this(request);// 这里将扩展参数写入参数表addAllParameters(extendParams);}/**** 功能描述:重写getParameter,代表参数从当前类中的map获取** @author :* 创建日期:2014年1月7日下午4:54:53** @param name 参数名称* @return** 修改历史:(修改人,修改时间,修改原因/内容)*/@Overridepublic String getParameter(String name) {String[] values = params.get(name);if (values == null || values.length == 0) {return null;}return values[0];}/**** 功能描述:重写getParameter,代表参数从当前类中的map获取** @author :* 创建日期:2014年1月7日下午4:55:14** @param name 参数名称* @return** 修改历史:(修改人,修改时间,修改原因/内容)*/@Overridepublic String[] getParameterValues(String name) {return params.get(name);}/**** 功能描述:增加多个参数** @author :* 创建日期:2014年1月7日下午4:54:20** @param otherParams Map<String, Object>** 修改历史:(修改人,修改时间,修改原因/内容)*/public void addAllParameters(Map<String, Object> otherPa rams) {for(Map.Entry<String, Object> entry : otherParams.entrySet ()) {addParameter(entry.getKey(), entry.getValue());}}/**** 功能描述:增加参数** @author :创建日期:2014年1月7日下午4:53:46** @param name 参数名称* @param value 参数值** 修改历史:(修改人,修改时间,修改原因/内容)*/public void addParameter(String name, Object value) {if (value != null) {if (value instanceof String[]) {params.put(name, (String[]) value);} else if (value instanceof String) {params.put(name, new String[] { (String) value });} else {params.put(name, new String[] { String.valueOf(value) });}}}/**** 功能描述:重写getParameterMap,代表参数从当前类中的map获取** @author :创建日期:2014年1月7日下午4:53:46** @return Map<String, String[]>** 修改历史:(修改人,修改时间,修改原因/内容)*/@Overridepublic Map<String, String[]> getParameterMap(){return params;}}public class ParameterRequestFilter implements Filter {@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {ParameterRequestWrapper requestWrapper = new Paramet erRequestWrapper((HttpServletRequest)req);// 获取请求参数Map<String, String[]> paramsMap = requestWrapper.getPa rameterMap();if(paramsMap != null && paramsMap.size() > 0){// 遍历请求参数Mapfor(Entry<String, String[]> entry:paramsMap.entrySet()){String[] values = entry.getValue();if(values != null && values.length > 0){String[] trimValues = new String[values.length];for(int index = 0; index < values.length; index++){trimValues[index] = StringUtil.trim(values[index]);}entry.setValue(trimValues);}}}chain.doFilter(requestWrapper, res);}@Overridepublic void init(FilterConfig arg0) throws ServletException { }}。
H2数据库使用详解
H2数据库使⽤详解H2最完整的资料下载地址:H2数据库使⽤H2数据库介绍常⽤的开源数据库:H2,Derby,HSQLDB,MySQL,PostgreSQL。
其中H2,HSQLDB类似,⼗分适合作为嵌⼊式数据库使⽤,其它的数据库⼤部分都需要安装独⽴的客户端和服务器端。
H2的优势:1、h2采⽤纯Java编写,因此不受平台的限制。
2、h2只有⼀个jar⽂件,⼗分适合作为嵌⼊式数据库试⽤。
3、性能和功能的优势H2⽐HSQLDB的最⼤的优势就是h2提供了⼀个⼗分⽅便的web控制台⽤于操作和管理数据库内容,这点⽐起HSQLDB的swing和awt控制台实在好⽤多了。
H2和各数据库特征⽐较。
准备⼯作3、点击 connect ,登录。
4、执⾏上图中红⾊部分sql语句,成功创建test表。
因为没有指定数据库⽂件位置,会⾃动输出到输出到C:\Users\Administrator下。
H2⽂件结构%H2_HOME%-h2-binh2-1.3.154.jar //jar包h2.bat //Windows控制台启动脚本h2.sh //Linux控制台启动脚本h2w.bat //Windows控制台启动脚本(不带⿊屏窗⼝)+docs 帮助⽂档+service //通过wrapper包装成服务。
+src //源代码build.bat windows构建脚本build.sh linux构建脚本H2的使⽤⽀持Embedded,server和in-memory模式以及内存模式。
Embedded模式1、新建java project⼯程 H2Test。
2、%H2_HOME%\bin\h2-1.3.154.jar 复制到 \H2Test\lib下,并加⼊⼯程引⽤。
3、新建Generic H2 (Embedded)数据库,指定:JDBC ,然后执⾏上⾯的test sql语句,来创建⼀个test表。
4、新建 TestH2类主要代码public static void main(String[] a)throws Exception {Class.forName("org.h2.Driver");Connection conn = DriverManager.getConnection("jdbc:h2:E:\\research\\workspace\\H2Test\\db\\test", "sa", "");// add application code hereStatement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery("SELECT * FROM TEST ");while(rs.next()) {System.out.println(rs.getInt("ID")+","+rs.getString("NAME"));}conn.close();}控制台打印出:1,Hiserver模式1、直接将jdbc url 改为:jdbc:h2:tcp://localhost/~/test 就⾏了。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
应用程序连同其文件夹一起拷到application文件夹下了,所以路径只需要指定到../application/
wrapper.java.classpath.4=../application/
5、运行cmd
cd c:\MyServerApp\bin
App.bat测试
InstallApp-NT.bat安装
UninstallApp-NT.bat卸载安装的服务
||***********************************************************************||
1、下载wrappper-windows-x86-32系列的工具包,解压缩为<wrapper-home>。
2、新建一个目录,例如:C:\My源自erverApp,并在其下面创建五个文件夹
分别为:bin 可执行程序文件夹
conf 配置文件夹
lib jar包文件夹
应用程序要用到的所有jar包
wrapper.java.classpath.5=../application/lib/*.jar
wrapper.java.library.path.1=../lib
wrapper.java.additional.1==run.bat
将<wrapper-home>\lib 下的wrapper.jar,wrappertest.jar和wrapper.dll文件复制到lib目录下
最终的包结构可以是这样子的:
C:\MyServerApp
|-bin
|-App.bat
|-InstallApp-NT.bat
wrapper.ntservice.description=@WrapperDescription@
wrapper.ntservice.dependency.1=
wrapper.ntservice.starttype=AUTO_START
wrapper.ntservice.interactive=false
与<wrapper-home>\bin 下的wrapper.exe复制到bin 目录下,并且将App.bat.in,InstallApp-NT.bat.in,
UninstallApp-NT.bat.in等的后缀.in去掉。
将<wrapper-home>\src\conf 下的wrapper.conf文件复制到conf目录下
logs 日志文件夹包
application 应用程序包 此包下还新建一个lib 用于存放应用程序所需要的jar包。
3、将<wrapper-home>\src\bin 中的App.bat.in,InstallApp-NT.bat.in,UninstallApp-NT.bat.in等文件
4、配置Wrapper工具的wrapper.conf配置文件
配置Java虚拟机的位置
mand=C:\Program Files\Java\jdk1.6.0_07\bin\java
配置wrapper的主类,如果用他的代理方式,就填org.tanukisoftware.wrapper.WrapperSimpleApp
要将哪一个应用程序做成服务,就要把他的主函数所在的类名写在这里
wrapper.app.parameter.1=com.timeseries.MySeries
wrapper.console.format=PM
wrapper.console.loglevel=INFO
指定日志记录的地方
|-UninstallApp-NT.bat
|-wrapper.exe
|-lib
|-wrapper.jar 必须要的
|-wrappertest.jar
|-wrapper.dll
|-conf
|-wrapper.conf
|-logs
|-wrapper.log
|-application
|-lib 应用程序中如果用到了jar包,那么就复制到此文件夹里
|-用来存放应用程序(一般应用程序是有包结构的,就把工程里面的bin目录下的.class文件连同包一起拷过来)
wrapper.syslog.loglevel=NONE
wrapper.console.title=Wrapper Application
=@wrapper@
wrapper.ntservice.displayname=@WrapperApplication@
wrapper.java.mainclass=org.tanukisoftware.wrapper.WrapperSimpleApp
工具寻找jar包以及应用程序的路径
wrapper.java.classpath.1=../lib/wrappertest.jar
wrapper.java.classpath.2=../lib/wrapper.jar
wrapper.logfile=../logs/wrapper.log
wrapper.logfile.format=LPTM
wrapper.logfile.loglevel=INFO
wrapper.logfile.maxsize=0
wrapper.logfile.maxfiles=0
服务里面,程序获取当前路径,不是根据.class或者jar文件所在的目录下的,而是bin目录下。
这一点很重要。所以很多程序所要的配置必须放在bin目录下,而不是和程序放在一起的目录下面。
否则服务执行时候,找不到所需的配置文件。