2012-02-02 114 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