无法从子包中扫描组件 - Spring Jar [英] Unable to scan components from sub-package - Spring Jar

查看:228
本文介绍了无法从子包中扫描组件 - Spring Jar的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个使用外部jar的依赖关系的spring命令行应用程序。当我从eclipse运行应用程序时,它的工作原理很好,但是当我将它导出为可运行的jar时,它无法从子包中自动连接该依赖项。但是,如果我在spring-context中编写每个bean定义,那么它可以工作。有什么问题吗? @Component 不工作或组件扫描基础包或其他?



这里是Spring-context.xml:

 <?xml version =1.0encoding = UTF-8\" >?; 
< beans xmlns =http://www.springframework.org/schema/beans
xmlns:xsi =http://www.w3.org/2001/XMLSchema-instancexmlns :p =http://www.springframework.org/schema/p
xmlns:context =http://www.springframework.org/schema/context
xsi:schemaLocation = http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/上下文
http://www.springframework.org/schema/context/spring-context-3.2.xsd\">


< context:property-placeholder location =classpath *:/ connection.properties,classpath *:/ log4j.properties/>
< import resource =classpath *:/ sm-service-context.xml/>

< context:annotation-config />
< context:component-scan base-package =com.hca.sm.migration/>

< bean class =com.hca.sm.migration.MigrationController/>

< / beans>

更新:错误堆栈跟踪:

  org.springframework.beans.factory.BeanCreationException:创建名为com.hca.sm.migration.MigrationController#0的bean时出错:自动连线依赖关系的注入失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动连线字段:protected com.hca.sm.migration.soap.util.SOAPMessageUtil com.hca.sm.migration.MigrationController.soapMessageUtil;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到依赖关系类型为[com.hca.sm.migration.soap.util.SOAPMessageUtil]的符合条件的bean:至少有一个Bean被认定为该依赖关系的自动连线候选。依赖关系注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)} 
在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)$ b $在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
在org.springframework.beans.factory.support.AbstractBeanFactory $ 1.getObject(AbstractBeanFactory.java:302)
在org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
在org.springframework.beans.factory .support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
在org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
在org.springframework.beans.factory .support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
在org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
在org.springframework.context.support.AbstractApplicationContext .refresh(AbstractApplicationContext.java:482)
在org.springframework.context.support.ClassPathXmlApplicationContext。< init>(ClassPathXmlApplicationContext.java:139)
在org.springframework.context.support.ClassPathXmlApplicationContext。 < init>(ClassPathXmlApplicationContext.java:83)
at com.hca.sm.migration.SMMigrationApp.main(SMMigrationApp.java:39)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method )
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
在java.lang.reflect。 Method.invoke(Method.java:606)
在org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
导致:org.springframework.beans.factory。 BeanCreationException:无法自动连线字段:protected com.hca.sm.migration.soap.util.SOAPMessageUtil com.hca.sm.migration.MigrationController.soapMessageUtil;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到依赖关系类型为[com.hca.sm.migration.soap.util.SOAPMessageUtil]的符合条件的bean:至少有一个Bean被认定为该依赖关系的自动连线候选。依赖关系注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
在org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
... 18更多
导致:org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到依赖关系类型[com.hca.sm.migration.soap.util.SOAPMessageUtil]的符合条件的bean至少有1个bean符合这种依赖关系的自动连线候选。依赖关系注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
在org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
在org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
...另外
错误[main](SMMigrationApp.java:17) - org .springframework.beans.factory.BeanCreationException:创建名为'com.hca.sm.migration.MigrationController#0'的bean时出错:注入自动连线依赖关系失败;嵌套异常是org.springframework.beans.factory.BeanCreationException:无法自动连线字段:protected com.hca.sm.migration.soap.util.SOAPMessageUtil com.hca.sm.migration.MigrationController.soapMessageUtil;嵌套异常是org.springframework.beans.factory.NoSuchBeanDefinitionException:找不到依赖关系类型为[com.hca.sm.migration.soap.util.SOAPMessageUtil]的符合条件的bean:至少有一个Bean被认定为该依赖关系的自动连线候选。依赖关系注释:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}

MigrationController.java:

  package com.hca.sm.migration; 

import java.util.List;
import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/ *其他导入* /

@Component
public class MigrationController extends AbstractEntityUtil {

private static final Logger logger = Logger.getLogger(MigrationController。 class.getName());

@Autowired
protected SOAPMessageUtil soapMessageUtil;

@Autowired
protected SOAPGroupUtil soapGroupUtil;

@Autowired
protected SOAPMessageThreadUtil soapMessageThreadUtil;

@Autowired
protected RestServiceUtil restServiceUtil;

private SecureMail connectionPort = null;
private GroupList groupList = null;

@PostConstruct
public void init(){
connectionPort = soapConnectionUtil.getSOAPConnection();
}

public void migrateOldSmToNew(String clientId,String dryRun){
groupList = soapGroupUtil.getListOfGroupsByClientId(clientId,connectionPort);

/ *其他逻辑* /

}
}

我的主要类从我所在的控制器:

  package com.hca.sm.migration ; 

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public final class SMMigrationApp {

public static void main(String [] args){
String clientId =dc = ihcs, DC = COM;
String dryRun =true;

try {
ApplicationContext smApplicationContext = new ClassPathXmlApplicationContext(classpath *:/ SM-MigrationApplicationContext.xml);
// migration
MigrationController migrationController =(MigrationController)smApplicationContext.getBean(MigrationController.class.getName()); //这里是错误
migrationController.migrateOldSmToNew(clientId,dryRun);

} catch(Exception e){
e.printStackTrace();
}

}
}


