使用外部jar

时间:2016-08-14 14:20:05

标签: java spring aop aspectj

我正在尝试为测量方法运行时间创建一个计时器方面。

我创建了一个名为@Timer的注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(value = {ElementType.METHOD, ElementType.TYPE})
public @interface Timer {
    String value();
}

然后我按如下方式创建了方面:

@Aspect
public class MetricAspect {

    @Autowired
    private MetricsFactory metricsFactory;

    @Pointcut("@annotation(my.package.Timer)")
    public void timerPointcut() {}

    @Around("timerPointcut() ")
    public Object measure(ProceedingJoinPoint joinPoint) throws Throwable {
       /* Aspect logic here */
    }

    private Timer getClassAnnotation(MethodSignature methodSignature) {
        Timer annotation;
        Class<?> clazz = methodSignature.getDeclaringType();
        annotation = clazz.getAnnotation(Timer.class);
        return annotation;
    }

我有一个配置类如下:

@Configuration
@EnableAspectJAutoProxy
public class MetricsConfiguration {

    @Bean
    public MetricAspect notifyAspect() {
        return new MetricAspect();
    }
}

直到这里的所有内容都在一个打包的jar中定义,我在春季启动应用程序中用作依赖

在我的spring启动应用程序中,我导入了MetricsConfiguration并调试了代码并看到了MetricAspect bean的创建。

我在代码中使用它如下:

@Service
public class MyService {
    ...

    @Timer("mymetric")
    public void foo() {
       // Some code here...
    }

    ...
}

但是我的代码没有达到measure方法。不确定我错过了什么。

为了完成图片,我在我的pom文件中添加了这些依赖项:

<dependencies>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.7.4</version>
    </dependency>

    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.7.4</version>
    </dependency>
</dependencies>

导入@Configuration的{​​{1}}类:

MetricsConfiguration

它装载了Spring的自动配置加载。

7 个答案:

答案 0 :(得分:10)

可以Intent intent = new Intent(Intent.ACTION_GET_CONTENT); //tried ACTION_VIEW but it says no apps that can perform this action! Uri uri = Uri.fromFile(mDownloadDir); //mDownloadDir is file object intent.setDataAndType(uri, "resource/folder"); mContext.startActivity(Intent.createChooser(intent, "Open folder")); @Component解决您的问题吗?

@Configurable

Enable Spring AOP or AspectJ

编辑:

我创建了一个模拟你的问题的项目,毕竟没问题。是否受到其他问题的影响?

https://github.com/zerg000000/spring-aspectj-test

答案 1 :(得分:3)

我无法使用 aspectJ 1.8.8 spring 4.2.5 重现您的问题。 Here是我的maven多模块方法,方面在独立的jar中。

我稍微修改了你的代码,但没有更改任何注释。唯一可能不同的是我添加了org.springframework:spring-aop依赖项并定义了我的入口点,如下所示:

@Import(MetricsConfiguration.class)
@SpringBootApplication
public class Application {
    // @Bean definitions here //

    public static void main(String[] args) throws InterruptedException {
        ApplicationContext ctx = 
            SpringApplication.run(Application.class, args);
        ctx.getBean(MyService.class).doWork();
    }
}

答案 2 :(得分:2)

我有一个类似的问题,方面是在jar库中构建的,而spring-boot应用程序是在其他地方。原来,spring-boot应用程序和jar库的软件包不同。由于这个原因,Spring并没有考虑将库的程序包自动装配到应用程序上下文中。

因此,必须在Application.java中包含@ComponentScan({"base.package.application.*", "base.package.library.*"})

答案 3 :(得分:1)

  1. 如果外部jar是Spring boot starter,则可以在自动配置中配置Aspect Bean:

(1)

@Aspect
public class MyAspect {
  //....
}

(2)

package a.b.c

@Configuration
public class MyAutoConfiguration {
    @Bean
    MyAspect myAspect() {
        return new MyAspect();
    }   
}
在spring.factories中

(3)config

org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
a.b.c.MyAutoConfiguration
  1. 如果外部jar不是Spring引导启动器,只需将Aspect加载为bean,就可以使用@ComponentScan

答案 4 :(得分:0)

添加此componentScan以解决问题。

@ComponentScan("package.of.aspect")
@Configuration
@EnableAspectJAutoProxy
@Import(MetricsConfiguration.class)
@PropertySource("classpath:application.properties")
public class ApplicationConfiguration {

}

答案 5 :(得分:0)

即使有详细的日志记录,也很难调试切入点本身有问题的spring-boot Aspectj方面:How to debug Spring AOP

不幸的是,带有注释的spring boot + spring-aop并没有很多调试方面的方法,以及为什么不扫描某些类(尤其是非spring compoment jar类),例如jar类whose methods are in abstract classes或static最终方法需要正确的切入点才能覆盖所有类/实现,即使它们是组件扫描的。

调试Asepct的最佳方法(或使用核心AOP并避免spring-aop)是使用LTW使用org / aspectj / aop.xml或META-INF / aop.xml进行配置控制来启用aop.xml。 Aspectj Weaver -Daj.weaving.verbose = true -javaagent:〜/ .m2 / repository / org / aspectj / aspectjweaver / 1.9.5 / aspectjweaver-1.9.5.jar

要使用Debug / Verbose日志调试所有方面/类,以查看为什么未扫描某些类: ...

这几乎总是有助于找出切入点或类未被选中的问题。

或者,只需使用LTW aop,请参见https://github.com/dsyer/spring-boot-aspectj

答案 6 :(得分:-2)

根据mojohaus的说明,您必须将如下所示的构建设置添加到编织方面,并将其添加到实现方面界面的所有类中。

<build>
    <plugins>
        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>aspectj-maven-plugin</artifactId>
            <version>1.11</version>
            <configuration>
                <complianceLevel>1.8</complianceLevel>
                <includes>
                    <include>**/*.java</include>
                    <include>**/*.aj</include>
                </includes>
                <aspectDirectory>src/main/aspect</aspectDirectory>
                <testAspectDirectory>src/test/aspect</testAspectDirectory>
                <XaddSerialVersionUID>true</XaddSerialVersionUID>
                <showWeaveInfo>true</showWeaveInfo>
                <aspectLibraries>
                    <aspectLibrary>
                        <groupId>your aspect groupId</groupId>
                        <artifactId>your aspect artifactId</artifactId>
                    </aspectLibrary>
                </aspectLibraries>
            </configuration>
            <executions>
                <execution>
                    <id>compile_with_aspectj</id>
                    <goals>
                        <goal>compile</goal>
                    </goals>
                </execution>
                <execution>
                    <id>test-compile_with_aspectj</id>
                    <goals>
                        <goal>test-compile</goal>
                    </goals>
                </execution>
            </executions>
            <dependencies>
                <dependency>
                    <groupId>org.aspectj</groupId>
                    <artifactId>aspectjtools</artifactId>
                    <version>${aspectj.runtime.version}</version>
                </dependency>
                <dependency>
                    <groupId>your aspect groupId</groupId>
                    <artifactId>youar aspect artifactId</artifactId>
                    <version>1.0.0-SNAPSHOT</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>