I am using Spring's component scan to find beans in my app.
<context:component-scan base-package="com.myapp"/>
However the performance when the app is deployed on our staging server (JBoss 5 with a lot of apps deployed) is much slower than in development (also JBoss 5 but few apps). The component scan takes a long time. I suspect this is due to a much larger classpath?
Is there an easy way to get Spring to only look for beans in my war file? i.e. WEB-INF/classes and WEB-INF/lib? Or is there another solution?
With Spring, we use the @ComponentScan annotation along with the @Configuration annotation to specify the packages that we want to be scanned. @ComponentScan without arguments tells Spring to scan the current package and all of its sub-packages.
To disable the default filter, set the useDefaultFilters element of the @ComponentScan annotation to false.
@EnableAutoConfiguration : enable Spring Boot's auto-configuration mechanism. @ComponentScan : enable @Component scan on the package where the application is located (see the best practices) @Configuration : allow to register extra beans in the context or import additional configuration classes.
A Classpath scanning basically means, detecting the classes that need to be managed by the Spring under a specified package. You need to make use of the spring @ComponentScan annotation with the @Configuration for classpath scanning.
Two tips;
I don't know if you have a solution in place but a colleague and I have a potential solution.
In full disclosure we work for Red Hat on the Snowdrop project, which provides support for Spring apps on JBoss.
The potential solution is to use a component-scan within snowdrop's jboss namespace - https://github.com/snowdrop/snowdrop/tree/CustomBeanScanner
Using that you could add the custom component scanner so instead of <context:component-scan base-package="foo.bar"/>
, you would use: <jboss:component-scan base-package="foo.bar"/>
.
We know it works but we don't know if anyone would want to change their application to make use of the feature. Is the intentional coupling worth the speed increase?
The code is out there on the branch listed above for anyone to try/use.
thanks, Joshua
You should set the classpath scanning settings to your package (eg. "com.foo"). However - the number of classes in your classpath should not be much different in staging versus development. It will be your WAR plus server-wide classes, which should be roughly the same. Specifically you will not have classes from other WARs in your classpath.
I suspect the server is overloaded. You should get some statistics from that machine: ie, what is the CPU utilization? Is there a lot of disk I/O? Is is paging/swapping excessively? Also check the memory utilization of the JVM - maybe it is spending a lot of time doing garbage collection.
What if you specify
<context:component-scan base-package="com.myapp" resource-pattern="/WEB-INF/classes/**/*.class"/>
or some alternative of this approach?
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With