Sometimes the answer to your problems is right in front of you. But somehow you just can’t grasp it until you’ve had a bit of an enlightenment experience. This happened to me a couple of weeks ago.

Dear Emily,

You know about Spring Beans, right? Sure, these are Java objects annotated with @Bean to make your application do something. And what about Spring Autoconfiguration? Ah, that’s a simple question as well. Spring Boot uses its imports file to load configuration beans automatically[1]. You can override these by defining your own beans of the same class if you want custom things to happen.

Sounds easy-peasy! But then in practice, I work with hundreds of repositories. Dozens of them are Spring projects, already configured and running in production beautifully. Of course, all these projects have to be maintained; upgrading to Spring Boot 3 is one of the tasks to keep them stable and secure.

So I was working together with a colleague on a project configured with Spring JMS. It had to be updated to Spring Boot 3 as well. After upgrading, we ran into some troubles. I honestly can’t remember what went wrong exactly, but that doesn’t matter for this story. Tutorial blogs like Getting Started with Spring JMS state you should define a DefaultJmsListenerContainerFactory bean to do your configuration:

public DefaultJmsListenerContainerFactory jmsListenerContainerFactory(ConnectionFactory connectionFactory) {
  var factory = new DefaultJmsListenerContainerFactory();
  // a lot more setters to configure the bean

  return factory;
I use the DefaultJmsListenerContainerFactory bean as example, but you can use following trick for all Spring Beans.

But this project did not define any bean by itself, it just used the original bean provided by the autoconfiguration. I could define those beans myself, but then I still was not sure if I understood the problem. Spring uses reflection to load it beans, so there is no 'link' to the original bean, thus you cannot click through to find the original code. For the beans you use in your code yourself, IntelliJ can help you out, as it scans the classpath and shows all linked beans next to the line number:

intellij objectmapper bean discovery

So where to debug? Well I could not figure it out…​ until I had a good night of sleep. The answer was surprisingly simple! Just temporarily use the bean somewhere in your code. Once you have a definition, IntelliJ will show the icon and you can click through:

intellij default bean discovery

I was a little flabbergasted it took me so long to realize this. But hey, I got my answer 😉.


1. You could create such file yourself in a library jar as well to make your own autoconfigured beans.