自动装配DAO bean

时间:2017-08-18 09:52:19

标签: java spring mongodb generics

所以我尝试过搜索这个拦截器并尝试了许多不同的方法来寻找解决方案,但我无法绕过它。我是Spring的初学者,我创建了一个通用DAO,它接收任何扩展BaseEntity的T。我有以下代码:

    private Class<T> clazz;
@Autowired
public void setClazz(Class<T> clazz){
    System.out.println("In class Autowired Setter");
    this.clazz = clazz;
}

@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Class<T> getClazz(){
    return clazz;
}

我已将其放入 BaseDAOImpl 。然后我使用这个构造函数:

public BaseDAOImpl() {
    this.collection = MongoDbUtil.getCollection(mongoConnection.mongoDb(), clazz);
}

为MongoDB创建JacksonDbCollection。在我的 CustomerServiceImpl 中,我自动装配了我的BaseDAO bean,以便我可以使用我的DAO来保持持久性。

  @Autowired
public void setBaseDAO(BaseDAO<CustomerEntity> baseDAO) {
    this.baseDAO = baseDAO;
}

因此,当我运行一个使用我的BaseDAOImpl的方法时,我得到一个NullPointerException,我很确定这是因为Class没有拿起我的CustomerEntity。我的问题是,当我自动连接我的baseDao bean时,如何让Class获取CustomerEntity?或者你有什么建议让我解决我的问题?我只是需要一个不同的观点,并认为我会在这里要求它。

先谢谢您的帮助。

更新

BaseDAOImpl

package za.co.thekeeper.dao;
import org.mongojack.DBCursor;
import org.mongojack.DBQuery;
import org.mongojack.JacksonDBCollection;
import org.mongojack.WriteResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition; 
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Repository;
import za.co.thekeeper.entities.BaseEntity;
import za.co.thekeeper.mongo.MongoConnection;
import za.co.thekeeper.mongo.MongoDbUtil;
import java.util.ArrayList;
import java.util.List;

@Repository
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public class BaseDAOImpl<T extends BaseEntity> implements BaseDAO<T> {

private JacksonDBCollection<T, String> collection;

/**Dependency Injections**/
private MongoConnection mongoConnection;
@Autowired
public void setMongoConnection(MongoConnection mongoConnection) {
    System.out.println("In autowired setter");
    this.mongoConnection = mongoConnection;
}

private Class<T> clazz;
@Autowired
public void setClazz(Class<T> clazz){
    System.out.println("In class Autowired Setter");
    this.clazz = clazz;
}

@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Class<T> getClazz(){
    return clazz;
}

public BaseDAOImpl() {
    this.collection = MongoDbUtil.getCollection(mongoConnection.mongoDb(), clazz);
}

@Override
public T create(T entity) {
    entity.activate();
    entity.beforePersist();
    WriteResult<T, String> inserted = this.collection.insert(entity);
    return inserted.getSavedObject();
}

@Override
public void delete(T entity) {
    deactivate(entity);
}

@Override
public T activate(T entity) {
    entity.activate();
    return update(entity);
}

@Override
public T deactivate(T entity) {
    entity.deactivate();
    return update(entity);
}

@Override
public void activate(String id) {
    T entity = getById(id);

    if (entity == null) {
        throw new NullPointerException("Entity not found with id: " + id);
    }

    activate(entity);
}

@Override
public void deactivate(String id) {
    T entity = getById(id);

    if (entity == null) {
        throw new NullPointerException("Entity not found with id: " + id);
    }

    deactivate(entity);
}

@Override
public T update(T entity) {
    entity.beforePersist();
    WriteResult<T, String> saved = this.collection.save(entity);
    return saved.getSavedObject();
}

@Override
public void deleteById(String id) {
    deactivate(id);
    update(getById(id));
}

@Override
public T getById(String id) {
    return this.collection.findOneById(id);
}

@Override
public List<T> findByField(String field, Object o) {
    DBQuery.Query query = DBQuery.is(field, o);
    DBCursor<T> cursor = this.collection.find(query);
    return readCursor(cursor);
}

@Override
public void createDBRef(String databaseName, String collectionName, String id) {

}

@Override
public List<T> findAll() {
    return findByField("activate", Boolean.TRUE);
}

/**
 * Cursor
 **/
private List<T> readCursor(DBCursor<T> cursor) {
    if (cursor.size() > 0) {
        List<T> found = new ArrayList<>();
        while (cursor.hasNext()) {
            found.add(cursor.next());
        }
        return found;
    }
    return null;
}
}

CustomerServiceImpl

package za.co.thekeeper.service;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import za.co.thekeeper.dao.BaseDAO;
import za.co.thekeeper.dao.BaseDAOImpl;
import za.co.thekeeper.entities.CustomerEntity;
import za.co.thekeeper.entities.MerchantEntity;
import za.co.thekeeper.entities.ReceiptEntity;
import za.co.thekeeper.mongo.MongoConnection;

import java.util.List;
import java.util.UUID;

@Service

