Spring自动连接和类继承

Spring自动连接和类继承,spring,inheritance,autowired,Spring,Inheritance,Autowired,我在让@Autowired工作时遇到问题。对不起,如果我搞砸了任何条款,我对Spring是比较陌生的 Spring版本是3.0.5.0版本,我在bean定义中使用context:component扫描 这适用于@Autowired注释: @Component public class UserDao { @PersistenceContext protected EntityManager em; @Transactional public User findB

我在让@Autowired工作时遇到问题。对不起,如果我搞砸了任何条款,我对Spring是比较陌生的

Spring版本是3.0.5.0版本,我在bean定义中使用context:component扫描

这适用于@Autowired注释:

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

    @Transactional
    public User findById(Long id) {
        return em.find(User.class, id);
    }
}
@Component
public class UserDao implements Dao<User> {
    @PersistenceContext
    protected EntityManager em;

    @Transactional
    public User findById(Long id) {
         return em.find(User.class, id);
    }
}
这不适用于@Autowired注释:

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

    @Transactional
    public User findById(Long id) {
        return em.find(User.class, id);
    }
}
@Component
public class UserDao implements Dao<User> {
    @PersistenceContext
    protected EntityManager em;

    @Transactional
    public User findById(Long id) {
         return em.find(User.class, id);
    }
}
以下是一些其他类供参考:

Dao.java接口:

public interface Dao<T extends BaseEntity> {
    T findById(Long 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>
有人能解释一下这个问题吗?我想保留类继承


谢谢

您是否尝试过在UserResource类中自动连接Dao接口而不是UserDao,例如:

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

    // ...
}

如果您有几个Dao接口的实现,您必须告诉Spring哪一个是合适的,例如通过使用@Qualifier注释。

您是否尝试自动连接Dao接口而不是UserResource类中的UserDao,例如

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

    // ...
}

如果您有几个Dao接口的实现,您必须告诉Spring哪一个是合适的,例如通过使用@Qualifier注释。

当使用@Transactional注释时,Spring在类实现接口时创建JDK代理。在您的例子中,UserDao的JDK代理实现Dao将实现Dao,但不会扩展UserDao。因此,上下文中的bean将是Dao

当带有@Transaction注释的类没有实现接口时,Spring必须创建一个扩展UserDao的CGLIB代理。因此,上下文中的bean将是UserDao

在将CGLIB代理放入applicationContext.xml时,您可以告诉Spring始终使用CGLIB代理:

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

上下文中的bean是UserDaoJpa,它将在使用UserDao的地方被注入。

当使用@Transactional注释时,Spring在类实现接口时创建JDK代理。在您的例子中,UserDao的JDK代理实现Dao将实现Dao,但不会扩展UserDao。因此,上下文中的bean将是Dao

当带有@Transaction注释的类没有实现接口时,Spring必须创建一个扩展UserDao的CGLIB代理。因此,上下文中的bean将是UserDao

在将CGLIB代理放入applicationContext.xml时,您可以告诉Spring始终使用CGLIB代理:

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

上下文中的bean是UserDaoJpa,它将在使用UserDao的地方被注入。

您在上下文文件中定义了bean吗?如果您有多个UserDao bean,那么请尝试使用@qualifier和@autowire在类路径中只有一个UserDao,而我正在我的bean文件中使用。由于您没有得到任何uchbeandefinitionexception,因此您似乎没有在上下文文件中定义bean。请发布您的上下文文件。我试过有没有运气。请记住,只有添加接口才会使其中断。请尝试使用@Repository而不是@Component,并检查根异常,或者这是日志中唯一的异常?您是否在上下文文件中定义了bean?如果您有多个UserDao bean,那么请尝试使用@qualifier和@autowire在类路径中只有一个UserDao,而我正在我的bean文件中使用。由于您没有得到任何uchbeandefinitionexception,因此您似乎没有在上下文文件中定义bean。请发布您的上下文文件。我试过有没有运气。请记住,只有添加接口才会使其中断。尝试使用@Repository而不是@Component,同时检查根异常,或者这是日志中唯一的异常?当我尝试您的建议时,我得到了以下异常:由以下原因引起:org.springframework.beans.BeanInstantiationException:无法实例化bean类[web.rs.persistence.dao.UserDao]:指定的类是一个接口…有什么建议吗?注意:我没有选择代理目标类的路径如果你使用组件扫描,UserDaoJpa类上的@component注释是吗?否则,你必须这样创建bean:。你不能这样做:因为当我尝试你的建议时,它会尝试实例化一个接口,我得到了以下异常:由以下原因引起:org.springframework.beans.BeanInstantiationException:无法实例化bean类[web.rs.persistence.dao.UserDao]:指定的类是一个接口…有什么建议吗?注意:我没有走代理目标类的路线。如果您使用组件扫描,UserDaoJpa类上的@component注释是吗?否则,您必须以以下方式创建bean:。您不能有此选项:因为它将尝试实例化一个接口
 public class UserService {

   @Autowired
   private UserDao userDao;
 }