David Tinker
David Tinker

Reputation: 9634

How can I limit Spring component scan to only files in my war?

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?

Upvotes: 7

Views: 6929

Answers (5)

Joshua Wilson
Joshua Wilson

Reputation: 2526

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

Upvotes: 3

What if you specify

<context:component-scan base-package="com.myapp" resource-pattern="/WEB-INF/classes/**/*.class"/>

or some alternative of this approach?

Upvotes: 2

sourcedelica
sourcedelica

Reputation: 24040

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.

Upvotes: 2

abalogh
abalogh

Reputation: 8281

Two tips;

  • try to be as specific with the base-package(s) as you can: you can provide several packages in the base-package attribute, separated by commas.
  • use filters; check docs here. - you can specify annotations which are to be scanned (e.g. if you only use @Component) and you also can specify a regex which the classname will have to match.

Upvotes: 3

Shaun Hare
Shaun Hare

Reputation: 3871

Can you not just be more specific with your base package directive ?

Upvotes: 0

Related Questions