简体   繁体   中英

How can I @Autowire a spring bean that was created from an external jar?

I have a module/jar that I've created and am using as a util library . I created a service in there like so:

@Service
public class PermissionsService { ... }

... where this resides in a package here: com.inin.architect.permissions and in my main application, I'm referencing/loading this jar (ie set as a dependency in the maven POM.xml file for the app) like so:

<dependency>
        <groupId>com.inin.architect</groupId>
        <artifactId>permissions</artifactId>
        <version>1.0-SNAPSHOT</version>
    </dependency>

and within the application I want to use that service like:

@Autowired
PermissionsService permissions

In the application's spring setup, I've got this:

@Configuration
@EnableWebMvc
@ComponentScan(basePackages = { "com.inin.generator", "com.inin.architect.permissions" })
public class WebConfig extends WebMvcConfigurerAdapter implements ServletContextAware { }

However when I run my application under tomcat, it complains that there isn't a bean for the PermissionsService : "org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type ..."

So, how can I bring over the bean from the lib into my application? Surely there's a way. Do you have to set the library up as a full blown spring MVC application so that this can work? ie do you have to have @Configuration and @ComponentScan setup in the lib as well?

You have to scan at least the package containing the class you want to inject. For example, with Spring 4 annotation:

@Configuration
@ComponentScan("com.package.where.my.class.is")
class Config {
...
}

It is the same principle for XML configuration.

Just a note on this, but you could decouple your dependency from spring. In your @Configuration class create

@Bean public PermissionsService  permissionsService(){
   return new PermissionsService()
}

This will also allow it to be injected. Not that you have to remove your spring annotation, just an option making it potentially usable outside of spring.

Ok - i had exactly the same problem - i wanted to autowire a mongo db repository interface from an external jar.

  • I could autowire every bean from that jar with using

    @SpringBootApplication(scanBasePackages = {"com.myrootpackage"})

  • However - autowiring the interface always failed with "Could not find blablabla..."

But the interface was in the same package as the beans i could import. It turned out that searching for the mongo db interfaces is NOT taking the scanBasePackages from the @SpringBootApplication into consideration!

It has to be explicitly configured via

@EnableMongoRepositories(basePackages = {"com.myrootpackage"})

Or you could move the main class "up" so the default searching works also for the mongo interfaces. So i understood the problem and found a solution. But i am still a bit unhappy because i need to configure the same lookup path twice. I find it stupid honestly.

You can import application-context.xml for com.inin.architect.permissions in the following manner inside your main application.

<import resource="classpath:/permissionApplicationContext.xml" />

This will enable you to autowire beans from com.inin.architect.permissions that you have defined.

I faced the same issue while scanning other classes from other project dependencies, The scanning solution depends on the type of classes you need to scan as follows:

if they are normal @Component, @Service annotations use

@ComponentScan({"com.mypackge1","com.mypackage2"})

If the type of classes are domain objects based on entities use

@EntityScan("com.mypackge1.domain")

If JPA repository classes

@EnableJpaRepositories(basePackages = {"com.mypackage.repository"})

If Redis repository classes use

@EnableRedisRepositories(basePackages = {"com.mypackage.repository"})

Same for Mongo, etc.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM