Skip to content

Support for creating AOP proxies at Runtime if necessary#12223

Merged
dstepanov merged 3 commits into
5.0.xfrom
runtimeproxy
Nov 27, 2025
Merged

Support for creating AOP proxies at Runtime if necessary#12223
dstepanov merged 3 commits into
5.0.xfrom
runtimeproxy

Conversation

@dstepanov

@dstepanov dstepanov commented Nov 26, 2025

Copy link
Copy Markdown
Contributor

When annotating with @RuntimeProxy(MyCreator.class) we will not generate a proxy class that intercept the bean, instead we allow for the proxy to be created at the runtime.
Use-cases:

  • proxy implemented using bytebuddy - test included
  • proxy implemented using Java Proxy reflection - only for interfaces - test include
  • Mockito mock / spy proxies

In this case we will generate only the bean definition without a proxy implementation:

    public Object instantiate(BeanResolutionContext resolutionContext, BeanContext context) {
        return ((ByteBuddyRuntimeProxy)resolutionContext.getBean(ByteBuddyRuntimeProxy.class)).createProxy(DefaultRuntimeProxyDefinition.introduction(resolutionContext, this));
    }

@sdelamo sdelamo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dstepanov Can you provide a PR description that describes why we need this PR?

@sdelamo sdelamo added this to 5.0.0-M2 Nov 26, 2025
@github-project-automation github-project-automation Bot moved this to Backlog in 5.0.0-M2 Nov 26, 2025
@sdelamo sdelamo added this to the 5.0.0-M1 milestone Nov 26, 2025
Comment thread aop/src/main/java/io/micronaut/aop/DefaultRuntimeProxyDefinition.java Outdated
* @param <T> The proxied bean type
* @return The proxy instance
*/
<T> T createProxy(RuntimeProxyDefinition<T> proxyDefinition);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if I don't need proxying how would I return the original bean?

@dstepanov dstepanov Nov 26, 2025

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing is created at this moment, so you instantiate it yourself with the constructor values provided or if it's the target proxy you have to get it from the proxy definition

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To explain it a bit more, we have two ways of generating a proxy; with a proxy target or without.
With a proxy target we get the target bean instance from the bean context, and delegate the non-intercepted call to it. In a case of a no-proxy-target we simply extend the class and create an extra methods that do the super-call.
If you don't want to override the class at the runtime, you will need to add @Around(proxyTarget=true)

*
* @return The runtime proxy creator bean class
*/
Class<? extends RuntimeProxyCreator> value();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could we have something in this annotation that activates @Around(proxyTarget=true) behaviour

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can add proxyTarget to it

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added


@Singleton
@NullMarked
public class JdkRuntimeProxy implements RuntimeProxyCreator {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would be good to add a test Groovy implementation that returns the original instance and uses runtime Groovy meta-programming to replace the method and proxy instead. This will further validate what we are trying to achieve. See https://groovy-lang.org/metaprogramming.html#metaprogramming_emc

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added

@sonarqubecloud

Copy link
Copy Markdown

Quality Gate Failed Quality Gate failed

Failed conditions
61.4% Coverage on New Code (required ≥ 70%)
2 New Bugs (required ≤ 0)

See analysis details on SonarQube Cloud

Catch issues before they fail your Quality Gate with our IDE extension SonarQube for IDE

@graemerocher graemerocher changed the title Runtime proxies Support for creating AOP proxies at Runtime if necessary Nov 27, 2025
@graemerocher graemerocher added the type: enhancement New feature or request label Nov 27, 2025
@dstepanov dstepanov merged commit 7bb88cd into 5.0.x Nov 27, 2025
14 of 15 checks passed
@dstepanov dstepanov deleted the runtimeproxy branch November 27, 2025 13:28
@github-project-automation github-project-automation Bot moved this from Backlog to Done in 5.0.0-M2 Nov 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

type: enhancement New feature or request

Projects

No open projects
Status: Done

Development

Successfully merging this pull request may close these issues.

3 participants