我试图在控制器中注入我的dao对象。我做到了这个:
我有一个:
1. MongoDBHelper
2.商人DAO
3.商家服务
4. MerchantController
这是MongoDBHelper类:
import javax.inject.Singleton;
@Singleton
public class MongoDBHelper {
private DB db;
private Datastore datastore;
private Configuration config = Play.application().configuration();
private final String SERVER_URL = config.getString("server_url");
private final String USERNAME = config.getString("database.userName");
private final String PASSWORD = config.getString("database.password");
private final String DATABASE_NAME = config.getString("database.name");
public MongoDBHelper() {
try {
MongoClient mongoClient = new MongoClient();
this.db = mongoClient.getDB(DATABASE_NAME);
this.db.authenticate(USERNAME, PASSWORD.toCharArray());
Morphia morphia = new Morphia();
this.datastore = morphia.createDatastore(mongoClient, DATABASE_NAME);
morphia.mapPackage("models");
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
public DB getDB() {
return this.db;
}
public Datastore getDatastore() {
return this.datastore;
}
}
这是MerchantDAO类
public class MerchantDAO {
@Inject MongoDBHelper mongoDBHelper;
private Datastore datastore = mongoDBHelper.getDatastore();
private DB db = mongoDBHelper.getDB();
private static final String AUTH_TOKEN = "authToken";
private static final Config config = ConfigFactory.load(Play.application().configuration().getString("property.file.name"));
public void updateMerchantWithAuthToken(Merchant merchant){
Query<Merchant> query = datastore.createQuery(Merchant.class).field(config.getString("string.email")).equal(merchant.getEmail());
UpdateOperations<Merchant> ops = datastore.createUpdateOperations(Merchant.class).set(AUTH_TOKEN, merchant.getAuthToken()).set("lastRequestTime",merchant.getLastRequestTime());
UpdateResults res = datastore.update(query, ops);
}
}
}
这是MerchantService类:
public class MerchantService {
static final Config config = ConfigFactory.load(Play.application().configuration().getString("property.file.name"));
@Inject
MerchantDAO merchantDAO;
// Creating unique authToken for already logged in merchant
public String createToken(Merchant merchant) {
merchantDAO.updateMerchantWithAuthToken(merchant);
return authToken;
}
}
这是MerchantController
import javax.inject.Inject;
public class MerchantController extends Controller {
@Inject MerchantService merchantService;
public final static String AUTH_TOKEN_HEADER = "X-AUTH-TOKEN";
public static final String AUTH_TOKEN = "authToken";
public static final Config config = ConfigFactory.load(Play.application().configuration().getString("property.file.name"));
public static Merchant getMerchant() {
return (Merchant)Http.Context.current().args.get("merchant");
}
public Result login() throws Exception {
// code to perform login
return ok(); // status success / failure
}
}
我收到了以下错误:
ProvisionException: Unable to provision, see the following errors:
1) Error injecting constructor, java.lang.NullPointerException
at daos.MerchantDAO.<init>(MerchantDAO.java:22)
while locating daos.MerchantDAO
for field at services.MerchantService.merchantDAO(MerchantService.java:26)
while locating services.MerchantService
for field at controllers.MerchantController.merchantService(MerchantController.java:21)
while locating controllers.MerchantController
for parameter 2 at router.Routes.<init>(Routes.scala:36)
while locating router.Routes
while locating play.api.inject.RoutesProvider
while locating play.api.routing.Router
1 error
我可能做错了什么?为什么DI不能正常工作?
提前致谢。
答案 0 :(得分:1)
我认为问题出在这些方面:
private Datastore datastore = mongoDBHelper.getDatastore();
private DB db = mongoDBHelper.getDB();
在对象实例的构造过程中对它们进行评估。我相信注射不会发生,直到对象实例完成构建之后。因此,在进行上述赋值时,mongoDBHelper为null。
解决此问题的一种方法是在方法updateMerchantWithAuthToken中设置数据存储区和数据库。
答案 1 :(得分:0)
问题是您在MongoDBHelper实例化期间尝试访问Configuration对象。您应该将play配置对象注入模块的构造函数并初始化构造函数中的所有属性:
@Inject
public MongoDBHelper(Configuration configuration) {
config = Play.application().configuration();
<read the rest of the config values here>
请参阅D.I.的可配置绑定部分中的注释。文档here