0

我有一个(希望是)标准设置,其中包含一堆,@Controller和带注释的类,例如:@Service@Entity@Repository

@Service
public class ChannelManager {
    @Autowired
    private ChannelDao channelDao;

    public List<Channel> allChannels() {
        return channelDao.findAll();
    }
}

哪里ChannelDao是:

public interface ChannelDao extends PersistentDao<Channel> {}

ChannelImpl是:

@Repository
public class ChannelImpl extends PersistentImpl<Channel> implements ChannelDao {}

Channel是:

@Entity
@Table(name = "channel")
public class Channel extends Persistent {
    @Id
    @Column(name = "id", nullable = false)
    private Long id;
    // set/get
}

PersistentDao是:

public interface PersistentDao<T extends Persistent> {
    public List<T> findAll();
}

最后PersistentImpl是:

public class PersistentImpl<T extends Persistent> implements PersistentDao<T> {
    @PersistenceContext
    protected EntityManager entityManager;

    private Class<T> clazz; // gets assigned correctly

    public List<T> findAll() {
        return entityManager.createQuery("from " + clazz.getSimpleName()).getResultList();
    }
}

所有这些都按预期工作。我正在使用<context:annotation-config/>and<context:component-scan/>以及<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" ...>with a persistence.xml。基本上一切正常。

但现在我想概括 ChannelManager,因为我有许多其他实体并且希望避免重复。例如,我还需要一个带有List<Job> allJobs() { return jobDao.findall(); }方法的 JobManager。

所以我创建了这个:

@Service
public class GeneralManager<T extends PersistentDao, E extends Persistent>  {
    @Autowired
    private AutowireCapableBeanFactory factory;
    public void setFactory(AutowireCapableBeanFactory factory) {
        this.factory = factory;
    }

    private Class<? extends T> impl;
    private T dao;

    public GeneralManager(Class<? extends T> impl) throws Exception {
        this.impl = impl;
    }

    @PostConstruct
    public void postCtor() {
        dao = factory.createBean(impl); // seems to be created and is not null
    }

    public List<E> all() {
        return dao.findAll();
    }
}

我更新了 context.xml

<bean id="jobImpl" class="a.b.c.GeneralManager">
    <property name="factory" ref="autowireFactory"/>
    <constructor-arg value="a.b.c.JobImpl"/>
</bean>

<bean id="autowireFactory" class="org.springframework.beans.factory.support.DefaultListableBeanFactory"/>

<context:annotation-config/>
  <context:component-scan base-package="a.b.c">
    <context:exclude-filter type="regex" expression=".*GeneralManager"/>
</context:component-scan>

最后在控制器中添加了一个声明:

@Autowired
@Qualifier(value="jobImpl")
private GeneralManager<JobDao, Job> jobManager;

想象一下 Jobxxx 类类似于 Channelxxx 类。

但是,在执行特化中的findAll()方法时JobImpl, entityManager 为null,因此设置不正确。

所以我的问题真的是“这可以做到吗”?尽管如果有其他更好的方法可以做到这一点,请赐教!

编辑:可能需要注意的是,我使用的是 Spring 3.0.5、Java 1.6.0_21-b07 和 Hibernate 3.6.2.Final

4

2 回答 2

1

因此,在考虑了更多之后,我通过显式定义我试图避免的 bean 朝着稍微不同的方向前进。但它对我有用。我仍然不知道我试图做的事情是否因为类型擦除而无法实现。

我的代码现在看起来像:

public class GeneralManager<T extends PersistentDao, E extends Persistent>  {
    private T dao;
    public void setDao(T dao) {
        this.dao = dao;
    }
    ...
}

使用控制器:

@Autowired
private GeneralManager<ChannelDao, Channel> channelManager;

@Autowired
private GeneralManager<JobDao, Job> jobManager;

context.xml 现在有:

<bean id="jobManager" class="com.a.b.service.EntityManager" p:dao-ref="jobImpl"/>
<bean id="jobImpl" class="com.a.b.dao.JobImpl"/>
<bean id="channelManager" class="com.a.b.service.EntityManager" p:dao-ref="channelImpl"/>
<bean id="channelImpl" class="com.a.b.dao.ChannelImpl"/>

希望这对某人有帮助!

于 2011-04-01T09:08:53.463 回答
-1

为什么不简单地使用 spring-data 项目?它完全满足您的需求,甚至更多。

于 2013-03-28T16:17:52.470 回答