2012-02-02 11 views
1

@Autowiredが動作するのに問題があります。申し訳ありませんが、私は任意の条件をねじれ、私は比較的新しい春です。春のオートワイヤリングとクラスの継承

春のバージョンは3.0.5.RELEASEで、私は豆の定義でcontext:component-scanを使用しています。

これは@Autowired注釈で動作します:

@Component 
public class UserDao { 
    @PersistenceContext 
    protected EntityManager em; 

    @Transactional 
    public User findById(Long id) { 
     return em.find(User.class, id); 
    } 
} 

これは@Autowiredアノテーションでは動作しません:このセットアップ、

@Component 
public class UserDao implements Dao<User> { 
    @PersistenceContext 
    protected EntityManager em; 

    @Transactional 
    public User findById(Long id) { 
     return em.find(User.class, id); 
    } 
} 

私が追加したすべては 'ダオを実装'と、次のようになります。

org.springframework.beans.factory.NoSuchBeanDefinitionException: No matching bean of type [web.rs.persistence.dao.UserDao] 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)} 

参照のためにいくつかの他のクラス:

Dao.java(インターフェース):

public interface Dao<T extends BaseEntity> { 
    T findById(Long id); 
} 

UserResource.java:

@Component 
public class UserResource { 
    @Autowired 
    UserDao userDao; 

    public User getUser(Long id) { 
     return userDao.findById(id); 
    } 
} 

applicationContext.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:context="http://www.springframework.org/schema/context" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     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/tx 
     http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 

     <context:component-scan base-package="web.rs" /> 

     <bean id="placeholderConfig" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
      <property name="location" value="classpath:config.properties" /> 
     </bean> 

     <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
      <property name="loadTimeWeaver"> 
       <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver" /> 
      </property> 
      <property name="persistenceUnitName" value="${persistence.unit}" /> 
     </bean> 

     <bean id="trx-manager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
      <property name="entityManagerFactory" ref="emf" /> 
     </bean> 

     <tx:annotation-driven transaction-manager="trx-manager" /> 
    </beans> 

は誰でも当てることができますいくつかのこの問題についての光?私はクラス継承を維持したいと思います。

ありがとうございます!

+0

コンテキストファイルにBeanを定義しましたか? UserDaoのBeanが複数ある場合は、 '@ autowire'とともに' @ qualifier'を試してください。 –

+0

クラスパスにUserDaoが1つしかありません。私の豆のファイル。 –

+0

あなたは 'NoSuchBeanDefinitionException'を取得しているので、コンテキストファイルにBeanを定義しているようです。コンテキストファイルを投稿してください。 –

答えて

7

@Transactionalアノテーションを使用する場合、クラスがインターフェイスを実装するときにSpringはJDKプロキシを作成します。あなたのケースでは、(UserDaoがDao <User>を実装する)User DaoはDao <User>を実装しますが、UserDaoは継承しません。したがって、コンテキスト内のBeanはDao <ユーザー>になります。

@Transactionアノテーションを持つクラスがインターフェイスを実装していない場合、SpringはUserDaoを拡張するCGLIBプロキシを作成する必要があります。したがって、コンテキスト内のBeanはUserDaoになります。あなたのapplicationContext.xmlをでこれを入れたときに

あなたは常にCGLIBプロキシを使用するように春を告げることができます。

<tx:annotation-driven transaction-manager="trx-manager" proxy-target-class="true" /> 

はいくつかの欠点がありますが、私はそれを覚えていません。

私は、プロキシ・ターゲット・クラス=「true」を使用していないと私のデザインは、このようなものです:

私はダオのすべてのタイプのためのインターフェイスを持っています。

public interface UserDao extends Dao<User> 

    List<User> findByUsername(); 

私は特定のインターフェイス

@Component 
public class UserDaoJpa implements UserDao 

    public List<User> findByUsername() { 
    ... 
    } 

マイサービスクラスを実装するUserDaoを使用しています。

public class UserService { 

    @Autowired 
    private UserDao userDao; 
} 

コンテキストでBeanがUserDaoJpaで、UserDaoがどこにあるか、それが注入されます中古。

+0

提案をしようとすると、次の例外が発生します。 '原因:org.springframework.beans.BeanInstantiationException:Beanクラス[web.rs.persistence.dao.UserDao]をインスタンス化できませんでした:指定されたクラスはインタフェースです'。 .. 助言がありますか? (注:私は 'proxy-target-classes'のルートに行きませんでした) –

+0

コンポーネントスキャンを使用している場合、UserDaoJpaクラスの@Componentアノテーションはありますか?それ以外の場合は、この方法でBeanを作成する必要があります。これを持つべきではありません:これは、インターフェースをインスタンス化しようとするためです –

2

UserResourceクラス(UserDaoではなく)のDaoインターフェイスをオートワイヤリングしようとしましたか?あなたがDaoインターフェイスのいくつかの実装を持っている場合は

@Component 
public class UserResource { 
    @Autowired 
    Dao<User> userDao; 

    // ... 
} 

、あなたは@Qualifier注釈を使用することにより、たとえば、適切なものである春を告げる必要があります。

+0

すごい!それはそれをした!ありがとうありがとう! –