首页 文章

关于设定器的 spring 建议未触发

提问于
浏览
1

我有以下代码 . 即使调用了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>

Logging 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() {
    }
}

CUSTOMER CLASS

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");
    }

}

Main Class

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

    }

}

2 回答

  • 2

    您的方面签名是错误的 .

    * 将匹配一个奇异的字段

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

    Example 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)
    

    Example 2

    com..Customer.setName(*, *)
    

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

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

    You should change your allgetters() to the following:

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

    Spring AOP仅适用于Spring管理的bean . 在初始化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上方法的执行 .

  • 0

    只是发布什么用户 @javamusings:

    只有在Java类中调用setter时才会调用该通知 . 在aspectj.xml中初始化属性时不会调用它

相关问题