I've enabled caching in a SpringBoot application with the #EnableCaching and #Cacheable annotations. The cache properties are defined in the application.yaml file.
spring
cache
type=simple
Now I want to know if there is a way to access explicitly the cacheManager bean defined by Spring Boot(created to support the #EnableCaching annotation) without defining a new CacheManager Bean in the configuration files.
I'm basically trying to autowire the cacheManager bean defined by Spring Boot so that I can make explicit calls to it.
#Autowired
private CacheManager cacheManager;
...
Cache cache = cacheManage.getCache("toto")
Regards
Notes: My IDE is telling me that It can't autowire the cacheManager bean
Finally, the IDE warning was wrong. I was able to autowire the cache manager bean provided by Spring Boot and I was able to call it explicitly.
Regards
Related
I want my spring boot server to be up even if my redis cache isnt up.
I am using #EnableCachingannotation , but my server startup fails if redis is down giving me BeanCreationException. Because BeanCreationException cannot be handled , the only option I have is to lazy load my #EnableCaching class.
I tried annotating that class as under:
#Configuration
#EnableCaching
#Lazy
#Profile("dev")
public class RedisCache extends CachingConfigurerSupport {}
But still this bean is getting loaded at server startup and startup therefore fails.
How do I lazy load the above mentioned class
As far as I know Spring configuration is alwasy loaded on application startup, because that is when the ApplicationContext is created.
In order to do what you want you'd either have to create some sort of custom implementation of ApplicationContext (although I honestly cannot think of how it should work regarding the dependency resolution for dependency injection) or create custom wrapper for caching which would not try to establish connection to Redis until the cache is used.
It may also be possible to configure Spring Boot to skip this particular #Configuration class (Using Boot configuration classes) and then to manually create AnnotationConfigApplicationContext and then retrieve Redis connection Beans from this context manually rather than autowiring them.
I have a scenario where I'd like to have a #Primary DataSource bean that depends on another DataSource bean. I am currently encountering a BeanCurrentlyInCreationException exception when I do this because the DataSourceInitializer triggers resolution of the #Primary bean while it is still being created.
I've created an example repository that reproduces this issue and explains it in more detail, if helpful: https://github.com/zachmarshall/spring-datasource-init-bug
A Spring Boot issue was created for this. There was acknowledgement that the code is at least problematic, but no real resolution yet.
Ultimately, I did find a workaround:
...by using #DependsOn("dataSourceInitializer") on the #Primary bean definition, spring eagerly creates the dataSourceInitializer bean before the primary is marked as in creation. Kind of a hack but works for now.
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.
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.)
I'm having trouble with a field annotated as #Resource in a Spring bean. What I have:
A field, with setter method, annotated #Resource
#Resource
private URL someUrl;
public void setSomeUrl(URL someUrl) {
this.someUrl = someUrl;
}
An <env-entry> tag in my deployment descriptor (web.xml)
<env-entry>
<env-entry-name>someUrl</env-entry-name>
<env-entry-type>java.net.URL</env-entry-type>
<env-entry-value>http://somedomain.net/some/path</env-entry-value>
</env-entry>
The application fails to start with a BeanCreationException, which I dont' expect because I don't necessarily want spring to inject a Spring-managed bean. I want Spring to process #Resource and retrieve the JNDI resource.
This is Spring 2.5.6SEC03 and the bean itself is annotated #Service for autowiring into other #Component instances. Servlet container in this case is Tomcat 7 but will ultimately be deployed onto Weblogic 10, so while I'd like ideally for a solution to work on both, Weblogic is the must-have.
Am I misusing this feature in Spring 2.5? In general? Is there some bit I'm missing? Something I misunderstand about JNDI? All help is appreciated. Thanks.
If you are using Spring Stereotype annotations, (#Service, #Component...), then you are probably including in your spring configuration the <context:component-scan /> element to pick them up. It is fine to do this, but it will automatically register a CommonAnnotationBeanPostProcessor with the application context, as stated just above the second note in this link.
The issue with including the CommonAnnotationBeanPostProcessor is that Spring handles the #Resource annotation and will attempt to inject beans from its application context. You can register your own CommonAnnotationBeanPostProcessor bean and tell Spring to allow direct JNDI access to these #Resource's by configuring the bean by setting the alwaysUseJndiLookup property to true.
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true"/>
</bean>
Pay attention to the note in the linked documentation:
NOTE: A default CommonAnnotationBeanPostProcessor will be registered by the "context:annotation-config" and "context:component-scan" XML tags. Remove or turn off the default annotation configuration there if you intend to specify a custom CommonAnnotationBeanPostProcessor bean definition!