@ Autowired-依存関係に適したタイプのBeanが見つかりません


89

SpringとHibernateを使用して、エンティティ、サービス、およびサービスのJUnitテストを作成することからプロジェクトを開始しました。これはすべてうまく機能します。次に、さまざまなステップバイステップのチュートリアルを使用してこのWebアプリケーションを作成するためにspring-mvcを追加しましたが、@ Autowiredアノテーションを使用してコントローラーを作成しようとすると、デプロイ中にGlassfishからエラーが発生します。どういうわけかSpringは私のサービスを認識していないと思いますが、何度も試みてもまだ処理できません。

を使用したサービスのテスト

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml"})

そして

@Autowired
MailManager mailManager;

正しく動作します。

@Autowiredのないコントローラーも、問題なくWebブラウザーでプロジェクトを開くことができます。

/src/main/resources/beans.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:aop="http://www.springframework.org/schema/aop"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.0.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd
        http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd">

    <context:property-placeholder location="jdbc.properties" />

    <context:component-scan base-package="pl.com.radzikowski.webmail">
        <context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <!--<context:component-scan base-package="pl.com.radzikowski.webmail.service" />-->

    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
        <property name="driverClassName" value="${jdbc.driverClassName}" />
        <property name="url" value="${jdbc.url}" />
        <property name="username" value="${jdbc.username}" />
        <property name="password" value="${jdbc.password}" />
    </bean>

    <!-- Persistance Unit Manager for persistance options managing -->
    <bean id="persistenceUnitManager" class="org.springframework.orm.jpa.persistenceunit.DefaultPersistenceUnitManager">
        <property name="defaultDataSource" ref="dataSource"/>
    </bean>

    <!-- Entity Manager Factory for creating/updating DB schema based on persistence files and entity classes -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <property name="persistenceUnitManager" ref="persistenceUnitManager"/>
        <property name="persistenceUnitName" value="WebMailPU"/>
    </bean>

    <!-- Hibernate Session Factory -->
    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource"/>
        <!--<property name="schemaUpdate" value="true" />-->
        <property name="packagesToScan" value="pl.com.radzikowski.webmail.domain" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
            </props>
        </property>
    </bean>

    <!-- Hibernate Transaction Manager -->
    <bean id="txManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
        <property name="sessionFactory" ref="sessionFactory"/>
    </bean>

    <!-- Activates annotation based transaction management -->
    <tx:annotation-driven transaction-manager="txManager"/>

</beans>

/webapp/WEB-INF/web.xml

<web-app xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="WebApp_ID" version="2.4" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <display-name>Spring Web MVC Application</display-name>
    <servlet>
        <servlet-name>mvc-dispatcher</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>mvc-dispatcher</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/mvc-dispatcher-servlet.xml</param-value>
    </context-param>
    <listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
</web-app>

/webapp/WEB-INF/mvc-dispatcher-servlet.xml

<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       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.0.xsd
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

    <context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
        <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
    </context:component-scan>

    <mvc:annotation-driven/>

    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
        <property name="prefix" value="/WEB-INF/views/" />
        <property name="suffix" value=".jsp" />
    </bean>

</beans>

pl.com.radzikowski.webmail.service.AbstractManager

package pl.com.radzikowski.webmail.service;

import org.apache.log4j.Logger;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;

/**
 * Master Manager class providing basic fields for services.
 * @author Maciej Radzikowski <maciej@radzikowski.com.pl>
 */
public class AbstractManager {

    @Autowired
    protected SessionFactory sessionFactory;

    protected final Logger logger = Logger.getLogger(this.getClass());

}

pl.com.radzikowski.webmail.service.MailManager

package pl.com.radzikowski.webmail.service;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

@Component
@Transactional
public class MailManager extends AbstractManager {
    // some methods...
}

pl.com.radzikowski.webmail.HomeController

package pl.com.radzikowski.webmail.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import pl.com.radzikowski.webmail.service.MailManager;

@Controller
@RequestMapping("/")
public class HomeController {

    @Autowired
    public MailManager mailManager;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String homepage(ModelMap model) {
        return "homepage";
    }

}

