IDEA作为我们(后端Java开发者)必不可少的IDE,以其智能的代码提示、多样的框架支持、简洁的开发界面等特性,被业界公认为最好的Java开发工具之一。而一款IDE是否强大,最简单的衡量标准就是查看其插件生态环境的发展情况,多种多样的插件既丰富了IDE自身的功能,同时大大提高了开发人员的工作效率。
一 概念简介插件类型
IDEA的插件根据功能分为以下4种类型:
开发目录结构
组成部分二 开发过程简述
此部分以一个简单插件开发实例进行说明。
1 创建项目
IDEA插件项目开发时,有两种创建方式,一种是IntelliJ Platform Plugin,另一种是Gradle下的IntelliJ Platform Plugin(在Gradle插件安装的情况下)。推荐使用第二种方式,使用Gradle的方式可以方便的添加第三方依赖库,同时也是官方推荐的方式。
选择好创建方式后,根据需要填写信息即可完成创建。
2 设置创建入口
由于实例插件是一个工具集成类型的插件idea破解插件,我们需要在IDEA的UI添加插件的入口,这部分在配置文件plugin.xml中添加如下内容:
我们可以发现,入口就是一个Action。需要申明Action的位置和处理类。以上声明的UI效果:
3 编写处理逻辑
在配置文件中指明的动作处理类中添加处理逻辑。具体逻辑根据实际需要。
三 使用总结1 弹出对话框
使用:
Messages.showErrorDialog(myTabbedPane.getComponent(),” 弹出文本内容”);
2 提示信息
使用 new Notification(groupId 自定义, 标题, 内容, 类型(info、warning、error)).notify(项目对象实例);
3 扩展点使用
在配置文件中idea破解插件,添加扩展点配置,其他扩展点类型:
自定义JavaDoc的扩展效果:
4 自定义LiveTemplate
(1)在plugin.xml中配置liveTemplate扩展点的相关实现:
(2)在 DefaultLiveTemplatesProvider 接口的实现类的 getDefaultLiveTemplateFiles 方法中注册LiveTemplate定义文件:
@Override
public String[] getDefaultLiveTemplateFiles() {
//文件名不需要有后缀,例如a.xml,这里只需要输入a
return new String[]{"liveTemplates/文件1", "liveTemplates/文件2"};
}
(3)在 TemplateContextType 类的子类的构造方法中定义上下文名称,以及 isInContext 方法中定义上下文可以使用的位置。例如:
public XXXJavaInlineCommentContextType() {
super("上下文id", "名称", 上下文基础类型);
}
@Override
public boolean isInContext(@NotNull final PsiFile file, final int offset) {
if (PsiUtilCore.getLanguageAtOffset(file, offset).isKindOf(JavaLanguage.INSTANCE)) {
PsiElement element = file.findElementAt(offset);
if (element instanceof PsiWhiteSpace && offset > 0) {
element = file.findElementAt(offset-1);
}
if (null == element) {
return false;
}
return (element.getParent() instanceof PsiInlineDocTag && element.getParent().getParent() instanceof PsiDocTag)
|| (element.getParent() instanceof PsiInlineDocTag && PsiTreeUtil.getParentOfType(element, PsiField.class, false) != null);
}
return false;
}
(4)编写LiveTemplate定义xml文件,例如:
5 插件中调用Dubbo
(1)在Gradle的构建文件build.gradle中的dependencies内添加如下配置:
compile 'org.apache.dubbo:dubbo:2.7.7'
compile 'org.apache.dubbo:dubbo-dependencies-zookeeper:2.7.7'
(2)在接口调用处进行如下编码:
//将当前线程的classloader备份,并设置当前线程的classloader为当前类的classloader
//当前线程的classloader是IDEA的,当前类的classloader是当前插件的
//不进行如此设置会造成Dubbo扩展点实现无法在ClassLoader中找到
ClassLoader backCl = Thread.currentThread().getContextClassLoader();
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
// 以下内容参考Dubbo的泛化调用
// 当前应用配置
ApplicationConfig application = new ApplicationConfig();
application.setName("应用名");
// 连接注册中心配置
RegistryConfig registry = new RegistryConfig();
registry.setAddress("zookeeper://127.0.0.1:2181");
// 引用远程服务
ReferenceConfig reference = new ReferenceConfig(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
reference.setApplication(application);
reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
reference.setInterface("服务全类名");
reference.setVersion("服务版本号");
reference.setGeneric(true);
// 和本地bean一样使用xxxService
GenericService genericService = reference.get();
//泛化调用
Object result = genericService.$invoke("方法名", new String[]{"参数类型"}, new Object[]{"参数值"});
System.out.println(result);
//恢复classloader设置
Thread.currentThread().setContextClassLoader(backCl);
6 发布插件的指定IDEA仓库
(1)在build.gradle文件中进行如下配置
publishPlugin {
host = 'https://xxxx.com' //仓库地址
username 'onepublish' //仓库指定用户名
password 'onepublish' //仓库密码
token 'onepublish' //仓库验证token
}
(2)执行gradle中publishPlugin任务。
7 发布到指定IDEA插件失败
当我们开发完成后,通过publishPlugin任务发布时,可能会出现以下报错信息:
The resource identified by this request is only capable of generating responses with characteristics not acceptable according to the request "accept" headers.
这个问题的原因是我们使用的org.jetbrains.intellij版本较高,请使用2.x的版本。或者参照插件的源码自己写一个没有accept的上传方法即可。
相关代码:
package idea;
import retrofit.RestAdapter;
import retrofit.client.Request;
import retrofit.client.Response;
import retrofit.client.UrlConnectionClient;
import retrofit.converter.SimpleXMLConverter;
import retrofit.mime.TypedFile;
import retrofit.mime.TypedString;
import java.io.File;
import java.io.IOException;
import java.net.HttpURLConnection;
/**
* @author lijie
* @date 2019/1/17
*/
public class PublishPluginTest {
public static void main(String[] args) {
PluginRepositoryService service = new RestAdapter.Builder().setEndpoint("https://插件仓库链接").setClient(new UrlConnectionClient() {
@Override
protected HttpURLConnection openConnection(Request request) throws IOException {
HttpURLConnection connection = super.openConnection(request);
connection.setReadTimeout(10 * 60 * 1000);
return connection;
}
}).setLogLevel(RestAdapter.LogLevel.BASIC)
.setConverter(new SimpleXMLConverter())
.build()
.create(PluginRepositoryService.class);
Response response = service.uploadByXmlId(new TypedString(""), new TypedString(""),
new TypedString(pluginId), new TypedString("default"),
new TypedFile("application/octet-stream",
new File(plugin压缩文件路径)));
System.out.println(response.getBody());
}
}
package idea;
import retrofit.client.Response;
import retrofit.http.*;
import retrofit.mime.TypedFile;
import retrofit.mime.TypedString;
/**
* @author lijie
* @date 2019/1/17
*/
public interface PluginRepositoryService {
@Multipart
@POST("/plugin/uploadPlugin")
public Response uploadByXmlId(@Part("userName")TypedString username, @Part("password")TypedString password,
@Part("pluginId")TypedString pluginId, @Part("channel")TypedString channel,
@Part("file")TypedFile file);
}
8 如何在插件中引入本地jar包
在build.gradle的dependencies里边添加如下内容:
compile fileTree(dir:'src/main/resources/lib',includes:['*jar'])
然后,将本地jar包放到指定目录即可。
限时特惠:本站每日持续更新海量设计资源,一年会员只需29.9元,全站资源免费下载
站长微信:ziyuanshu688