11月24

PF4J的了解和使用

22:09编程杂谈  From: 本站原创
在平时编码过程中我们都知道要抽象,要封装变化,要实现开闭原则,比如对于很多相似的功能,我们可以将通用的功能抽象出来,然后把变化的不同的地方提取出去,比如模版模式、策略模式等都是实现类似的效果

比如对于策略模式,我们通常是定义一个接口,然后有不同的实现,这种是可以的,但是如果通用流程中要扩展的点较多的话,这些不同的实现也需要管理,可以把他们合并到一个单独的包中,再进一步,我们甚至可以将包单独提取出来,支持运行时加载包实现新增功能的支持

JDK对此功能的支持就是 SPI,但是它的限制较多,也不够灵活,比如dubbo就是自己定义了一套SPI的实现,这次我们来看另一个实现,pf4j 提供一套在基本框架中定义扩展点接口,然后通过不同的插件来实现扩展点的功能,来支持对新增开放对修改关闭

下面我们就来学习一下它的使用

使用
比如我们有一套通用的流程,假设是下单流程,不同的业务线等对于下单都有一些特殊点,但是它们的基本流程是相似的,这时候我们就可以先定义好通用的流程,不同的地方预留出扩展点接口,使用 pf4j 的流程如下

先定义好扩展点接口(需要定义单独的包,因为基本应用和各个扩展点的包都依赖它)
定义单独的插件包,其中实现扩展点接口的功能
在应用中编写基本流程和扩展点的发现使用功能
这次我们就参考 pf4j 提供的例子来看一下

1. 定义扩展点接口
pom.xml首先声明依赖

<dependency>
    <groupId>org.pf4j</groupId>
    <artifactId>pf4j</artifactId>
    <version>3.6.0</version>
    <!-- 一般应用中会依赖这个包,所以这里设置为provided即可 -->
    <scope>provided</scope>
</dependency>
之后即可声明各个扩展点接口

/**
* 假设我们需要一个通知用户的功能
* 需要注意的是,我们一定要继承 ExtensionPoint 接口,表示这是一个扩展点
*/
public interface Notice extends ExtensionPoint {
    boolean notice(List<Long> userIds);
}
11月24
PF4J是一个Java轻量级的插件框架,可以实现动态加载,执行,卸载外部插件(支持jar以及zip),具体可以看官网:https://pf4j.org/。

本文例子基于Github地址:https://github.com/pf4j/pf4j

<dependency>
  <groupId>org.pf4j</groupId>
  <artifactId>pf4j</artifactId>
  <version>3.6.0</version>
</dependency>
插件项目会涉及到3个工程:工程结构
plugin-api:定义可扩展接口
plugins:插件项目,可以包含多个插件,需要实现plugin-api中定义的接口
plugin-app:主程序,需要依赖plugin-api,加载并执行plugins
定义可扩展接口(plugin-api)
简单定义一个接口,需继承ExtensionPoint:

package plugin.api;

import org.pf4j.ExtensionPoint;

public interface Greeting extends ExtensionPoint {

    String getGreeting();
}
实现插件(plugins)
插件需要实现plugin-api定义的接口,并且使用@Extension标记:
package plugins;

import org.pf4j.Extension;
import plugin.api.Greeting;

@Extension
public class WelcomeGreeting implements Greeting {

    public String getGreeting() {
        return "Welcome";
    }
}

插件打包(plugins)
插件打包时,需要往MANIFEST.MF写入插件信息,此处使用maven插件(打包命令为package):
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-jar-plugin</artifactId>
  <version>2.3.1</version>
  <configuration>
    <archive>
      <manifestEntries>
        <Plugin-Id>welcome-plugin</Plugin-Id>
        <Plugin-Version>0.0.1</Plugin-Version>
      </manifestEntries>
    </archive>
  </configuration>
</plugin>
11月22
运行SpringBoot的时候报如下错Consider defining a bean of type ‘com.google.code.kaptcha.Producer’ in your configuration.

报错原因为配置中找不到一个指定自动注入类型的bean。
那么我们要从collecter层开始查找,点击service层,看service实现类是否加上@Service或者@Component,检查service实现类是否有implements service。如果这些都没有问题:

我们来看@SpringBootApplication,点过去。可以看到有个@ComponentScan,ComponentScan做的事情就是告诉Spring从哪里找到bean

