Print all the Spring beans that are loaded
Yes, get ahold of ApplicationContext
and call .getBeanDefinitionNames()
You can get the context by:
- implementing
ApplicationContextAware
- injecting it with
@Inject
/@Autowired
(after 2.5) - use
WebApplicationContextUtils.getRequiredWebApplicationContext(..)
Related: You can also detect each bean's registration by registering a BeanPostprocessor
bean. It will be notified for each bean.
Print all the Spring beans that are loaded - Spring Boot
As shown in the getting started guide of spring-boot: https://spring.io/guides/gs/spring-boot/
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Bean
public CommandLineRunner commandLineRunner(ApplicationContext ctx) {
return args -> {
System.out.println("Let's inspect the beans provided by Spring Boot:");
String[] beanNames = ctx.getBeanDefinitionNames();
Arrays.sort(beanNames);
for (String beanName : beanNames) {
System.out.println(beanName);
}
};
}
}
As @Velu mentioned in the comments, this will not list manually registered beans.
In case you want to do so, you can use getSingletonNames(). But be careful. This method only returns already instantiated beans. If a bean isn't already instantiated, it will not be returned by getSingletonNames()
.
List all my beans loaded by SpringApplication.run
Using ConfigurableApplicationContext
you can get all bean types. For example:
@Autowired
ConfigurableApplicationContext context;
.....
ConfigurableListableBeanFactory beansFactory = context.getBeanFactory();
String[] beansNames = beansFactory.getBeanDefinitionNames();
Set<String> beansType = new HashSet<>();
for(String beanName : beansNames){
if (beanName.matches("(.*)Controller")){
beansType.add(beansFactory.getType(beanName).toString());
}
}
Other easier option to show all the beans is
In the case you are using spring-web You could use Spring boot actuator
. Add the next dependency in your pom.xml
and go to the /bean
endpoint to show all beans, and it will put the name of the bean and the class.
Check which beans have loaded in spring context
At startup, Spring logs at info level the names of all the beans being loaded by a context. Or in code, you can use getBeanDefinitionNames()
to get all the bean names.
How to list all loaded Spring bean definition files
When starting a ClassPathXmlApplicationContext
or more generally an AbstractXmlApplicationContext
, an XmlBeanDefinitionReader
will be used to load your xml files.
Each time an xml file will be loaded, to be precise before it gets loaded, you'll have a log (info) from loadBeanDefinitions(EncodedResource encodedResource)
:
if (logger.isInfoEnabled()) {
logger.info("Loading XML bean definitions from " + encodedResource.getResource());
}
If you can't rely on this information you can play with ReaderEventListener
:
public class TrackingImportXmlApplicationContext extends ClassPathXmlApplicationContext {
private static final TrackingImportReaderEventListener trackingImportReaderEventListener = new TrackingImportReaderEventListener();
public TrackingImportXmlApplicationContext(String configLocation) {
super(configLocation);
}
public TrackingImportXmlApplicationContext(String... configLocations) {
super(configLocations);
}
@Override
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
super.initBeanDefinitionReader(reader);
reader.setEventListener(trackingImportReaderEventListener);
}
public TrackingImportReaderEventListener getTrackingImportReaderEventListener() {
return trackingImportReaderEventListener;
}
public static class TrackingImportReaderEventListener extends EmptyReaderEventListener {
private final Set<String> imports = new HashSet<>();
@Override
public void importProcessed(ImportDefinition importDefinition) {
imports.add(importDefinition.getImportedResource());
}
public Set<String> getImports() {
return imports;
}
}
}
And then :
public class Main {
public static void main(String[] args) {
TrackingImportXmlApplicationContext applicationContext = new TrackingImportXmlApplicationContext("/META-INF/applicationContext.xml");
TrackingImportXmlApplicationContext.TrackingImportReaderEventListener tracking = applicationContext.getTrackingImportReaderEventListener();
for (String _import : tracking.getImports()) {
System.out.println(" >>> imported : " + _import);
}
}
}
In this later solution you'll only have imported file, but of course you already know your initial xml file(s)
How can I check if a bean has been loaded by springboot
The below code will log all the beans being loaded by spring application in its container:-
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private ApplicationContext appContext;
public static void main(String[] args) throws Exception {
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... args) throws Exception {
String[] beans = appContext.getBeanDefinitionNames();
Arrays.sort(beans);
for (String bean : beans) {
System.out.println(bean);
}
}
}
In spring are all the beans created at the time of container creation
By default yes. All beans get created on startup. There's the @Lazy
annotation which allows you to delay the initialization until the bean gets used.
View all Spring Configuration files loaded so far
You can use ApplicationContext#getBeansWithAnnotation
. It will not only take classes with @Configuration
annotation but also classes annotated with annotations meta-annotated with @Configuration
, like @SpringBootApplication
:
@Bean
ApplicationRunner applicationRunner(ApplicationContext applicationContext) {
return args -> {
applicationContext.getBeansWithAnnotation(Configuration.class)
.entrySet()
.stream()
.filter(entry -> entry.getValue().getClass().getPackage().getName().startsWith("com.your.package"))
.forEach(entry -> {
System.out.println("name: " + entry.getKey() + ", bean: " + entry.getValue());
});
};
}
Print non-managed Spring bean name
Here my understading it that bean will live in Spring Container till i
shutdown the server
Your understanding is wrong it will die with the request i.e. the scope of the object is within that method(processBean
) only. The container will NOT manage your bean. Apart from that, there is no sense in using
@Autowired
in your non managed bean. Since container doenn't manage it it will be null (unless you inject it using beanFactory.autowireBean();
) and therefore answer to your question that if you can print any such bean using spring services is NO
How to Lazy load all the Spring beans whether it is defined by @Bean or @Component in Springboot 2.2
I think you misunderstood the meaning of the lazy
flag you are passing,
It means that the object will be created only when it is invoked but it does not say that it will not scan that package. Spring will scan all packages and store bean definition names but it will create the objects only when it is invoked, if you have passed the lazy
flag to it.
You can verify this behaviour by checking the number of beans created when you pass the lazy
flag as true and false.
you can check it as given below
ApplicationContext context = SpringApplication.run(SpringBootApplication.class, args);
System.out.println("count:"+context.getBeanDefinitionCount());
Edit on Apr/7th 2020 start
Another way to do that is create a constructor and use that to inject the autowired properties and print out a log when they enter the constructor.
I did the same in a sample project and below is he result, first one is for eager initialization and next one for lazy.
spring.main.lazy-initialization=false
Application logs
Inside Constructor
calling bean
inside bean method
spring.main.lazy-initialization=true
Application logs
calling bean
Inside Constructor
inside bean method
Edit on Apr/7th 2020 end
Please mark this as answered if I answered your question.
Thank you
Related Topics
@Generatedvalue Polymorphic Abstract Superclass Over MySQL
Create Whole Path Automatically When Writing to a New File
How Does Java Garbage Collector Handle Self-Reference
Sslhandshakeexception: No Subject Alternative Names Present
Detect Enter Press in Jtextfield
Is There a Java Library to Access the Native Windows API
Pass Array to Oracle Procedure
Java Restfull Webservice: Jax-Rs Implementation with Jersey 2.3.1 Libraries
How to "Add" to Classpath Dynamically in Java
Jsoup Cookies for Https Scraping
Comparing Boxed Long Values 127 and 128
Is There a Java Equivalent to C#'s 'Yield' Keyword
Making a Log4J Console Appender Use Different Colors for Different Threads