14

我正在尝试设置一个@Configurable域对象(不由 spring 容器管理)。
我通过添加-javaagent:path/to/spring-instrument.jar作为 JVM 参数来完成这项工作,但我并不清楚这个 -javaagent 是否必须到位。我在 Tomcat 8 上运行它。我可能误解了文档,但似乎我可以使用另一种机制来实现这一点,特别是这一行:

不要再定义TomcatInstrumentableClassLoaderTomcat 8.0更高。而是InstrumentableClassLoader通过策略让 Spring 自动使用 Tomcat 新的原生设施TomcatLoadTimeWeaver

下面的代码示例:

@SpringBootApplication
@EnableLoadTimeWeaving
public class TestApplication {

    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }   
    @Bean
    public MyService myService(){
        return new MyService();
    }
}

@Configurable
public class MyDomainObject {

    @Autowired
    private MyService myService;

    public MyService getMyService(){
        return myService;
    }
}

 public class MyService {
    private static final Logger log = LoggerFactory.getLogger(MyService.class);

    public void test(){
        log.info("test");
    }
}

那么有没有办法在不指定 -javaagent 的情况下编织这些 @Configrable 对象?我有兴趣了解在作为 WAR 部署到独立 Tomcat 8 服务器和/或在作为“胖”jar 启动时使用嵌入式 Tomcat 8 服务器时是否可以完成此操作。

就目前而言,部署到独立 Tomcat 8 服务器不会引发错误,但上述getMyService()方法返回 null。作为 fat jar 启动会在启动过程中引发以下错误:

Caused by: java.lang.IllegalStateException: ClassLoader [sun.misc.Launcher$AppClassLoader] does NOT provide an 'addTransformer(ClassFileTransformer)' method. Specify a custom LoadTimeWeaver or start your Java virtual machine with Spring's agent: -javaagent:org.springframework.instrument.jar

我想真正的问题是我如何Specify a custom LoadTimeWeaver在 Tomcat 8 中使用?正如文档所述,似乎没有任何事情会自动发生,但我可能再次误解了这意味着什么。

4

2 回答 2

1

你可以试试这个:

@Bean
public InstrumentationLoadTimeWeaver loadTimeWeaver() {
    return new InstrumentationLoadTimeWeaver();
}

或者

有一个新库可以解决动态设置 spring InstrumentationLoadTimeWeaver 以启用对方面的支持而无需使用显式 java 代理启动 JVM

<dependency>
    <groupId>de.invesdwin</groupId>
    <artifactId>invesdwin-instrument</artifactId>
    <version>1.0.2</version>
</dependency>

@SpringBootApplication
@EnableLoadTimeWeaving
public class TestApplication{
    public static void main(final String[] args) {
        DynamicInstrumentationLoader.waitForInitialized(); //dynamically attach java agent to jvm if not already present
        DynamicInstrumentationLoader.initLoadTimeWeavingContext(); //weave all classes before they are loaded as beans
        SpringApplication.run(TestApplication.class, args); //start application, load some classes
    }
}
于 2020-06-16T21:53:58.990 回答
-2

创建自己的注释 @MyConfigurable 怎么样?所以当它的方法被调用时,你可以做任何你喜欢的事情。

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.CONSTRUCTOR)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyConfigurable
{}
于 2016-06-15T14:12:59.390 回答