简体   繁体   English

不由 Spring 管理的域对象上的 AspectJ 切入点表达式

[英]AspectJ Pointcut Expression on domain objects not managed by Spring

Question: Can Spring point-cut expressions run on non-managed spring components such as domain object?问: Spring切入点表达式可以运行在域对象等非托管Spring组件上吗? From my experiments looks like it doesnt, so what is the best way to run pointcut expressions on a regular object?从我的实验来看似乎没有,那么在常规对象上运行切入点表达式的最佳方法是什么?

I created custom annotation name @Encrypt, so that when it is used on top of a field in a domain object, the field is sent to a web service and is automatically encrypted.我创建了自定义注释名称 @Encrypt,以便在域对象中的字段之上使用它时,该字段将发送到 Web 服务并自动加密。

I first started with method level annotation, and found that point cut expression doesn't work on Objects not managed by Spring, it has to be a spring bean.我首先从方法级别的注释开始,发现切点表达式不适用于不是由 Spring 管理的对象,它必须是一个 spring bean。

1. Spring Aspect: Checks for custom annotation @Encrypt and prints out. 1. Spring Aspect:检查自定义注解@Encrypt 并打印出来。

@Aspect
public class EncryptAspect {

    @Around("@annotation(encrypt)")
    public Object logAction(ProceedingJoinPoint pjp, Encrypt encrypt)
            throws Throwable {

        System.out.println("Only encrypt annotation is running!");
        return pjp.proceed();
    }
}

2. Custom Annotation: 2. 自定义注解:

@Documented
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)

public @interface Encrypt
{
    // Handled by EncryptFieldAspect
}

3. Domain object using Annotation 3. 使用注解的域对象

public interface CustomerBo {
    void addCustomerAround(String name);
}

public class CustomerBoImpl implements CustomerBo {    
    @Encrypt
    public void addCustomerAround(String name){
        System.out.println("addCustomerAround() is running, args : " + name);
    }
}

4. Invocation 4. 调用

        ApplicationContext appContext = new ClassPathXmlApplicationContext("http-outbound-config.xml");
//      CustomerBoImpl customer = new CustomerBoImpl(); --> Aspect is not fired if object is created like this.
        CustomerBo customer = (CustomerBo) appContext.getBean("customerBo"); // Aspect Works
        customer.addCustomerAround("test");

To your first question ("Can Spring point-cut expressions run on non-managed spring components such as domain object?") the answer is no.对于您的第一个问题(“Spring 切入点表达式能否在域对象等非托管 Spring 组件上运行?”),答案是否定的。 Spring reference manual has a chapter that exactly explains how Spring AOP works and why it won't work in that case . Spring 参考手册有一章准确地解释了 Spring AOP 如何工作以及为什么它在这种情况下不起作用

The options I see are (in order of how I would most likely approach this issue):我看到的选项是(按照我最有可能处理这个问题的方式):

  1. Droping the aspect and encapsulating this invariant in a service or a factory that creates CustomerBo 's.删除方面并将此不变量封装在创建CustomerBo的服务或工厂中。 It would be best, if CustomerBoImpl was immutable, so that you would not have to worry that it will be decrypted and left in that incorrect state.如果CustomerBoImpl是不可变的,那就最好了,这样您就不必担心它会被解密并处于错误状态。
  2. If you are using Java Persistence API (JPA) to persist your domain objects, and if it is ok for the encryption to run just before saving them in the database, you may want to use listeners .(Note: the link leads to the documentation of Hibernate, which is one of the implementations of JPA)如果您使用 Java Persistence API (JPA) 来持久化域对象,并且可以在将它们保存到数据库之前运行加密,那么您可能需要使用listeners 。(注意:链接指向文档Hibernate,这是JPA的实现之一)
  3. The nuclear option - actually switching to using AspectJ which can introduce advice to constructors, field value changes etc.核心选项 - 实际上切换到使用 AspectJ,它可以向构造函数、字段值更改等引入建议。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM