Rumah  >  Soal Jawab  >  teks badan

在java spring中,是否可以动态将一个新的class加载到beanFactory中?

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

阿神阿神2719 hari yang lalu459

membalas semua(5)saya akan balas

  • PHPz

    PHPz2017-04-18 10:28:24

    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

    balas
    0
  • PHP中文网

    PHP中文网2017-04-18 10:28:24

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

    balas
    0
  • 怪我咯

    怪我咯2017-04-18 10:28:24

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

    balas
    0
  • 阿神

    阿神2017-04-18 10:28:24

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

    balas
    0
  • 怪我咯

    怪我咯2017-04-18 10:28:24

    tanda untuk belajar

    balas
    0
  • Batalbalas