エラー:

SEVERE:   Exception while loading the app
SEVERE:   Undeployment failed for context /WebMail
SEVERE:   Exception while loading the app : java.lang.IllegalStateException: ContainerBase.addChild: start: org.apache.catalina.LifecycleException: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'homeController': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public pl.com.radzikowski.webmail.service.MailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [pl.com.radzikowski.webmail.service.MailManager] 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)}

多くのコードで申し訳ありませんが、何がそのエラーを引き起こす可能性があるのか​​わかりません。

追加

私はインターフェースを作成しました:

@Component
public interface IMailManager {

追加された実装:

@Component
@Transactional
public class MailManager extends AbstractManager implements IMailManager {

自動配線を変更しました:

@Autowired
public IMailManager mailManager;

しかし、それでもエラーがスローされます(@Qualifierで試した場合も)

..フィールドを自動配線できませんでした:public pl.com.radzikowski.webmail.service.IMailManager pl.com.radzikowski.webmail.controller.HomeController.mailManager .. ..

@Componentと@Transactionalのさまざまな組み合わせも試してみました。

どういうわけかweb.xmlにbeans.xmlを含めるべきではありませんか?


Beans.xmlをどのようにロードしていますか?
Michael Wiles

では、MailManagerInterfaceとの1つだけを残してみIMailManagerませんか?:)
Patison 2013

申し訳ありませんが、コードをひどく貼り付けました。私のプログラムではIMailManagerどこにでもあります。
Radzikowski 2013

ああ、まさに...追加<import resource="classpath:/beans.xml"/>mvc-dispatcher-servlet.xml
Patison

ちなみに、@ emdの決定を試しましたか?
Patison 2013

回答:


81

AbstractManagerクラスの代わりにインターフェースを自動配線する必要がありますMailManager。実装が異なる場合は、特定のクラスをAbstractManager作成@Component("mailService")してから@Autowired @Qualifier("mailService")組み合わせて自動配線できます。

これは、Springがインターフェースに基づいてプロキシオブジェクトを作成して使用するためです。


2
ありがとうございますが、それでも機能しません(同じエラー)。投稿に変更を加えました。たぶん私は私のプロジェクトに何かを適切に含めたり検索したりしませんか?
Radzikowski 2013

@Autowired AbstractManager[] abstractManagersそのすべての実装を含むようなことをする方法があるかどうか疑問に思います。
woLfPwNeR 2016年

@WoLfPwNeRあなたが書いた通りに動作するはずです。リンク
Patison 2016年

なぜMailManagerですか?
Alex78191 2018

@Service同じインターフェースを実装する2つのクラスがあります。どちらも@Autowired別のクラスに属しています。最初は、特定のクラスタイプを使用したときに、元の投稿と同じ問題が発生しました。この回答に続いて、私は違うとインターフェイスタイプを使用するように変更@Qualifier("myServiceA")して@Qualifier("myServiceB")、問題が解決されました。ありがとう!
xialin

27

テストがコンポーネントと同じパッケージに含まれていなかったため、これが発生しました。(コンポーネントパッケージの名前を変更しましたが、テストパッケージの名前は変更していませんでした。)また@ComponentScan、テスト@Configurationクラスで使用していたため、テストで依存するコンポーネントが見つかりませんでした。

したがって、このエラーが発生した場合は再確認してください。


2
これは私のために働いた。@ComponentScanで古いパッケージ名を使用していたため、コードをリファクタリングして新しいパッケージ名に移動すると、テストが失敗しました。
Vijay Vepakomma 2016

1
@Configurationからクラスを使用する方法src/mainsrc/test
Alex78191 2018

10

重要なのは、サーバーの起動時に、アプリケーションコンテキストとWebアプリケーションコンテキストの両方がWebApplicationContextに登録されるということです。テストを実行するときは、ロードするコンテキストを明示的に指示する必要があります。

これを試して:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:/beans.xml", "/mvc-dispatcher-servlet.xml"})

1
Spring Bootを使用している場合はどうすればよいですか?
Alex78191 2018

Mavenの依存関係のコンポーネントスキャンを構成することを忘れており、年に1回のようにこれに苦労しています。
B15

統合テストではなくアプリケーション自体について話している場合、Springブートの場合は、次のように実行できます。 @SpringBootApplication(scanBasePackages = { "com.package.one", "com.package.two" })
b159月

5

これで私の時間の多くを過ごしました!私の悪い!後で、アノテーションを宣言したクラスServiceまたはComponent抽象型のクラスであることがわかりました。Springframeworkでデバッグログを有効にしましたが、ヒントを受け取りませんでした。クラスが抽象型かどうかを確認してください。その場合、適用される基本ルールは、抽象クラスをインスタンス化できません。


1
あなたは私の一日を救った、これは見つけるのがとても難しい!
JaphethOngeri-inkalimeva18年


3

jarファイルの1つからクラスを自動配線しているときに、同じ問題に直面していました。@Lazyアノテーションを使用して問題を修正しました:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;

