3
votes

I have a spring webapp with annotation driven configuration.

All Controllers, Repositories are autowired.

When integrating Spring Security I defined a separate security-app.xml. I created a Service called LoginUserService which implements UserDetailsService. Now the method loadUserByUsername() method of this class gets invoked for authentication.

This class has an autowired dependency for UserRepository. Now this autowired dependency turns out to be null. To fix this I enable annotation driven configuration and add the package name for the repository class in component scan configuration.

This solution is also discussed here spring security with custom user details

But now the problem is that the UserRepository has an EntityManager field with @PersistenceContext annotation. For the spring security configuration it is able to locate the UserRepository but not able to locate the entity manager. Should I create a new EntityManagerFactory here? I guess that will create two persistence units in my application?

How can I inject an autowired dependency to UserRepository created with the original servlet xml?

Update

This is briefly discussed here: https://stackoverflow.com/a/7078395/161628

But I guess a canonical detailed answer will be more useful to me.

Update

How about using ApplicationContext to get the UserRepository at runtime?

if (userRepository == null) {
    userRepository = ApplicationContextProvider.getApplicatonContext().getBean(UserRepository.class);
}

Why is Spring's ApplicationContext.getBean considered bad?

1

1 Answers

1
votes

EDIT: Beans that you declare in your config for your DispatcherServlet are not going to be available to any beans you declare or component scan in your contextConfigLocation config files. So in this case, if you're setting up your JPA config in your config file that you load for your DispatcherServlet there is no way to wire that in to beans your declare in your security config. You need to move any "core" bean config like that (datasource config, db connection pool config, JPA/Hibernate config, repository/service component scanning, etc.) into a config file that you load via the contextConfigLocation. Then that stuff will be available both to your security beans and your MVC beans. I think generally the idea is to only load MVC specific beans in your DispatcherServlet config (e.g. Controllers, views, request handlers, request scoped beans, etc.). That way you ensure you have a clean separation between MVC code and non-MVC code, with only a one-way dependency from the MVC code to the "core" code, and no dependencies on MVC code in your "core" code. This helps make your code more modular, and makes it easier to reuse your "core" code in other ways, specifically in unit tests.

(Original comment text was asking about how the security config is loaded, if it's in the contextConfigLocation or somewhere else.)