使用注解的 Spring 3 的 AOP

发布于 2024-12-05 20:57:54 字数 2147 浏览 2 评论 0原文

我正在尝试让 Aspect 使用 Spring 3 和注释。

@Aspect
public class AttributeAspect {

  @Pointcut("@annotation(com.mak.selective.annotation.Attribute)")
  public void process(){
    System.out.println("Inside Process ....");
  }

  @Around("process()")
  public void processAttribute(){
    System.out.println("Inside Actual Aspect ..");
  }
}

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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans                 http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 <aop:aspectj-autoproxy proxy-target-class="false" />
<context:component-scan base-package="com.mak.selective.annotation.*" />
<bean name="attribute" class="com.mak.selective.annotation.AttributeAspect"/>
</beans>

我的测试来测试方面:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/springcontext/*.xml")
public class AttributeTest {

@Attribute(tableName = "firstTable", columnName = "New Column")
private void getAttribute() {
    System.out.println("Inside Attribute call...");
}

@Test
public void testAttributeAspect() {
    getAttribute();
}

}

使用此代码,我只能看到“内部属性调用...”,但方面看不到任何内容。 请指导。

<块引用> <块引用> <块引用> <块引用>

通过创建一个新对象(组件)并将其注入到 Junit 测试类中来实现此目的。

I am trying to get Aspect working with Spring 3 and annotations.

@Aspect
public class AttributeAspect {

  @Pointcut("@annotation(com.mak.selective.annotation.Attribute)")
  public void process(){
    System.out.println("Inside Process ....");
  }

  @Around("process()")
  public void processAttribute(){
    System.out.println("Inside Actual Aspect ..");
  }
}

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:p="http://www.springframework.org/schema/p"
xmlns:util="http://www.springframework.org/schema/util"
xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans                 http://www.springframework.org/schema/beans/spring-beans.xsd       http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
 <aop:aspectj-autoproxy proxy-target-class="false" />
<context:component-scan base-package="com.mak.selective.annotation.*" />
<bean name="attribute" class="com.mak.selective.annotation.AttributeAspect"/>
</beans>

MY Test to test the Aspect:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/springcontext/*.xml")
public class AttributeTest {

@Attribute(tableName = "firstTable", columnName = "New Column")
private void getAttribute() {
    System.out.println("Inside Attribute call...");
}

@Test
public void testAttributeAspect() {
    getAttribute();
}

}

With this code i can only see "Inside Attribute call..." but nothing from Aspect.
Please guide.

Got this working by making a new Object (Component) and injected to the Junit test class.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

儭儭莪哋寶赑 2024-12-12 20:57:54

很高兴看到您可以通过 XML 来实现它,但您也可以通过注释来实现它。

问题是 @Aspect 注释不是 Spring 构造型,因此扫描器不会将方面注册为 Spring Bean。只需在 @Aspect 上方或下方添加 @Service@Component 即可注册。

另外,可以直接命名 bean(例如,@Service("myNamedService")),也可以让它实现一个接口(例如,public class AttributeAspect Implements IAspect {),如下所示根据标准弹簧设计。

Good to see that you got it working from XML, but you could have also done it from annotations.

The issue is that the @Aspect annotation is not a Spring stereotype, so the scanner is not registering the aspect as a Spring Bean. Just add either @Service or @Component above or below @Aspect and it will be registered.

Also, either directly name the bean (e.g., @Service("myNamedService")) or have it implement an interface (e.g., public class AttributeAspect implements IAspect {), as per standard Spring design.

旧话新听 2024-12-12 20:57:54

如果您想在调用方法的同一个 bean 表单中拦截方法的调用,则需要使用真正的 AspectJ。 (如果 testAttributeAspect() 方法位于另一个 bean 中,您所做的应该可以工作。)


如何做真正的 AspectJ?

使用 AspectJ 编译器和编织器可以使用完整的 AspectJ 语言,第 7.8 节“在 Spring 应用程序中使用 AspectJ”对此进行了讨论。

@参见Spring 参考

You need to use real AspectJ if you want to intercept invocations of methods within the same bean form where it is invoked. (What you have done, should work if the method testAttributeAspect() is located in an other bean.)


How to do real AspectJ?

Using the AspectJ compiler and weaver enables use of the full AspectJ language, and is discussed in Section 7.8, “Using AspectJ with Spring applications”.

@See Spring Reference

铜锣湾横着走 2024-12-12 20:57:54

有几件事:

首先,当您围绕建议进行操作时,您需要像这样编写建议方法:

@Around(...)
public void aroundAdviceMethod(ProceedingJoinPoint pjp) throws Throwable {
    try {
        System.out.println("before...");
        pjp.proceed();
    }
    finally {
        System.out.println("After...");
    }
}

而且(这至少适用于您使用代理时,在您的情况下不完全确定),您放置的方法关于需要的建议是公开的(您的不是),spring管理(通过@Component或其他方式)并从类外部调用,以便代理可以生效(在您的示例中也不是这种情况)。所以你需要这样的东西:

@Component
public class SomeClass {
    @Attribute
    public void someMethodCall() {
        System.out.println("In method call");
    }
}

public class SomeUnitTest {
    @Autowired SomeClass someClass;
    @Test 
    public void testAspect() {
        someClass.someMethodCall();
    }
}

A few things:

Firstly, when you do around advice you need to write the advice method like this:

@Around(...)
public void aroundAdviceMethod(ProceedingJoinPoint pjp) throws Throwable {
    try {
        System.out.println("before...");
        pjp.proceed();
    }
    finally {
        System.out.println("After...");
    }
}

But also (and this at least applies when you're using proxies, not entirely sure in your case), the method you're putting advice on needs to be public (yours isn't), spring managed (via @Component or otherwise) and called external from the class so the proxy can take effect (also not the case in your example). So you need something like this:

@Component
public class SomeClass {
    @Attribute
    public void someMethodCall() {
        System.out.println("In method call");
    }
}

public class SomeUnitTest {
    @Autowired SomeClass someClass;
    @Test 
    public void testAspect() {
        someClass.someMethodCall();
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文