Spring依赖注入不起作用 [英] Spring dependency injection not working
问题描述
我的独立Java应用程序出现问题.事实是,我试图自动连接服务和DAO,但是当我从UI调用服务方法时会收到 NullPointerException
,因为依赖项注入无法正常工作.我已经尝试了很多方法,其中许多是基于类似的问题,但问题仍然存在.我正在使用Spring 4.0.6.RELEASE和Hibernate 4.3.11.Final.这是我的代码:
I've got a problem in my standalone Java application. The thing is that I'm trying to Autowire both my Services and my DAOs, but I get a NullPointerException
when I invoke service methods from the UI since dependency injection is not working properly. I've tried a lot of things, many of them from similar questions, but the problem is still there. I'm using Spring 4.0.6.RELEASE and Hibernate 4.3.11.Final. Here is my code:
1-服务调用:
public class LoginView {
@Autowired
private UsuarioService usuarioService;
...
...
JButton btnAutenticarse = new JButton("Autenticar");
btnAutenticarse.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
Usuario usuario = usuarioService.login(textField.getText(),
String.valueOf(passwordField.getPassword()), false); // NullPointerException
} catch (InstanceNotFoundException e1) {
...
2-服务定义:
@Service("usuarioService")
public class UsuarioServiceImpl implements UsuarioService {
@Autowired
private UsuarioDao usuarioDao;
...
3-DAO的定义:
@Repository("usuarioDao")
public class UsuarioDaoHibernate extends GenericDaoHibernate <Usuario, Long>
implements UsuarioDao {
...
4-GenericDAO的定义:
4 - Definition of GenericDAO:
public class GenericDaoHibernate<E, PK extends Serializable> implements
GenericDao<E, PK> {
@Autowired
private SessionFactory sessionFactory;
....
5- AppConfig.java
:
@Configuration
@ComponentScan(basePackages = "org.example.model")
public class AppConfig {
@Bean(name = "usuarioService")
public UsuarioService usuarioService() {
return new UsuarioServiceImpl();
}
@Bean(name = "usuarioDao")
public UsuarioDao usuarioDao() {
return new UsuarioDaoHibernate();
}
6- spring-config.xml
:
<!-- Enable usage of @Autowired. -->
<context:annotation-config/>
<!-- Enable component scanning for defining beans with annotations. -->
<context:component-scan base-package="org.example.model"/>
<!-- For translating native persistence exceptions to Spring's
DataAccessException hierarchy. -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/appdb" />
<property name="username" value="username" />
<property name="password" value="password"/>
</bean>
<bean id="dataSourceProxy" class="org.springframework.jdbc.datasource.LazyConnectionDataSourceProxy"
p:targetDataSource-ref="dataSource"/>
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean" >
<property name="dataSource" ref="dataSource"/>
<property name="packagesToScan">
<list>
<value>org.example.model</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<bean id="persistenceExceptionTranslationPostProcessor"
class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<!-- Enable the configuration of transactional behavior based on
annotations. -->
<tx:annotation-driven transaction-manager="transactionManager" />
推荐答案
Spring只会在Spring托管的bean中注入自动装配字段.如果您使用的是 new LoginView()
Spring,则无法注入依赖项.
Spring will only inject Autowired fields in Spring managed beans. AKA if you are using new LoginView()
Spring cannot inject dependencies.
public class LoginView {
@Autowired
private UsuarioService usuarioService;
}
应该是
@Component
public class LoginView {
@Autowired
private UsuarioService usuarioService;
}
如果您不能让Spring管理该类,则需要以其他方式设计它.
If you can't let Spring manage that class, you'll need to design it a different way.
顺便说一句,我建议您使用构造函数注入而不是字段注入.
I'd recommend you use constructor injection instead of field injection, by the way.
我可能要做的是使另一个类成为Spring托管的bean,并执行以下操作:
What I might do is make another class to be a Spring managed bean and do something like this:
@Component
public class InitClass{
private UsarioService usarioService;
@Autowired
public InitClass(UsarioService usarioService){
this.usarioService = usarioService;
}
@PostConstruct
public void init(){
new LoginView(usarioService);
}
}
然后,此类将处理您现在在 @PostConstruct
中进行的所有初始化.可能需要在 @PostConstruct
中执行此操作,因为直到那时Spring Bean才可能尚未完全初始化.
Then this class will handle all the initialization you're doing now in @PostConstruct
. It may be required to do this in @PostConstruct
as Spring beans may not be fully initialized until then.
但是,在不了解如何初始化所有内容的情况下,很难说出最佳策略是什么.
However, without seeing how everything is initialized, it's hard to tell what the best strategy would be.
这篇关于Spring依赖注入不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!