-
Notifications
You must be signed in to change notification settings - Fork 38.3k
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
Register http interface beans with the right package #29973
Comments
What are you trying to achieve exactly? It seems you are working on a wrong assumption. There's no real "registering of a package" for beans, and what you obtain (through custom code) is merely the raw Spring Framework makes extensive and transparent use of proxies. Note that this can be influenced in various ways, including The difference in "package names" you noticed is due to the presence of proxies, and to the fact that some are This issue is thus more of a question, which should preferably be on StackOverflow. Nevertheless, I've compiled some information on how to deal with the proxies below:
JDK proxies work on one or more interfaces. The fact that it can work on multiple interfaces is a likely reason why it can't generate a proxy class in the target class' package (since there is potentially multiple arbitrary candidate packages).
Now, how to accommodate proxies in that code that lists bean names and "packages"? You could try to use
It would look like this: record BeanInformation(String beanName, String packageName, String beanClass) {};
final List<BeanInformation> beans = new ArrayList<>();
final String[] names = beanFactory.getBeanDefinitionNames();
for (String name : names) {
final Object bean = beanFactory.getBean(name);
Class<?> targetClass = AopUtils.getTargetClass(bean);
if (AopUtils.isJdkDynamicProxy(bean)) {
Class<?>[] proxiedInterfaces = AopProxyUtils.proxiedUserInterfaces(bean);
Assert.assertTrue("Only one proxied interface expected", proxiedInterfaces.length == 1);
targetClass = proxiedInterfaces[0];
}
beans.add(new BeanInformation(name, targetClass.getPackageName(), targetClass.getSimpleName()));
}
beans.forEach(info -> System.err.println(info.beanName() + " -> " + info.beanClass() + " in package " + info.packageName())); If you only want to deal with
|
Good morning @simonbasle, First, I would like to give you thanks because I was wrong in my approach and obviously, I don´t have that expertise in Proxies. Said it, I will continue learning about Spring and the part about Proxies because it is a gap in my side. Many thanks Juan Antonio |
When a Developer defines a
http interface
, the new feature released in Spring Boot 3:https://docs.spring.io/spring-framework/docs/current/reference/html/integration.html#rest-http-interface
The Bean is not registered in the
Spring Container
with the right package:Example:
Http Interface definition:
Http Interface configuration:
And you list all Beans running in the Spring Boot Container:
then the User Bean generated by a http interface is not registered with the right java package:
The right package should be in the example:
or
At the moment, all beans generated by the user, are registered with the right package for the annotations: @SpringBootApplication, @RestController, @service, @configuration & @bean:
But not the Bean registered by a http interface using the HttpServiceProxyFactory:
spring-framework/spring-web/src/main/java/org/springframework/web/service/invoker/HttpServiceProxyFactory.java
Line 99 in ac521a3
How to reproduce the scenario?
https://github.com/jabrena/spring-boot-http-client-poc/blob/main/src/test/java/info/jab/ms/BeanInventoryTests.java#L26-L44
Many thanks in advance
Juan Antonio
The text was updated successfully, but these errors were encountered: