Defining Spring beans without per class bean config - java

How is it possible to define a Spring beans which need only #Autowired for defining new bean of certain type?
I have seen a solution, where service layer services are created without extra bean definitions for the new service. With bean definition I mean a line on config file specific to this service.
Is it possible to define beans so that certain package for example com.foo.bar.service.* become automatically defined with only adding #Autowired when calling it and not defining any other config per class in that package?

You might be able to write your own code that scans a Java package, and adds a bean for each of the classes found. That's not usually what is required, as many packages have helper classes that should not be exposed as beans.
But more likely, the beans will have one of the #Component, #Repository, #Service, #Controller annotations on them, and Spring will then register these as beans.
http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-scanning-filters

Related

Why EntityScan , EnableJpaRepositories annotations required if we are already using componentScan annotation?

I am already using componentScan annotation in main class of spring boot app , but If I use only this annotation it will gives issue while getting repositories reference. So to overcome this I am using EntityScan and EnableJpaRepositories annotations with componentScan.
#EntityScan(basePackages={"com.gonkar.fleetms.models"})
#EnableJpaRepositories(basePackages={"com.gonkar.fleetms.repositories"})
So my question is why its required to use other two annotations? if I am already using componentScan.
The #ComponentScan annotation is used to create beans for classes annotated with #Component, #Controller / #RestController, #Service, #Repository. It marks them for being added to the Spring container (making them eligible for dependency injection and allowing them to be #Autowired).
The #EntityScan annotation doesn't create any beans, it identifies which classes should be used by a JPA persistence context.
The #EnableJpaRepositories annotation is used to create repository classes from Spring Data interfaces.
All three annotation are often used together, but they are responsible for different things.

Spring #Autowired detection

If I have a class which uses a spring bean, (will be wired via #Autowired).
I noticed that not only the class that will be injected needs the #Component but also the class the uses it (inject it). Why is it like that? Should not spring inject wherever #Autowired is? Without having to use #Component for the injector class?
Spring processes and manages only those classes which are marked by one of stereotype annotations #Component, #Controller, #Repository, #Service.
It does not scan all of your classes (that would make the startup very slow).
If the class is not managed by Spring it does not process any of the annotation inside that particular class.
In Spring, one works with beans. A bean is a java object that is managed by a spring context. When encountering a bean containing an #Inject, Spring will seach its context for a bean of the type of the variable to be injected. If no such bean is defined, Spring will have nothing to inject. Also, if the class with the #Inject doesn't have a bean, then Spring won't know about it, and thus cannot inject anything into it.
To get Spring to create a bean of a class, several methods are available. Through annotations, the class has to be annotated with #Component, or the more specialized annotations #Service, #Repository and #Controller. Only then will Spring create a bean for the class that can be #Injected into other beans.

order how spring scan the beans defined with #service #component or #repository

anyone of you do know which rule use when scan to instanced the spring beans defined with #component, #service or #repository, since when deploy an application into a environment spring instanced beans in one order and on other environment(with the same characteristics as the previous) the order is totally different, and because of this I get an error related to cyclic dependencies.
thanks,
sorin

Autowired Dependency Injection with Spring Security

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?
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.)

What is #Service in Spring MVC

If I use #Service on a service class, do I need to make a service class bean in my servlet xml file or do I have to do both?
You don't have to declare a bean in your context file if you:
1) Annotate the class with:
#Component, #Service, #Controller or #Repository
2) Include the context:component-scan element in your context file like this:
<context:component-scan base-package="your.package" />
Hope that helps.
Last time I looked (Spring 2.5) #Service was a marker annotation subclassed from #Component, but with no additional behaviour. Which means that beans tagged with #Service become candidates for auto detection if you are using annotation-based configuration via classpath scanning.
As per the docs, the intention is that this annotation might include service layer specific functionality in future Spring releases. It can also act as an AOP point cut for all of your service layer components.

Categories

Resources