问题
Inside my library FooLibrary.jar
Spring instantiates class com.example.FooImpl
which has a property bars
. I have lots of Bar
instances also instantiated by Spring. A set of bars is autowired into FooImpl
like this:
@Component
public class FooImpl {
@Inject
private Set<Bar> bars;
In a standalone application, Spring instantiates the Bar
instances, instantiates the FooImpl
instances, and then autowires FooImpl.bars
with the set of Bar
s. It works.
Now I'm running the same Spring configuration in a webapp inside Tomcat. FooLibrary.jar
is inside WEB-INF/lib
, and everything continues to work as outlined above.
The problem is that the web app automatically compiles somes classes using JavaCompiler
, which can't find its dependencies for dynamically compiling unless I place that library on the startup Tomcat path. The minute I add FooLibrary.jar
to the Tomcat classpath (e.g. in in the launch configuration of Tomcat inside Eclipse, or I presume startup.sh
or setclasspath.bat
if running Tomcat standalone), autowire stops working.
That is, when my webapp starts up, Spring creates all the Bar
instances, then instantiates FooImpl
, but never autowires the set of Bar
s into FooImpl.bars
. Any idea why?
(Does it have something to do with the Spring ContextLoaderListener
being started from the webapp classloader, but the FooImpl
and Bar
instances coming from the Tomcat classloader, I wonder?)
回答1:
Autowiring can fail due to incompatible types (e.g. classes loaded in multiple classloaders).
Since you already place the JAR in tomcat's boot classpath, it must be visible to the webapp as well without you having to place the JAR in WEB-INF/lib.
You can make the dependency scope provided
to not have Maven place it in WEB-INF/lib.
来源:https://stackoverflow.com/questions/17029828/spring-autowire-stops-working-for-classes-on-the-tomcat-classpath