在java spring中,是否可以动态将一个新的class加载到beanFactory中?
阿神
阿神 2017-04-18 10:26:24
0
5
481

在java spring中,是否可以动态将一个新的class加载到beanFactory中?是否可以将class类以字节流的方式存到redis中,再由类加载器重新加载到java运行实例中?
目前项目中有一个需求,需要可以动态地加载类到spring的beanFactory中或者说applicationContext里面,这个类是可以由开发人员动态上传到生产环境中,而无需重新启动生产环境。请问是否可以做到呢?还有一个问题,是否可以将class文件以字节的方式暂存在redis中间件上,需要用这个class时,动态地加载它?

阿神
阿神

闭关修行中......

membalas semua(5)
PHPzhong

Selepas JDK1.5, terdapat API java.lang.instrument.Instrumentation siap sedia untuk melaksanakan fungsi ini.

java.lang.instrument.Instrumentation.redefineClasses(ClassDefinition... definitions)

Antara muka di atas boleh mentakrifkan semula class sedia ada.
Gunakan seperti di bawah.

private void redefineScripts(File dir) {
    File[] files = dir.listFiles();
    for (File f : files) {
        if (f.isDirectory()) {
            redefineScripts(f);
        } else if (f.getName().endsWith(".class")) {
            String name = getScriptCanonicalName(f);
            String path = name.replaceAll("\.", "/");
            File target = new File(targetDir, path + ".class");

            try {
                InputStream in = new FileInputStream(target);
                byte[] buf = StreamUtils.copyToByteArray(in);
                ClassDefinition cdef = new ClassDefinition(scriptClassLoader.loadClass(name), buf);
                instrumentation.redefineClasses(cdef);
            } catch (Exception ex) {
                throw new ScriptException(ex);
            }
        }
    }
}

Kaedah untuk mendapatkan Instrumentation objek:

private void loadAgent() {
    try {
        String pid = ManagementFactory.getRuntimeMXBean().getName().split("@")[0];
        VirtualMachine vm = VirtualMachine.attach(pid);
        vm.loadAgent("<jar file>", OBJECT_NAME.toString());
        vm.detach();
    } catch (Exception ex) {
        throw new RuntimeException(
                "无法加载代理JAR文件["
                + Typhons.getProperty(Constants.AGENT_JAR_PATH) + "]", ex);
    }
}

agent.jarAnda perlu menentukan Agent-Class semasa pembungkusan dan Can-Redefine-Classes dayakan fungsi penulisan semula kelas.

<plugin>
    <artifactId>maven-jar-plugin</artifactId>
    <configuration>
        <archive>
            <manifest>
                <addClasspath>true</addClasspath>
            </manifest>
            <manifestEntries>
                <Agent-Class>org.skfiy.typhon.agent.Agent</Agent-Class>
                <Can-Redefine-Classes>true</Can-Redefine-Classes>
            </manifestEntries>
        </archive>
    </configuration>
</plugin>

Agent.java Pelaksanaan

public class Agent {

    /**
     * 代理主函数入口. 通过传入的{@code str }{@code ObjectName }执行其{@code setInstrumentation }
     * 方法.
     * <p>
     * e.g.<pre>
     * public void setInstrumentation(Instrumentation instrumentation) {
     *  this.instrumentation = instrumentation;
     * }
     * </pre>
     * 
     * @param str 一个{@link ObjectName }字符串
     * @param inst {@link Instrumentation }实现
     * @throws Exception 异常
     */
    public static void agentmain(String str, Instrumentation inst) throws Exception {
        ObjectName objectName = ObjectName.getInstance(str);
        MBeanServer mbeanServer = MBeanServerFactory.findMBeanServer(null).get(0);
        mbeanServer.invoke(objectName, "setInstrumentation",
                new Object[]{inst},
                new String[]{Instrumentation.class.getName()});
    }
}

Di sini saya menyuntik objek JMX melalui Instrumentation Mengapa saya melakukannya dengan cara ini? | .
Kemudian saya cuba memanggilnya menggunakan . vm.loadAgent(); ClassLoaderBaiklah, selagi anda mendapat objek , anda boleh melakukan apa sahaja yang anda tidak boleh lakukan sebelum ini. JMX

Ty80

Cuba dapatkan AutowireCapableBeanFactory melalui ApplicationContext, dan kemudian panggil kaedah createBean() atau autowire() untuk menyuntik

刘奇

Java mempunyai aliran input dan output objek, jadi anda pasti boleh menyimpan objek dalam bait

阿神

Semua yang dinyatakan di atas adalah salah. Saya boleh memberitahu anda dengan jelas bahawa segala-galanya mungkin.

刘奇

tanda untuk belajar

Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan