【问题标题】:How can I make this @Pointcut expression work?我怎样才能使这个@Pointcut 表达式起作用?
【发布时间】:2013-05-06 04:31:54
【问题描述】:

我在使用切入点表达式建议方法时确实遇到了问题。 我有以下配置:

春季 3.1.2.RELEASE

pom.xml

    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aop</artifactId>
      <version>${org.springframework.version}</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjrt</artifactId>
        <version>1.7.2</version>
    </dependency>
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.7.2</version>
    </dependency>

servlet.xml

    <aop:aspectj-autoproxy/>

我想建议的班级

@Repository(value="userDaoImpl")
@Transactional
public class UserDaoImpl implements UserDao{

    //attributes and methods

    @Override
    public void delete(ProfiledUser user) throws HibernateException
    {
        sessionFactory.getCurrentSession().delete(user);        
    }
}

它实现了 UserDao 接口,它扩展了 GenericDao&lt;T&gt; 接口

这是我的建议

@Aspect
@Component("userDeletionAspect")
public class UserDeletionAspect {

    @Pointcut("execution(public void aa.bb.cc.dd.UserDaoImpl.delete(..))")
    public void objectDeletionPointcut(){}

    @Before("objectDeletionPointcut()")
    public void notifyDeletion(JoinPoint jp)
    {       
        System.out.println("pointcut executed");
    }
}

这是行不通的。就是说UserDaoImpl的delete方法在执行的时候根本不会被拦截。

从 Spring 文档中,我了解到 spring 代理 与接口一起工作,因此我尝试将切入点定义更改如下:

  @Pointcut("execution(* aa.bb.cc.dd.GenericDao.delete(..))")

但没有任何改变。 如何拦截UserDaoImpl类的.delete()方法?

【问题讨论】:

  • 请从您的问题中删除重复的“objectDeletionPointcut”;)
  • @MarkusCoetzee 完成 :-)

标签: spring spring-aop pointcut


【解决方案1】:

你需要

<aop:aspectj-autoproxy>
    <aop:include name="userDeletionAspect"/>
</aop:aspectj-autoproxy>

而不是

<aop:aspectj-autoproxy/>

仅供参考 - 您可以在切入点表达式中定位具体类或特定接口的实现。

Spring 只能针对公共方法,因此您可以从切入点表达式中删除“公共”部分。此外,如果您愿意,可以像这样声明您的建议以及切入点表达式:

@Before("execution(void aa.bb.cc.dd.UserDaoImpl.delete(..))")
public void notifyDeletion(JoinPoint jp) {       
     System.out.println("pointcut executed");
}

您现在应该可以开始了,但是如果您仍然遇到一些问题,这里有一个使用 Spring AOP 的简单日志记录示例 - logging with AOP in spring?

【讨论】:

  • 不幸的是,即使按照您的建议更改代码我仍然无法拦截该 delete() 方法。我在 Dao 类级别使用 @Trasactional 注释,因此所有 Dao 方法(包括我的 delete() 方法)都已由 TransactionInterceptor 类代理。它会影响我的拦截尝试吗?
  • 添加事务注释不会导致任何问题。在我的 Spring MVC 应用程序中,我成功地将一些建议定位在我的控制器上,这些建议用 @Transactional 注释。首先,您的“servlet.xml”是您的应用程序上下文吗?其次,您是否配置了 Spring 来扫描您的 UserDeletionAspect 类的包,以便它可以将其作为 bean 添加到容器中?
  • 宾果游戏!我的 Dao 类使用 @Repository 原型进行了注释,并且......他们完成了他们的工作,所以我认为他们以某种方式注册到了容器中。对于 AOP 来说,这似乎还不够。我添加了&lt;context:component-scan base-package="xx.yy.zz.dao" /&gt;,一切都像魅力一样。我只是有点担心这些课程会被注册两次。
  • 我很高兴你让它工作了 :) 除非你告诉 Spring 在它们各自的包中扫描它们,否则带注释的类不会被添加到容器中,所以你不必担心它是注册了两次。但是假设您将存储库声明为 XML 中的 bean 并对其进行注释,并且您告诉 Spring 扫描它的包,那么当您的应用程序上下文启动时您可能会遇到问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多