Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[AOP]: ConstructorInterceptor is not working #11044

Closed
HristoP96 opened this issue Aug 1, 2024 · 4 comments
Closed

[AOP]: ConstructorInterceptor is not working #11044

HristoP96 opened this issue Aug 1, 2024 · 4 comments
Labels
closed: notabug The issue is not a bug

Comments

@HristoP96
Copy link

HristoP96 commented Aug 1, 2024

Expected Behavior

A class implementing the ConstructorInterceptor should be able to intercept the respective object's contrusctor pre/post its invoke, based on the InterceptorBinding of the advice that the interceptor is listening to throught the InterceptorBean.

Actual Behaviour

A class implementing the ConstructorInterceptor is not intercepting consctructors on/post/pre object creation.

Steps To Reproduce

  1. Clonse this repo https://github.com/HristoP96/aop-demo-1
  2. Run the project
  3. Watch the console

Expected behavior:
After a Product contsructor is invoked, the interceptor should print "Product created" and afterwards the program should print Is my product favorite false

Actual behavior:
The program only prints Is my product favorite null

Environment Information

  • Windows 11
  • JDK 17

Example Application

https://github.com/HristoP96/aop-demo-1

Version

4.4.2

@nilols
Copy link

nilols commented Aug 1, 2024

I think the problem here is that new Product() in the ApplicationEventListener circumvent everything, you probably need a @Factory or something that can create Product beans for the interceptor to work (so that you create the bean through micronaut)

I did a quick test by changing your example a bit

@Singleton
public class OnStart implements ApplicationEventListener<StartupEvent> {
    @Inject
    ProductService productService;

    @Override
    public void onApplicationEvent(StartupEvent event) {
        productService.addProduct(event.getSource().createBean(Product.class)); // <-- here
        System.out.printf("Is my product favorite %s%n", productService.getProduct(0).getFavorite());
    }
}
@Singleton
@InterceptorBean(FavouriteSetter.class)
public class FavouriteInterceptor implements ConstructorInterceptor<Product> {

    @Override
    public @NonNull Product intercept(@NonNull ConstructorInvocationContext<Product> context) {
        Product target = context.proceed(); // <--- and here 
        System.out.println("Product created");
        try {
            Field field = target.getClass().getDeclaredField("favorite");
            field.setAccessible(true);
            field.set(target, false);
        } catch (NoSuchFieldException | IllegalAccessException e) {
            e.printStackTrace();
        }
        return target;
    }
}

and my output is

Product created
Is my product favorite false

@graemerocher graemerocher added the closed: notabug The issue is not a bug label Aug 3, 2024
@graemerocher
Copy link
Contributor

constructor interception cannot work when you directly use new as described in the previous comment

@rsalbergaria
Copy link

rsalbergaria commented Oct 28, 2024

Hello,

I am trying to use the solution mentioned. However, I am encountering an issue where instantiating a Product bean using Named does not work as expected, and the interceptor is not being triggered.

Here is the code I am using:

`
@singleton
public class ProductServiceApplication {

private final ProductService productService;
private final Product product;

public ProductServiceApplication(ProductService productService, @Named("teste") Product product) {
    this.productService = productService;
    this.product = product;
}

public void addProduct() {
    productService.addProduct(product);
}

public Product getProduct(int index) {
    return productService.getProduct(index);
}

}

`

Caused by: io.micronaut.context.exceptions.NoSuchBeanException: No bean of type [com.example.stuff.Product] exists for the given qualifier: Named('teste').

When I attempt to instantiate a Product bean using the Named annotation, the dependency injection fails with the error above. Additionally, it seems that using Named prevents the interceptor from being triggered.

Question: Is it possible to use Named in this context and still have the interceptor work as expected? If so, could you provide guidance on how to achieve this?

@rsalbergaria
Copy link

rsalbergaria commented Oct 29, 2024

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
closed: notabug The issue is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants