我的应用程序上下文XML很简单:
<context:component-scan base-package="com.depressio.spring" />
在那个包中,我有我的配置:
package com.depressio.spring
@Configuration
@ComponentScan(basePackages = "com.depressio")
public class DepressioConfiguration
{
@Inject private ApplicationContext context;
}
在com.depressio
内,有一个存储库(DAO):
package com.depressio.dao;
@Repository
public class ParameterDAO
{
public Parameter getParameter(long ID) { ... }
}
...以及注射工作正常的服务(使用parameterDAO时没有NPE):
package com.depressio.resource;
@Service
@Path("/depressio/parameters")
public class ParameterResource
{
@Inject private ParameterDAO parameterDAO;
@Path("{id}")
public Response getParameter(long parameterID)
{
return Response.ok(parameterDAO.getParameter(parameterID).legacyFormat()).build();
}
}
但是,legacyFormat()
方法调用会构造另一个对象。在该对象中,我必须注入不同的DAO(尽管也注明了@Repository
)。注射不起作用。
所以,我们有原始的Parameter
对象:
package com.depressio.domain;
public class Parameter
{
...
public LegacyParameter legacyFormat()
{
return new LegacyParameter(this);
}
}
...以及注射不起作用的LegacyParameter
:
package com.depressio.domain.legacy;
public class LegacyParameter
{
@Inject private LegacyDAO legacyDAO;
....
public LegacyParameter(Parameter newParameter)
{
// NullPointerException when using the injected legacyDAO.
}
}
我尝试过一些事情,包括:
对LegacyParameter
使用no-args构造函数,然后调用populate
方法,以便在构造对象之前不使用注入的DAO。这没有用。
将LegacyDAO
注入ParameterResource
并传入。这有效,但不是理想的,因为我必须将它传递给很多(注射应该有帮助)避免,不?)。它确实证明了LegacyDAO
是可以注意的......显然不是LegacyParameter
。
在@Service
上添加@Component
,@Named
或LegacyParameter
注释。所有这些都在我尝试引用注入的legacyDAO
的行上结束了NullPointerException。
我错过了什么?
答案 0 :(得分:0)
正如Sotirios所指出的那样,它不会起作用,因为你创建了一个普通的Java对象,并且没有给Spring提供增强它的机会。 让Spring创建你想要享受Spring&#39;魔法的对象。 (比如设置@Inject依赖项等)。 或者自己创建自己的对象并设置依赖项(yourObject.setDao(dao))。
也就是说,在特殊情况下,您仍然希望动态创建对象。由你自己但依靠Spring为这些对象注入依赖。在这种情况下,您应该明确地调用Spring: LegacyParameter p = new LegacyParameter(...); 。applicationContext.getAutowireCapableBeanFactory()autowireBean(P); 在你的情况下,我认为你真的不需要它。 (如果确实需要这样的话,请参阅此链接inject bean reference into a Quartz job in Spring?。)
另外,我建议简化配置。 为什么你同时使用基于xml和基于java的配置呢?在您的示例中,您只能保留其中一个并具有相同的效果。