关于二传手的春季建议未触发

时间:2018-07-07 16:59:33

标签: spring spring-aop aspect

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

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

spring.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");

    }

}

2 个答案:

答案 0 :(得分:2)

您的方面签名错误。

*将匹配一个奇数字段

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

示例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;
}

Quote from the documentation:

  

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

答案 1 :(得分:0)

只需发布用户 @javamusings 所说的

仅当在Java类中调用设置程序时,才调用建议。在Aspectj.xml中初始化属性时不会调用它