解决方案

OKAY!所以经过大量的挖掘,我选择了另一种方法来将我的应用程序打包成可运行的jar,它的接缝为我工作。但是,我仍然不明白为什么在这种情况下,组件扫描基础包不起作用。我认为它必须使用maven组装jar和 .classpath menifest.mf 之内做某事。所以我建议任何人有这样的问题使用以下插件:

 < plugin> 
< groupId> org.springframework.boot< / groupId>
< artifactId> spring-boot-maven-plugin< / artifactId>
< version> 1.2.2.RELEASE< / version>
<执行>
< execution>
< goals>
< goal>重新包装< / goal>
< / goals>
< / execution>
< / executions>
< / plugin>

这是创建独立的可运行的jar的最简单的方法,包括所有依赖项。

要在控制台编译和运行maven命令:

  mvn clean package 

要在控制台运行jar:

  java -jar jarName.jar 

希望这有助于像我一样的人! !!!


I'm developing a spring command line app which uses dependency of external jars. When I run the app from eclipse it works perfectly, but when I export it as runnable jar it fails to autowire the dependecies from the sub-package. However if I write each bean definition in spring-context, then it works. What is the problem with it? Is @Component not working or component-scan base package or something else?

Here is Spring-context.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd 
    http://www.springframework.org/schema/context 
    http://www.springframework.org/schema/context/spring-context-3.2.xsd">


    <context:property-placeholder location="classpath*:/connection.properties, classpath*:/log4j.properties" />
    <import resource="classpath*:/sm-service-context.xml" />

    <context:annotation-config />
    <context:component-scan base-package="com.hca.sm.migration" />

    <bean class="com.hca.sm.migration.MigrationController" />

</beans>

Update: ERROR Stacktrace:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.hca.sm.migration.MigrationController#0': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected com.hca.sm.migration.soap.util.SOAPMessageUtil com.hca.sm.migration.MigrationController.soapMessageUtil; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.hca.sm.migration.soap.util.SOAPMessageUtil] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:292)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1185)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:537)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:475)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:228)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:703)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:760)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:482)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.hca.sm.migration.SMMigrationApp.main(SMMigrationApp.java:39)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at org.eclipse.jdt.internal.jarinjarloader.JarRsrcLoader.main(JarRsrcLoader.java:58)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected com.hca.sm.migration.soap.util.SOAPMessageUtil com.hca.sm.migration.MigrationController.soapMessageUtil; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.hca.sm.migration.soap.util.SOAPMessageUtil] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:508)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:289)
    ... 18 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.hca.sm.migration.soap.util.SOAPMessageUtil] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:1103)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:963)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:858)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:480)
    ... 20 more
ERROR [main] (SMMigrationApp.java:17) - org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.hca.sm.migration.MigrationController#0': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: protected com.hca.sm.migration.soap.util.SOAPMessageUtil com.hca.sm.migration.MigrationController.soapMessageUtil; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.hca.sm.migration.soap.util.SOAPMessageUtil] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

MigrationController.java:

package com.hca.sm.migration;

import java.util.List;
import javax.annotation.PostConstruct;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/* other imports */

@Component
public class MigrationController extends AbstractEntityUtil {

    private static final Logger logger = Logger.getLogger(MigrationController.class.getName());

    @Autowired
    protected SOAPMessageUtil soapMessageUtil;

    @Autowired
    protected SOAPGroupUtil soapGroupUtil;

    @Autowired
    protected SOAPMessageThreadUtil soapMessageThreadUtil;

    @Autowired
    protected RestServiceUtil restServiceUtil;

    private SecureMail connectionPort = null;
    private GroupList groupList = null;

    @PostConstruct
    public void init() {
        connectionPort = soapConnectionUtil.getSOAPConnection();
    }

    public void migrateOldSmToNew(String clientId, String dryRun) {
        groupList = soapGroupUtil.getListOfGroupsByClientId(clientId, connectionPort) ;

        /* other logic*/

    }
}

And my main class from where I call the controller:

package com.hca.sm.migration;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Component;

@Component
public final class SMMigrationApp {

    public static void main(String[] args) {
        String clientId = "dc=ihcs,dc=com";
        String dryRun = "true";

        try {
            ApplicationContext smApplicationContext = new ClassPathXmlApplicationContext("classpath*:/SM-MigrationApplicationContext.xml");
            // migration
            MigrationController migrationController = (MigrationController) smApplicationContext.getBean(MigrationController.class.getName());  //here is error
            migrationController.migrateOldSmToNew(clientId, dryRun);

        } catch (Exception e) {
            e.printStackTrace();
        }

    }
}

解决方案

OKAY! So after much of digging I chose another approach to pack my application as runnable jar and it seams to work for me. However I still don't get why the component-scan-base package was is not working in this case. I assume it has to do something with the way maven assemble the jar and .classpath inside menifest.mf. So I suggest if anyone is having such problem use following plugin:

<plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <version>1.2.2.RELEASE</version>
    <executions>
        <execution>
           <goals>
               <goal>repackage</goal>
            </goals>
        </execution>
     </executions>
 </plugin>

This is the most simple way to create standalone runnable jar which includes all the dependencies.

To compile and package run maven command at console:

mvn clean package

To run the jar at console :

java -jar jarName.jar

Hope this helps someone like me!!!!

这篇关于无法从子包中扫描组件 - Spring Jar的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