    @Autowired
    @Lazy
    private IGalaxyCommand iGalaxyCommand;


2

Maxが提案したように、正しい方法はAbstractManagerを自動配線することですが、これも正常に機能するはずです。

@Autowired
@Qualifier(value="mailService")
public MailManager mailManager;

そして

@Component("mailService")
@Transactional
public class MailManager extends AbstractManager {
}

2

最近これに遭遇しましたが、結局、サービスクラスに間違ったアノテーションをインポートしました。Netbeansにはインポートステートメントを非表示にするオプションがあります。そのため、しばらくの間表示されませんでした。

@org.jvnet.hk2.annotations.Service代わりに使用しました@org.springframework.stereotype.Service


1
  • BeanBがコンテキストに存在しない可能性がある1つの理由
  • 例外のもう1つの原因は、2つのBeanの存在です。
  • または、定義されていないコンテキストBeanの定義が、Springコンテキストから名前で要求されます

このURLをもっと見る:

http://www.baeldung.com/spring-nosuchbeandefinitionexception


1
 <context:component-scan base-package="com.*" />

同じ問題が発生しました。アノテーションをそのまま維持し、ディスパッチャーサーブレット::ベースパッケージスキャンを維持することで解決com.*.しました。


1

これはあなたを助けるかもしれません:

私のプロジェクトでも同じ例外があります。検索中に検索したところ、@ Autowiredするインターフェイスを実装しているクラスへの@Serviceアノテーションが欠落していることがわかりました。

コードで、@ ServiceアノテーションをMailManagerクラスに追加できます。

@Transactional
@Service
public class MailManager extends AbstractManager implements IMailManager {

@Service注釈が含まれてい@Component。両方を持つことは冗長です。
AnthonyW 2017年

1

@Autowire MailManager mailManagerの代わりに、以下に示すようにBeanをモックすることができます。

import org.springframework.boot.test.mock.mockito.MockBean;

::
::

@MockBean MailManager mailManager;

また、クラスで@MockBean MailManager mailManager;個別に構成し、@SpringBootConfiguration以下のように初期化することもできます。

@Autowire MailManager mailManager

1

パッケージ固有のスキャンを次のように有効にしたにもかかわらず、春のブートアプリケーションで同じ問題に直面しました

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

しかし、この問題は@ComponentScan({"com.*"})、私のApplicationクラスで提供することで解決されました。


0

私の推測では、ここにあります

<context:component-scan base-package="pl.com.radzikowski.webmail" use-default-filters="false">
    <context:include-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

すべてのアノテーションは、最初にuse-default-filters = "false"によって無効にされ、次に@Controllerアノテーションのみが有効になります。したがって、@ Componentアノテーションは有効になっていません。


0

コントローラをテストしている場合。テストクラスで@WebAppConfigurationを使用することを忘れないでください。


0

自動配線された依存関係をサービスクラスに追加したが、サービスユニットテストで注入されたモックに追加するのを忘れたため、これが発生しました。

単体テストの例外は、問題が実際に単体テストにあったときに、サービスクラスの問題を報告しているように見えました。振り返ってみると、エラーメッセージは問題が何であるかを正確に教えてくれました。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.