0

I have a class Book:

package book;
public class Book {
    private String title;
    public Book(String title) {
        this.title = title;
    }
    public boolean equals(Object object) {
        if(object instanceof Book) {
             Book book = (Book) object;
             return this.title.equals(book.title);
        }
        return false;
    }
}

This is my Aspect class and Configuration class:

package book;
@Aspect
@Component
public class Logging {
    @Pointcut("execution(* java.lang.Object.equals(..))")
    private void equals() {}

    @Before("equals()")
    public void log() {
        System.out.println("logging...");
    }
}

package book;
@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class Config {
}

And this is my test class:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = Config.class)
public class LoggingTest {
    @Value("#{new book.Book('book1')}")
    private Book book;

    @Value("#{new book.Book('book2')}")
    private Book book2;

    @Test
    public void test() {
        assertFalse(book.equals(book2));
    }
}

This test class run successfully. but the expected logging... was not printed. Could you please tell me what's wrong in my code?

Thanks in advance!

cb4
  • 6,689
  • 7
  • 45
  • 57
walsh
  • 3,041
  • 2
  • 16
  • 31

1 Answers1

1

Spring AOP is not the same as AspectJ. Spring AOP has a lot of limitations compared to AspectJ and it's only applied to Spring managed beans. Your Book objects created with the script expressions withing the @Value annotations are not Spring managed beans, hence no AOP functionality is applied to them.

Nándor Előd Fekete
  • 6,988
  • 1
  • 22
  • 47
  • I add two beans of type `Book` using `@Bean` in the `Config` class and replace the `@Value` with `@Autowired`, but the expected `logging...` is also not printed. – walsh Nov 09 '16 at 01:07
  • I'd recommend using AspectJ instead of Spring AOP, especially since it seems you'll need it for non-spring managed classes. But if you want to stick with Spring AOP, you'll need to change `@EnableAspectJAutoProxy` to `@EnableAspectJAutoProxy(proxyTargetClass = true)`, since the `equals` method you're trying to intercept is not part of any interface your `Book` "service" will implement. – Nándor Előd Fekete Nov 09 '16 at 01:15
  • Thanks for quick reply! I add the attribute `proxyTargetClass = true`, but also not work. I also change the pointcut expression from `@Pointcut("execution(* java.lang.Object.equals(..))")` to `@Pointcut("execution(* book.equals(..))")`, unluckily, it aslo not work. – walsh Nov 09 '16 at 01:25
  • Where are you calling the `equals` method from? Inside the `Book` bean or from outside? With Spring AOP's proxy based AOP it will only get intercepted if it's called from outside. See this related answer for more details: http://stackoverflow.com/a/1606780/2699901 – Nándor Előd Fekete Nov 09 '16 at 01:41