@Autowired object gets a null value in one class, while successfully wired in another

前端 未结 5 1127
小鲜肉
小鲜肉 2021-02-19 01:32

I am working on a project using Spring 3, and Spring Security. My problem is with IoC container. Problem started when I wrote my own implementation of UserDetailsService

相关标签:
5条回答
  • 2021-02-19 01:47

    I had the same problem. Although this can happen in many ways, in my case I was creating a new object, instead of using the autowired one. i.e.:

    private Service service = new ServiceImpl();
    

    instead of:

    @Autowired private Service service;
    

    This was not in the Service using the Repository injection, but in a controller on top of that.

    0 讨论(0)
  • 2021-02-19 01:50

    yes, it seems to be impossible to autowire objects into beans that inherit from spring security classes. i don't know if this is a bug in spring security, or if it's done for security or what. if anyone has an explanation I would be interested in hearing it. You can solve your problem though by manually injecting the beans via xml configuration (as opposed to using the @Autowired annotation) and then they will be present. One word of caution though..

    I did this, and i noticed that my userDao which had annotations on it (specifically @Transactional) was no longer operating in a transaction. My userDao was being used in multiple places. If I injected it into my custom AbstractUserDetailsAuthenticationProvider though, it no longer operated in a transaction for any other class that used it. Removing the injection into the custom AbstractUserDetailsAuthenticationProvider restored the transaction functionality to my userDao when used by other objects which were receiving it (either via @Autowired or manual xml injection).

    So how did I get my userDao into my Spring Security context and still keep it @Transactional? I had to create a Factory class:

    public class UserDaoFactory {
    
    private static UserDao userDao;
    
    public static UserDao getUserDao() {
        return UserDaoFactory.userDao;
    }
    
    public void setUserDao(UserDao userDao) {
        UserDaoFactory.userDao = userDao;
    }
    }
    

    Then put this and your dao two objects into the spring container:

    <bean id="userDao" class="com.package.UserDaoImpl">
        <property name="sessionFactory" ref="sessionFactory" />
    </bean>
    
    <bean id="userDaoFactory" class="com.package.UserDaoFactory">
        <property name="userDao" ref="userDao" />
    </bean>
    

    So the userDao will get autowired into your userDaoFactory. It will have all of it's @Transactional capability (because spring security hasn't stripped it off?). Then in your spring security object you can do a:

    userDao = UserDaoFactory.getUserDao();
    

    I implemented ServletContextAware in my custom AbstractUserDetailsAuthenticationProvider object to do the above once during initialization, and viola.

    So note, while you can manually inject your bean via xml configuration into the spring security object to overcome the @Autowired problem, you will end up with a new problem if you are trying to wrap that DAO in @Transactional.

    now maybe someone knows why this may be happening. it could be a mis-configuration on my part (i admit i'm not a spring expert), or it could be a feature of spring. i would love to hear what anyone has to say and how to improve this though.

    0 讨论(0)
  • 2021-02-19 01:56

    I don't know why :( but removing the tag from project-security.xml and will work!

    http://forum.springsource.org/showthread.php?115561-Autowire-on-custom-authentication-provider-doesn-t-work

    0 讨论(0)
  • 2021-02-19 01:57

    This is likely due to SEC-1911 which causes issues when relying on BeanPostProcessors like AutowiredAnnotationBeanPostProcessor and using the <debug /> element. Try removing <debug /> and seeing if @Autowired works again. Note that this first issue is a duplicate of SEC-1885, which is where this is fixed but the first issue's symptoms better match up with this issue.

    0 讨论(0)
  • 2021-02-19 02:00

    Since the second bean is not in the specified bean annotation package component scan as specified in project-servlet.xml:

    <context:component-scan base-package="com.project" />
    

    it does not consider it to be a service and does not translate the annotations.

    You need to extend it further or move it to a package starting with com.project or else like this:

    <context:component-scan base-package="com" />
    
    0 讨论(0)
提交回复
热议问题