Spring creating bean but not injecting it

2019-07-23 16:23发布

问题:

I know theres a ton of questions regarding problems with Spring Autowired, but I havent been able to find anything similar to mine, so sorry if its a dupe...

Im having problems with autowiring a bean that is created (debugging shows that the constructor is run), but then it doesnt get injected. There are no calls of manual instantiation. I have many other autowired fields in the project and they work fine. Most amusing, though, is the fact that Ive used the same pattern and config in a different project and it works there...

Now then, here are the codes:

The bean that gets created but not injected:

@Component("genericDao")
public class GenericHibernateJpaDao implements GenericDao {

    @Autowired
    protected EntityManagerFactory entityManagerfactory;

    public GenericHibernateJpaDao() {
    }
    //getters, setters and dao methods
}

GenericDao interface only defines methods and has no annotations.

Service super-class that defines the bean:

@Configurable
public abstract class AbstractService {
    @Autowired
    protected GenericDao genericDao;
    //getters, setters
}

Service implementation (declaration bit):

@Service
@Component
public class WechatMessageService extends AbstractService implements IMessageService {

Breakpoint in service implementation at genericDao.saveOrUpdate(n); shows genericDao to be null (this is also the line that throws NullPointerEx.) IMessageService is

@Service
@Configurable
@Transactional

application-config.xml (relevant bits):

<beans .......... default-autowire="byName">
    <context:component-scan base-package="package.with.dao" />
    <context:component-scan base-package="package.with.service" />
    <context:spring-configured/> 

Im guessing its just some fairly stupid mistake on my side, but I just cant figure it out and googling isnt helping.

Thanks for any help.

回答1:

If you don't have load-time weaving enabled (in order to work with AspectJ), you wouldn't need to use the @Configurable annotation.

Try removing @Configurable from AbstractService, as it's an abstract class. Also remove @Component from WechatMessageService, because you already have @Service, so there's no need for @Component.

Try the following for your AbstractService class:

public abstract class AbstractService {
    @Resource(name = "genericDao")
    protected GenericDao genericDao;
    //getters, setters
}

Autowiring by name is better performed with @Resource, so you don't need to use qualifiers.



回答2:

Well, turns out I was mistaken in my premise during debugging. While I had no manual initiation of the DAO bean, I was creating a manual instance of the service in the initialization of the tests, because I needed to pass it a dummy object. So yeah...

Thanks to everyone for the help though, as it nudged me to this realization and helped me understand Spring and its annotations better.