【问题标题】:AspectJ doesnt work fine in EclipseAspectJ 在 Eclipse 中不能正常工作
【发布时间】:2012-08-28 20:55:58
【问题描述】:

我尝试用java创建一个简单的程序。

在我的程序中:

1) Person 类 - 带有注解的方法

2) 方面类。

现在我要做的是在设置人名之前,将一些数据打印到日志文件和控制台。

这就是我所做的:

人员类

package pack.bl;

import org.springframework.stereotype.Component;
import pack.aop.LogLevel;
import pack.aop.TestAnnotation;

@Component
public class Person {

private String name,dest;
public Person(String name,String dest)
{
    this.setName(name);
    this.setDest(dest);
}

public String getName() {
    return name;
}

@TestAnnotation(value=LogLevel.INFO)
public void setName(String name) {
    this.name = name;
    System.out.println("Im " + this.toString() + " My name was changed to " + name);
}

public String getDest() {
    return dest;
}

@TestAnnotation(value=LogLevel.INFO)
public void setDest(String dest) {
    this.dest = dest;
}

@Override
public String toString()
{
    return this.name + "\n";
}

public static void main(String[] args) {
    Person p = new Person("Person1","Kripton");
    p.setName("Person2");
}

}

方面类

package pack.aop;

import java.util.Arrays;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.test.context.ContextConfiguration;


@Aspect
@ContextConfiguration(locations = {
        "applicationContext.xml"})

public class BeforeAdvice {

private Log logger = LogFactory.getLog("Logger");

@Before("@annotation(testAnnotation)")
public void myBeforeLogger(JoinPoint joinPoint,TestAnnotation testAnnotation)
{
    System.out.println("Okay - we're in the before handler...");
    System.out.println("The test annotation value is: " + testAnnotation.value());
    Signature signature = joinPoint.getSignature();
    String methodName = signature.getName();
    String stuff = signature.toString();
    String arguments = Arrays.toString(joinPoint.getArgs());
    logger.info("Write something in the log... We are just about to call method: "
    + methodName + " with arguments " + arguments + "\nand the full toString: "
    + stuff);
}

}

ApplicationContext.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"    
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/aop 
            http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
    http://www.springframework.org/schema/beans 
            http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
    http://www.springframework.org/schema/context 
            http://www.springframework.org/schema/context/spring-context.xsd">

<aop:aspectj-autoproxy/>

<context:component-scan base-package="pack.bl.Person"/>

*注意: LogLevel 是一个枚举。所以它需要像那样工作,当我跑步时 程序并设置人名,首先需要进入Aspect类中的'BeforeAdvice'(因为setName,用@testAnnotation注解)方法,然后执行这个方法。它需要回到 setName 方法并设置人名。*

还有一件事,testAnnotation 是我创建的一个 Annotation

【问题讨论】:

    标签: java spring aop aspectj spring-aop


    【解决方案1】:

    你没有提到任何关于你如何编织你的问题。从我所见,看起来您将作业委托给了 Spring 容器。但是你使用的是 Spring AOP 而不是 AspectJ。尽管您也可以将 AspectJ 注释与 Spring AOP 一起使用。

    我的建议是你把它分成两种情况。首先确保编织 AspectJ 方面并使用仅使用System.out.println(..) 的简单建议方法,然后确保 Spring 配置与您的方面和日志枚举集成。

    使用 AJDT Eclipse 插件

    要启用 AspectJ 编织,最简单的替代方法是使用 AspectJ plugin 并使用编译时编织。在您右键单击您的项目并启用 AspectJ 特性后,您将在代码中看到编织建议的橙色箭头。请参见下图以获取示例。

    我不确定你的切入点是否有效。如果你的建议没有在任何地方编织,你应该尝试这个切入点:

    @Pointcut("execution(@pack.aop.TestAnnotation * *(..)) ")
    public void logMethod() {}
    

    并这样建议:​​

    @Before("logMethod()")
    public void beforeLogMethod(JoinPoint joinPoint) {
        System.out.println("Logging..");
    }
    

    将方面和枚举与 Spring 容器集成

    其次,由于切面是在 Spring 容器之前创建的,因此您必须从切面的工厂方法Aspects.aspectOf(pack.aop.BeforeAdvice.class) 中检索切面,或者在 Spring 配置中使用工厂方法。

    从 Spring XML 配置中,您可以像这样检索方面(对象):

    <bean id="beforeAdvice" class="apack.aop.BeforeAdvice"
        factory-method="aspectOf" />
    

    您还必须使用工厂方法来检索在 Spring 容器之外创建的记录器。

    我已经写了一个相关的blog post,用一个例子解释了你的大部分问题,以及 AJDT Eclipse 插件工作的优雅程度。

    图像显示了两个箭头,说明了一个后建议,最后一个箭头说明了一个环绕建议。

    【讨论】:

    • 感谢您的回复,我的程序是基于java.dzone.com/articles/using-springs-aspectj-supportthoughtforge.net/665/… 的那些tutrial 示例,所以我不明白为什么它不能正常工作
    • 本教程使用Spring AOP。编织过程发生在运行时。它只使用一些 AspectJ 类,但不使用在加载时或编译时发生的 AspectJ 编织。
    • 那么,如果编织过程发生在运行时,它应该到达 BeforeAdvice Aspect,不是吗?
    • 这只是我正在尝试做的一个例子。我有一个带有一些自定义对象(它们是线程)的 java 应用程序,每个对象都有自己的日志文件。因此,当事件发生时,我需要将其记录在特定的日志文件中。因此,我使用了那些 tutrial 示例
    • 关于你的标题,我会推荐这个例子:eclipse.org/ajdt/demos/HelloWorldAspectJ.html。 AJDT 插件非常好,可以帮助您学习面向方面的编程。在它工作之后,您可以从 AspectJ weaving 更改为 Spring AOP,移除 AspectJ 特性并在 Spring 配置中添加一些行。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-06-29
    • 2021-06-28
    • 1970-01-01
    • 2014-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多