public class CustomerServiceImpl implements CustomerService {

private BaseDAO<CustomerEntity> baseDAO;

@Autowired
public void setBaseDAO(BaseDAO<CustomerEntity> baseDAO) {
    this.baseDAO = baseDAO;
}

@Override
public CustomerEntity registerNewCustomer(CustomerEntity customer) {
    if (customer.getId() == null) {
        customer.setId(UUID.randomUUID().toString());
    }

    CustomerEntity entity = baseDAO.create(customer);
    System.out.println(entity.toString());
    return entity;
}

@Override
public CustomerEntity getCustomer(String cellNumber) {
    List<CustomerEntity> entities = baseDAO.findByField("cellNumber", cellNumber);
    return entities.get(0);
}

@Override
public CustomerEntity updateCustomerDetails(CustomerEntity customer) {

    return baseDAO.update(customer);
}

@Override
public void deleteCustomer(CustomerEntity customer) {
    baseDAO.delete(customer);
}
}

申请背景

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
   xmlns:context="http://www.springframework.org/schema/context"
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://www.springframework.org/schema/beans 
   http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
   http://www.springframework.org/schema/context  
   http://www.springframework.org/schema/context/spring-context-4.0.xsd">

<context:annotation-config/>

<context:component-scan base-package="za.co.thekeeper"/>

按要求。

新更新

BaseDAO

package za.co.thekeeper.dao;

import za.co.thekeeper.entities.BaseEntity;
import za.co.thekeeper.mongo.MongoConnection;

import java.util.List;

public interface BaseDAO<T extends BaseEntity> {

T create(T entity);

void delete(T entity);

T activate(T entity);

T deactivate(T entity);

void activate(String id);

void deactivate(String id);

T update(T entity);

void deleteById(String id);

T getById(String id);

List<T> findByField(String id, Object o);

void createDBRef(String databaseName, String collectionName, String id);

List<T> findAll();
}

2 个答案:

答案 0 :(得分:0)

private BaseDAO<CustomerEntity> baseDAO;

@Autowired
public void setBaseDAO(BaseDAO<CustomerEntity> baseDAO) {
    this.baseDAO = baseDAO;
}

请尝试使用constructor-injection。检查是否有帮助

private BaseDAO<CustomerEntity> baseDAO;

@Autowired
public CustomerServiceImpl(BaseDAO<CustomerEntity> baseDAO) {
    this.baseDAO = baseDAO;
}

答案 1 :(得分:0)

您现有的BaseDAOImpl:

private MongoConnection mongoConnection;
@Autowired
public void setMongoConnection(MongoConnection mongoConnection) {
    System.out.println("In autowired setter");
    this.mongoConnection = mongoConnection;
}

private Class<T> clazz;
@Autowired
public void setClazz(Class<T> clazz){
    System.out.println("In class Autowired Setter");
    this.clazz = clazz;
}

@Bean
@Scope(BeanDefinition.SCOPE_PROTOTYPE)
public Class<T> getClazz(){
    return clazz;
}

public BaseDAOImpl() {
    this.collection = MongoDbUtil.getCollection(mongoConnection.mongoDb(), clazz);
}

这不是初始化此bean的正确方法。

  1. 您正在mongoConnection上执行setter注入并在默认构造函数中访问它。 MongoDbUtil.getCollection(mongoConnection.mongoDb(), clazz);在调用setter之前调用构造函数。这将导致NPE。
  2. 没有人设置clazz变量。
  3. 设置器上的
  4. @Autowired和吸气剂上的@Bean毫无意义。
  5. @Repository注释不是必需的。您可以使用@Component
  6. 正确的做事方式就是这样。

    BaseDAOImpl class - 为了简洁,仅包括一部分类

    package za.co.thekeeper.dao;
    import org.mongojack.DBCursor;
    import org.mongojack.DBQuery;
    import org.mongojack.JacksonDBCollection;
    import org.mongojack.WriteResult;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.beans.factory.config.BeanDefinition; 
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Repository;
    import za.co.thekeeper.entities.BaseEntity;
    import za.co.thekeeper.mongo.MongoConnection;
    import za.co.thekeeper.mongo.MongoDbUtil;
    import java.util.ArrayList;
    import java.util.List;
    
    public class BaseDAOImpl<T extends BaseEntity> implements BaseDAO<T> {
    
    private JacksonDBCollection<T, String> collection;
    
    /**Dependency Injections**/
    private MongoConnection mongoConnection;
    
    public void setMongoConnection(MongoConnection mongoConnection) {
        System.out.println("In autowired setter");
        this.mongoConnection = mongoConnection;
    }
    
    private Class<T> clazz;
    
    public void setClazz(Class<T> clazz){
        System.out.println("In class Autowired Setter");
        this.clazz = clazz;
    }
    
    public Class<T> getClazz(){
        return clazz;
    }
    
    public BaseDAOImpl(MongoCollection mongoCollection, Class<T> clazz) {
        this.mongoCollection = mongoCollection;
        this.clazz = clazz;
        this.collection = MongoDbUtil.getCollection(mongoConnection.mongoDb(), clazz);
    }
    }
    

    春季配置:

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
       http://www.springframework.org/schema/context  
       http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
    <context:annotation-config/>
    
    <context:component-scan base-package="za.co.thekeeper"/>
    
    <bean class="za.co.thekeeper.dao.BaseDAOImpl">
        <constructor-arg index="0" ref="mongoCollection"/>
        <constructor-arg index="1">
            <value type="java.lang.Class">CustomerEntity</value>
        </constructor-arg>
    </bean>
    

    Spring将从第二个构造函数注入中检测类型T,并允许您自动装配类型为BaseDAOImpl<CustomerEntity>的bean。

    注意:我认为mongoCollection在别处被声明为一个spring bean。否则,您需要在spring配置文件中添加它。