本次实验Java的动态加载依赖lib/StartModule.jar
文件:
public class Main {
public static void main(String[] args) throws Exception{
File jarFile = new File("lib/StartModule.jar");
URI uri = jarFile.toURI();
URLClassLoader classLoader = new URLClassLoader(new URL[]{uri.toURL()});
Class<?> init = classLoader.loadClass("Init");
MyAction action = (MyAction) init.newInstance();
action.action();
}
}
那么怎样避免每次生成StartModule.jar的时候需要手动生成jar呢?(jar cvf StartModule.jar classes/
)
那就是使用Gradle
的自动构建了。
首先新建一个Module tartModule
,这时候的目录树为(这里我省略了一些不重要的目录):
│ build.gradle
│ gradlew
│ gradlew.bat
│ settings.gradle
│ Test.iml
│
├─gradle
│
├─lib
├─src
│ ├─main
│ │ ├─java
│ │ │ Main.java
│ │ │ MyAction.java
│ │ │
│ │ └─resources
│ └─test
│ ├─java
│ └─resources
└─StartModule
│ build.gradle
│ StartModule.iml
│
└─src
├─main
│ ├─java
│ │ Init.java
│ │
│ └─resources
└─test
├─java
└─resources
/src/main/java/MyAction是一个接口:
public interface MyAction {
void action();
}
用来实现动态加载,模块StartModule
中的类Init实现了MyAction这个接口:
public class Init implements MyAction {
@Override
public void action() {
System.out.println("HAHAHAHA");
}
}
为了能够一键生成StartModule的jar并且把生成的jar拷贝到/lib
下,就必须配置Gradle的构建脚本了。
首先看StartModule
下的build.gradle
文件:
group 'xyz.bpazy'
version ''
apply plugin: 'java'
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
compile project(':') //添加依赖根目录,才可以使用MyAction接口
}
//添加一个task,作用为生成jar,生成的jar的目录在该moudle下的/build/libs中
task makeJar(type: Jar) {
baseName 'StartModule' //baseName用来指定生成的jar的名称,jar名称的形式为[$baseName-$version.jar],所以为了方便我把version的值设为空
from('build/classes/main') //指定要添加到jar文件的.class文件的路径
}
//这个task是用来清除已经生成的jar
task clearJar(type: Delete) {
delete 'build/libs'
}
//指定执行makeJar这个task依赖clearJar和build,也就是执行makeJar之前会先clearJar, build,然后才makeJar
makeJar.dependsOn(clearJar, build)
至此我们已经生成了jar,但是这个jar的目录不在正确的地方。
现在打开工程的根`build.gradle’:
group 'xyz.bpazy'
version '1.0-SNAPSHOT'
apply plugin: 'java'
apply plugin: 'application' //这个插件的作用是为gradle添加一个run的task,gradle run 就是直接执行主类的main方法
mainClassName = "Main" //指定run task的主类
sourceCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
testCompile group: 'junit', name: 'junit', version: '4.11'
}
//添加task release,类型是Copy
task release(type: Copy) {
//把`/StartModule/build/libs`下的所有jar文件拷贝到`/lib`文件夹下
from('StartModule/build/libs') {
include '*.jar'
}
into('lib')
}
//为release添加指定的依赖,这个依赖是子模块中的task,格式为[:$moduleName:$taskName]
release.dependsOn(':StartModule:makeJar')
//为run添加指定的依赖release
run.dependsOn('release')
在这样的配置下,我们执行命令gradle run,因为层层依赖,所以执行顺序是:
:StartModule:clearJar
->:StartModule:build
->:StartModule:makeJar
->:release
->:run
测试一下是否成功
D:\Project\Java\Test>gradlew run
:compileJava
:processResources UP-TO-DATE
:classes
:jar
:StartModule:compileJava
:StartModule:processResources UP-TO-DATE
:StartModule:classes
:StartModule:jar
:StartModule:assemble
:StartModule:compileTestJava UP-TO-DATE
:StartModule:processTestResources UP-TO-DATE
:StartModule:testClasses UP-TO-DATE
:StartModule:test UP-TO-DATE
:StartModule:check UP-TO-DATE
:StartModule:build
:StartModule:clearJar
:StartModule:makeJar
:release
:run
HAHAHAHA
BUILD SUCCESSFUL
Total time: 3.686 secs
动态加载/lib/StartModule.jar
成功了.