I'm trying to improve performance of Spring Boot tests by eliminating anything that's unnecessary for given component under test.
Setting spring.main.lazy-initialization=true avoids most of it but I still see database being autoconfigured even though it is not necessary as well as bunch of other stuff.
I can fix that by explicitly excluding it:
#EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)
But is there a way to automatically disable all autoconfigurations that are not necessary - something like lazy autoconfiguration?
Related
I have a project that uses a YAML with all default Boot properties with prefix spring.jms.*, spring.activemq.*... I'm moving it to a starter, so I need to isolate the needed configuration for my internal component from the defaults of the importer application.
Is there any way to nicely deal with this need? Ideally I can take profit transparently of the very same properties classes (JmsConfiguration, etc...) since they include the nested configurations. Perhaps in a way I have 2 blocks with spring.jms and such, and marking my properties as from a particular block.
I know profiles exist, but It feels weird to drive them from an optional component via starter.
Found it!
In the #Configuration:
#Bean
#ConfigurationProperties("custom.jms")
public JmsProperties customJmsProperties(){
return new JmsProperties();
}
Anyway, after some discussions with Pivotal people, it seems like my need is probably a sign of a bad design
I am using Spring Declarative Annotation based caching in my project .
applicationContext.xml
<cache:annotation-driven />
Currently, everything works perfectly using spring annotation based caching.
We use ehCache and ConcurrentHashMap based underline caching mechanism in development and local environment.
Now there is a requirement in project where I need to update the behavior of Spring cache framework with some specific business requirements.
I wonder if any one help me to figure it out how can I replace
<cache:annotation-driven />
this annotation with any spring class definition where I can customize the behavior?
Check out org.springframework.cache.annotation.EnableCaching.
Look at the comments in the source code.
It does the equivalent of the < cache:annotation-driven /> but in spring java config.
You will prolly need to override this class: org.springframework.cache.aspectj.AnnotationCacheAspect
Its responsible for wiring the advise in.
This answer lead me in the right direction. The thing that I found about the inner workings of the caching support from spring is that its not Dependency injected outside of the cacheManager and KeyGenerator implementations. I wanted to subclass/extend the CacheAspectSupport and found that this class is first extended by CacheInterceptor but then that class is created using new statements in a class ProxyCachingConfiguration. To be able to replace the one class/method would take replacing a whole list of classes which doesn't sound very spring friendly (admittedly i could be missing something).
What i was expecting from the replacement of the line was a fully listed out set of spring beans that composed all of the AOP pointcuts, advice/aspects, etc. that make up the caching support, but it seems like this is alål just statically created classes with tight coupling between each other.
I want to use the feature-toggle paradigm. Specifically, I want my Spring contexts to contain different bean definitions based on a toggle.
I've come across this: http://robertmaldon.blogspot.com/2007/04/conditionally-defining-spring-beans.html, which looks ok, but maybe a bit too cumbersome
You can use spring profiles - in short, you run your application with a profile setting, and the context contains different beans depending on that profile.
I believe what you're actually looking for is a way for Spring to manage different configuration profiles.
Unfortunately, at the time of this writing, such a feature does not exist. As far as I know, people usually devise various schemes to get around that, but essentially use Spring's PropertyPlaceholderConfigurer to "inject" different runtime configurations into their property files by placing ${placeholder} into their Spring import statements and then dereferencing this placeholder as their enviroment changes (e.g. "DEV", "TEST", "PROD").
That will be changed by Spring 3.1, though - as it will introduce #Profile annotation which seems well coupled with Spring Java Configuration option, giving one a way to completely abandon XML configuration (should one choose to, of course).
Perhaps this article will shed more light into this: Spring 3.1 M1: Introducing #Profile
I'm fairly new to Spring and my understanding is a bit scratchy so bear with me and word answers for an idiot.
I've started working on a relatively large, maven based project which has a load of (xml) spring configuration. For this we have a bunch of JUnit tests. At the moment spring configuration for the tests replaces the configuration for the core project modules, which is an issue because it means that if we make changes to the configuration of the main project then those changes aren't reflected in the test module and hence it's possible to get funny test results.
We are currently changing this structure so that the test module configuration overrides (rather than replaces) the main modules configuration. So we only have to override the particular beans we are interested in for each tests.
Is this the best way to do this? Are there alternative ways? Is it possible to fine tune this ever further so that you can override specific setters of a particular bean (rather than the entire bean) for tests?
Any advice is much appreciated.
You can split your main configuration in separate (logical) units and import them into your test configuration as needed.
Keep in mind that Spring 3.1 will introduce XML profiles. This is perfect for testing (with different enviroment specific configurations). It's not finally released yet but I would (and do) use the milestone in new projects.
Ow having to mess with the method to test it is a bit weird by it self in my opinion.
I would avoid that at all if possible, and use spring resources to help you, with dependency injection, different application-contexts for test and dev and mock frameworks you can test almost every thing I can think of.
Maybe you could try to use those.
An example, it's a bit hard to simulate an user security context, but with spring it becomes fairly easy, you just need to create an application-context.xml for the tests (and point to it) and assign a factory in it to create a Bean of Authentication type(it's an interface) and you can use easy mock to automate this bean responses.
But for that to work you have to build your code with that in mind so instead of calling SecurityContext.getContext.... you inject that Authentication Bean from the factory.
In your main configuration separate out all the environment dependent configuration (like datasource, jms connectionfactory etc) to a separate config file - (something like infrastructure-config.xml). The configuration that doesn't change across test & deploy goes into a different file - application-config.xml.
Now for the test only create a new version of the infrastructure config file - test-infrastructure-config.xml and use it with the application-config from the main.
Just trying to understand how Java annotations work under the covers.
Seeing as spring relies on annotations and scanning the object graph for DI and AOP (reflection), curious how things actually work.
With spring, are all lookup mappings etc. done at startup, so at runtime spring looks at its own inner mappings for DI/AOP/etc. instead of scanning the entire object graph?
Performance wise, if what I am guessing above is correct, it is basically performing a hash lookup?
Spring scans classes in the specified package when <context:component-scan> is present in the config.
Otherwise, Spring only looks at the annotations of classes explicitly declared in the config.
It is not true that Spring "relies" on annotations. Configuring your classes via annotations is just one option, using XML or other configuration files is another.