那可以直接在@SpringBootApplication加上

还有一种问题,你的spring启动类不在同一个父包路径下,比如你的其它类在com.heckjj.blog,而你的启动类在heckjj下,也会报错扫不到其它的类,比如说service找不到。
11月22
在pom.xml文件中maven插件配置增加下如配置

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-resources-plugin</artifactId>
    <version>3.0.2</version>
    <configuration>
        <encoding>UTF-8</encoding>
        <nonFilteredFileExtensions>
            <nonFilteredFileExtension>xls</nonFilteredFileExtension>
            <nonFilteredFileExtension>xlsx</nonFilteredFileExtension>
        </nonFilteredFileExtensions>
    </configuration>
</plugin>
10月28
今天在做导入功能的时候,遇到了字符串无法转化为日期格式异常。在网上找了很多办法。还是下面的解决办法来的实在。

在使用beanutils工具类封装javabean时,beanUtils不提供直接将字符串转换成Date(java.util.Date)数据类型的方法,所以会出现下面警告:
在控制层中写入以下代码
        DateConverter converter = new DateConverter();
        converter.setPattern(new String("yyyy-MM-dd"));
        ConvertUtils.register(converter, Date.class);
10月18
今天有个接口查询条件超过6个字段了,将其改为对象方式接收,但发现Integer的字段的默认值 都变成0了,调试代码发现有个过滤器处理XSS的对参数进行BeanUtils.populate了。
于是Iteger类型的数据为空时填写–写”直接转为0

以上情况均不符合要求,数据库要求为integer的默认值NULL

后来查阅资料寻找到以下方法
ConvertUtils.register(new IntegerConverter(null), Integer.class);
通过转换器来设置为null时的默认转换值。其它类型依次类推设置为相应的基本类型的包装类即可。
7月4

当我们安装了redis服务后,发现在其配置文件redis.windows.conf(或redis.conf)设置了密码:requirepass ******

但是打开redis-cli.exe后输入命令config get requirepass发现:

这说明配置文件中密码设置后没有生效。

原因:问题在于我们启动redis服务时是直接在其安装目录中双击redis-server.exe启动的,这样启动的结果是,配置文件不会指定,此时redis并不会自动使用安装目录下的redis.windows.conf(或redis.conf)文件

红线框住的的提示说的很明确“ Warning: no config file specified”没有指定配置文件

解决方法:

法1:实际上我们直接在安装目录中启动redis服务时错误的,正确的方式是打开“运行”,键入“cmd”切到安装目录后输出redis-server.exe redis.windows.conf,回车,就可以了。

法2:在redis安装目录下新建文件startup.bat后,右击“编辑”,或者先用记事本建立该文件,再把扩展名改一下,文件里面写上:redis-server.exe redis.windows.conf。保存,以后再运行就直接运行这个文件,不要再直接运行redis-server.exe了,就可以了。

6月18
一、问题原因
2、原因:后台传过去的json数据用了阿里的fastjson转换,但是解析list中引用的数据时,jvm会自动将其处理为“循环引用”,因此,也就出现了问题{" r e f " : " ref":" ref":".data[0].children[0]"},数据以引用的方式传给前台,前台却无法解析到那段引用的数据。

循环引用就是:当一个对象包含另一个对象时,fastjson就会把该对象解析成引用。

二、解决方案
JSON.toJSONString(list,SerializerFeature.DisableCircularReferenceDetect)

用这种转换方式,把list替换成你要转换的数据就可以了。
6月14
1.在gitlab上找到你要回滚的那个版本 ,复制那次提交的id

点击在新窗口中浏览此图片

2.输入指令,回滚到指定的版本

git reset --hard 复制的id


3.推送到远端(强推)

git push -f origin master
5月17
sql执行正常的,但是放到mybatisPlus中执行错误报: Failed to process, please exclude the tableName or statementId.

大概率是存在特殊字符使mybatis解析异常
1.在mapper.java中的方法上添加@SqlParser(filter=true)注解
点击在新窗口中浏览此图片

2.如果sql中有注释,删掉注释
点击在新窗口中浏览此图片
分页: 3/20 第一页 上页 1 2 3 4 5 6 7 8 9 10 下页 最后页 [ 显示模式: 摘要 | 列表 ]