【问题标题】:Annotation scan not scanning external jars in classpath注释扫描不扫描类路径中的外部 jar
【发布时间】:2013-05-12 09:33:19
【问题描述】:

问题:Spring Component Annotation 扫描未拾取在 pom.xml 中未包含的外部 jar 中注释的类。但我需要从外部 jar 中扫描具有特定注释的类。这些外部 jar 将被放置在类路径中,但在编译期间我的应用程序不会知道。

1)我们有一个 maven 模块(artifactId="metric_processor"),它生成一个 jar 文件(metric_processor.jar)并具有以下类

package com.metric;
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ProcessMetric {
    String name();
}

package com.metric;
public interface MetricProcessor {
   int computeMetric();
}

package com.metric;
@ProcessMetric(name="LATENCY")
@Component
public class LatencyMetricProcessor implements MetricProcessor {
    .....
}

2) 我们有另一个 maven 模块 ("artifactId="metric_processor_external"),它生成一个 jar(metric_processor_external.jar) 并包含“metric_processor”模块作为编译时范围。

package com.metric;
@ProcessMetric(name="TEST_METRIC_EXTERNAL")
@Component
public class TestMetricProcessor implements MetricProcessor {
    ....
}

3) 我们有第三个(主)maven 模块(artifactId="main_application"),它是一个独立的应用程序(使用 spring),它在编译范围内包含模块“metric_processor”。 (但不包括“metric_processor_external”)。第三个模块的构建插件是

<build>
    <plugins>
        <plugin>
            <artifactId>maven-assembly-plugin</artifactId>
            <version>2.4</version>
            <configuration>
                <descriptorRefs>
                    <descriptorRef>jar-with-dependencies</descriptorRef>
                </descriptorRefs>
                <archive>
                    <manifest>
                        <mainClass>com.main.TriggerMetricProcessor</mainClass>
                    </manifest>
                </archive>
            </configuration>
            <executions>
                <execution>
                    <id>make-assembly</id>
                    <phase>package</phase>
                    <goals>
                        <goal>single</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

此模块的应用程序上下文 xml 是

    <beans>
        <context:component-scan base-package="com.metric">
            <context:include-filter type="annotation" expression="com.metric.ProcessMetric" />
        </context:component-scan>
        <bean id="triggerMetricProcessor" class="com.main.TriggerMetricProcessor" />
    </beans>

我有以下类,它是应用程序的起点

package com.main;

import ...

public class TriggerMetricProcessor {
    public static void main(String[] args) throws  Exception {
        ApplicationContext context =
                new ClassPathXmlApplicationContext("application-context.xml");

        TriggerMetricProcessor triggerMetricProcessor = (TriggerMetricProcessor) context.getBean("triggerMetricProcessor");
        triggerMetricProcessor.initMetricProcessor(context);
    }

    private void initMetricProcessor(ApplicationContext context) {
        GenericBeanFactoryAccessor beanFactoryAccessor = new GenericBeanFactoryAccessor(context);
        final Map<String, Object> metricProcessors = beanFactoryAccessor.getBeansWithAnnotation(ProcessMetric.class);
        for (final Object metricProcessor : metricProcessors.values()) {
            final Class<? extends MetricProcessor> metricProcessorClass = (Class<? extends MetricProcessor>)metricProcessor.getClass();
            final ProcessMetric annotation = metricProcessorClass.getAnnotation(ProcessMetric.class);
            System.out.println("Found MetricProcessor class: " + metricProcessorClass + ", with name: " + annotation.name());
        }
    }
}

我们将第三个模块编译为

maven clean install assembly:single 

这会生成 jar 文件“main_application-with-dependencies.jar”

然后我们将其运行为

java -cp "metric_process_external.jar" -jar main_application-with-dependencies.jar

现在应用程序只找到“LatencyMetricProcessor”,没有找到“TestMetricProcessor”。

有人可以帮忙吗?

【问题讨论】:

    标签: spring jar annotations console-application


    【解决方案1】:

    当您使用 -jar 选项执行 jar 文件时,-cp 选项将被忽略。

    -jar 选项的Oracle Java docs 说:

    -jar

    执行封装在 JAR 文件中的程序。第一个论点是 JAR 文件的名称而不是启动类名称。为了 要使此选项起作用,JAR 文件的清单必须包含一行 Main-Class 形式的:类名。在这里,类名标识 具有 public static void main(String[] args) 方法的类 作为您的应用程序的起点。查看 Jar 工具 参考页面和 Java 教程的 Jar trail 以获取信息 关于使用 Jar 文件和 Jar 文件清单。

    使用此选项时,JAR 文件是所有用户的来源 类和其他用户类路径设置将被忽略。

    也可以看看这个帖子:stackoverflow.com/questions/5879925/in-linux-how-to-execute-java-jar-file-with-external-jar-files

    因此,您需要使用 Class-Path: 标头在清单文件中指定 metric_process_external.jar。你应该可以让你的 Maven 程序集插件来做到这一点。

    如果这不切实际,您需要在没有 -jar 标志的情况下运行您的应用程序:

    java -cp "metric_process_external.jar:main_application-with-dependencies.jar" com.main.TriggerMetricProcessor
    

    【讨论】:

    • 如果我使用 XML 的 bean 声明会怎样。它会起作用吗?我在那里遇到了问题。
    猜你喜欢
    • 2015-02-17
    • 2014-05-28
    • 1970-01-01
    • 2012-10-19
    • 1970-01-01
    • 2017-02-27
    • 1970-01-01
    • 2016-06-25
    • 1970-01-01
    相关资源
    最近更新 更多