Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 添加测微计相关性会导致奇怪的Spring代理问题_Java_Spring_Proxy_Aspectj_Micrometer - Fatal编程技术网

Java 添加测微计相关性会导致奇怪的Spring代理问题

Java 添加测微计相关性会导致奇怪的Spring代理问题,java,spring,proxy,aspectj,micrometer,Java,Spring,Proxy,Aspectj,Micrometer,我有一个带有private@Scheduled方法的简单Spring引导应用程序: @SpringBootApplication @EnableScheduling public class DemoApplication { public static void main(String[] args) { SpringApplication.run(DemoApplication.class, args); } @Scheduled(fixedRat

我有一个带有private@Scheduled方法的简单Spring引导应用程序:

@SpringBootApplication
@EnableScheduling
public class DemoApplication {

    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Scheduled(fixedRate = 1000)
    private void scheduledTask() {
        System.out.println("Scheduled task");
    }
}
pom.xml:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>

    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.8.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--<dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-spring-legacy</artifactId>
            <version>1.1.1</version>
        </dependency>
        <dependency>
            <groupId>io.micrometer</groupId>
            <artifactId>micrometer-registry-prometheus</artifactId>
            <version>1.1.1</version>
        </dependency>-->

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjrt</artifactId>
            <version>1.8.11</version>
        </dependency>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>1.8.11</version>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>


</project>
有人知道下面发生了什么吗

编辑:
我认为mictometer和aspectJ依赖项之间存在某种冲突,只有当两者都存在于类路径上时才会出现问题。

Spring建议通常在可能的情况下使用JDK代理实现,这需要一个接口来动态实现(它执行有趣的逻辑,然后委托给您的业务代码)。在这种情况下,您有一个实际的类,因此Spring所能做的最好的事情就是将其子类化

然而,这里有两个相互冲突的需求:Spring希望应用捕获代码度量的建议,但是由于该方法是
private
,因此无法从子类访问它。(实际上,我有点惊讶于它用私有方法检测并调用您的计划任务。)

将方法更改为
protected
允许Spring在运行时执行此操作(不是实际的Java代码,而是等效生成的字节码):


是的,存在冲突,或者您尝试过将私有方法的可见性更改为受保护的或公共的,但没有对依赖项进行注释。是的,更改方法可见性是可行的,但我希望避免。有可能吗?谢谢你的回复。如果我将访问级别更改为package private,它也可以正常工作-Spring是否使用与我的类相同的包创建代理类?@tutnhamon确定这一点的最佳方法是将
System.err.println(this.getClass())
放在任务方法中。我的猜测是肯定的,但关键因素是,当一个方法是私有的时,编译器知道一个事实,即它将“永远”不会从正在编译的类之外被使用,因此它可以以可能干扰子类化的特殊方式处理它。默认访问和更新意味着外部类可能需要与之交互。没错,控制台上打印的类名是“class com.example.demo.DemoApplication$$EnhancerBySpringCGLIB$$ee930494”。你能告诉我为什么在没有micrometer或aspectJ依赖项的情况下,它可以工作,Spring可以运行这个私有方法吗?@tutnhamon因为和许多Java框架一样,Spring欺骗:它使用
setAccessible
来操作它不应该访问的东西,比如
@PostConstruct
方法和
@Autowired
字段(不要使用这些)。在Java 9及更高版本上,您通常在控制台上看到的第一件事是关于非法反射访问的警告,如果您使用严格的安全管理器,您的应用程序将无法启动。@tutnhamon这是我最好的猜测。您自己试试,看看在这种情况下是否会报告。
Caused by: java.lang.IllegalStateException: Need to invoke method 'scheduledTask' found on proxy for target class 'DemoApplication' but cannot be delegated to target bean. Switch its visibility to package or protected.
    at org.springframework.aop.support.AopUtils.selectInvocableMethod(AopUtils.java:133) ~[spring-aop-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.processScheduled(ScheduledAnnotationBeanPostProcessor.java:343) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.scheduling.annotation.ScheduledAnnotationBeanPostProcessor.postProcessAfterInitialization(ScheduledAnnotationBeanPostProcessor.java:326) ~[spring-context-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyBeanPostProcessorsAfterInitialization(AbstractAutowireCapableBeanFactory.java:423) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1633) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:555) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]
    ... 15 common frames omitted
class DemoApplicationWithAdvice extends DemoApplication {
    @Override
    protected void scheduledTask() {
        // record start time
        super.scheduledTask();
        // write metric with execution time
    }
}