1
votes

i have this below code . advice on setter is not triggered even though setter is called. i can see it in the console

if i do advice on String getName() everything works just fine. but its not working on 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 Answers

2
votes

Your aspect signature is wrong.

* will match a singular field

.. will match zero or multiple fields

Example 1

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

Matches all packages starting with com.stackoverflow and ending with Customer. The wildcard will only match one package name. The method can accept zero or more arguments. Below are three examples of what it will match:

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(*, *)

Match all packages starting with com and ending with Customer. Accept methods with two arguments of any type. Below are two examples of what it will match. Notice that the wildcard will accept any number of packages.

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 only works with beans managed by Spring. A bean is not managed until it is initialized, regardless if it is defined in Java or 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 only supports method execution join points for Spring beans, so you can think of a pointcut as matching the execution of methods on Spring beans.

0
votes

Just Posting what user @javamusings said :

The advice is called only when the setter is called in the Java class. It is not called when the property is initialized in the aspectj.xml