2012-02-02 157 views
1

我有一個問題讓@Autowired工作。對不起,如果我搞砸任何條款,我對Spring相對來說比較新。彈簧自動裝配和類繼承

Spring版本是3.0.5.RELEASE,和我使用的上下文:組件掃描我的豆子定義。

這工作與@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,那就試着用'@ qualifier'和'@ autowire'一起使用 – 2012-02-02 05:36:19

+0

classpath中只有一個UserDao,我使用在我的beans文件中。 – 2012-02-02 05:38:46

+0

因爲你正在得到'NoSuchBeanDefinitionException'似乎你havnt在上下文文件中定義了bean.Can你可以發佈你的上下文文件 – 2012-02-02 05:49:11

回答

7

當使用@Transactional註解,春天創建一個代理JDK當類實現一個接口。在你的情況,的JDK代理(userDAO的實現道<用戶>)將實施道<用戶>但不會延長userDAO的。因此,在上下文中的bean將成爲道<用戶>。

當與@Transaction標註類沒有實現一個接口,春季必須創建一個擴展userDAO的CGLIB代理。因此,上下文中的bean將是一個UserDao。

你可以告訴Spring始終使用CGLIB代理把這個在你的applicationContext.xml時:

<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'的路線) – 2012-02-04 23:15:47

+0

如果您使用的是組件掃描,UserDaoJpa類上的@Component註釋是什麼?否則,你必須這樣創建bean:。你不能有這個:因爲它會嘗試實例化一個接口 – 2012-02-05 04:02:05

2

您是否嘗試在UserResource課程中自動調配Dao界面(而不是UserDao),例如:

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

    // ... 
} 

如果你有Dao界面的實現,就必須告訴Spring是一個合適的,例如通過使用@Qualifier註解。

+0

令人驚歎!那樣做了!謝謝謝謝! – 2012-02-02 07:06:00