首页 > 解决方案 > 未触发 Setter 的 Spring 建议

问题描述

我有这个下面的代码。即使调用了 setter,也不会触发关于 setter 的建议。我可以在控制台中看到它

如果我对 String getName() 提出建议,一切正常。但它不适用于 setter public void setName(String name)。

春天.xml

<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/beans
           http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
           http://www.springframework.org/schema/context
           http://www.springframework.org/schema/context/spring-context-3.1.xsd
           http://www.springframework.org/schema/aop 
           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

    <aop:aspectj-autoproxy />
    <bean id="cust" class="aspectJ.Customer">
        <property name="name" value="logging" />

    </bean>
    <bean id="aspect" class="aspectJ.LoggingAspect"/>
</beans>

记录 ASPECT

@Aspect
public class LoggingAspect {

    @Before("allgetters()")
    public void printAspect() {
        System.out.println("Aspect Running");
    }


    @Before("allgetters()")
    public void printAspectTwo() {
        System.out.println("Aspect TWO Running");
    }

    @Pointcut("execution(public void setName(*))")
    public void allgetters() {
    }
}

客户类

package aspectJ;

public class Customer {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
        System.out.println("SETTER CALLED");
    }

}

主班

public class MainClass {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
        Customer obj = (Customer) context.getBean("cust");

    }

}

标签: springspring-aopaspect

解决方案


您的方面签名是错误的。

*将匹配单个字段

..将匹配零个或多个字段

示例 1

com.stackoverflow.*.Customer.setName(..)

匹配以 com.stackoverflow 开头并以 Customer 结尾的所有包。通配符只会匹配一个包名。该方法可以接受零个或多个参数。以下是它将匹配的三个示例:

com.stackoverflow.question.Customer.setName()
com.stackoverflow.question.Customer.setName(String arg1)
com.stackoverflow.question.Customer.setName(String arg1, String arg2)

示例 2

com..Customer.setName(*, *)

匹配所有以 com 开头并以 Customer 结尾的包。接受带有两个任意类型参数的方法。下面是两个将匹配的示例。请注意,通配符将接受任意数量的包。

com.example.Customer.setName(String arg1, Object arg2)
com.stackoverflow.question.Customer.setName(Integer arg1, Double arg2)

您应该将您的更改allgetters()为以下内容:

@Pointcut("execution(public void setName(..))")
public void allgetters() {
}

Spring AOP 仅适用于 Spring 管理的 bean。bean 在初始化之前不会被管理,无论它是用 Java 还是 XML 定义的。

//The Customer object returned by this method is managed.
//The Customer object within the method is not managed
@Bean
public Customer createCustomer(){
    //This is a pure Java object 
    Customer customer = new Customer();
    //The object is not yet managed. This method call will therefore never be intercepted by your Pointcut.
    customer.setName(“John Doe”);
    return customer;
}

从文档中引用:

Spring AOP 仅支持 Spring bean 的方法执行连接点,因此您可以将切入点视为匹配 Spring bean 上的方法执行。


推荐阅读