We have a use case to not use Spring session, i.e. not have #EnableRedisHttpSession annotation even though Spring Session and Spring boot are in the classpath. We used to do that by having a custom property spring.session.enabled and having a #ConditionalOnProperty on the class that had the #EnableRedisHttpSession annotation. This worked in Spring boot 1.2.7. However with Spring Boot 1.3.0, the SessionAutoConfiguration class has a #EnableRedisHttpSession annotation on it.
Is there a way to disable the class from being used?
To disable Spring Boot Auto-Configuration of Spring Session:
#SpringBootApplication(exclude = {SessionAutoConfiguration.class})
public class Application
{
...
}
Then, to enable Spring Session depending on a property (for example, you may want it disabled when in development but enabled in production):
#Configuration
#ConditionalOnProperty(value = "spring.session.enabled", havingValue = "true", matchIfMissing = false)
#EnableRedisHttpSession
public class HttpSessionConfig
{
...
}
I had the same question and through the comments, I was able to get my answer so I'm putting this down here so the question is marked as answered:
Related
With Spring Boot 2.2.0 the "httptrace" Actuator endpoint doesn't exist anymore. How can I get this functionality back?
The functionality has been removed by default in Spring Boot 2.2.0.
As a workaround, add this configuration to the Spring environment:
management.endpoints.web.exposure.include: httptrace
and provide an HttpTraceRepository bean like this:
#Configuration
// #Profile("actuator-endpoints")
// if you want: register bean only if profile is set
public class HttpTraceActuatorConfiguration {
#Bean
public HttpTraceRepository httpTraceRepository() {
return new InMemoryHttpTraceRepository();
}
}
http://localhost:8080/actuator/httptrace works again.
You need to enable httptrace by having following application properties. By default it is disabled
management.trace.http.enabled: true
management.endpoints.web.exposure.include: httptrace
and Requires an HttpTraceRepository bean. You can use Your own Custom implementation or InMemoryHttpTraceRepository
I've got a Spring WebFlux application running successfully as a standalone spring boot application.
I am attempting to run the same application in a Tomcat container, and following the documentation, I've created a class that extends AbstractReactiveWebInitializer. The class requires that I implement a method getConfigClasses that would return classes normally annotated with #Configuration. If the working spring boot app started with a class called ApplicationInitializer, then the resulting implementations would look like this:
#SpringBootApplication(scanBasePackages = "my.pkg")
#EnableDiscoveryClient
#EnableCaching
public class ApplicationInitializer {
public static void main(String... args) {
SpringApplication.run(ApplicationInitializer.class, args);
}
}
and
public class ServletInitializer extends AbstractReactiveWebInitializer {
#Override
protected Class<?>[] getConfigClasses() {
return new Class[] {ApplicationInitializer.class};
}
}
When deployed, the only thing that starts is ApplicationInitializer, none of the autoconfigured Spring Boot classes (Cloud Config, DataSource, etc) ever kick off.
The documenation states this is the class I need to implement, I just expected the remainder of the spring environment to "just work".
How should I be using this class to deploy a Reactive WebFlux Spring Boot application to a Tomcat container ?
Edit:
After some additional research, I've narrowed it down to likely just Cloud Config. During bean post processing on startup, the ConfigurationPropertiesBindingPostProcessor should be enriched with additional property sources (from cloud config), but it appears to be the default Spring properties instead, with no additional sources.
The misisng properties is causing downstream beans to fail.
Spring Boot does not support WAR packaging for Spring WebFlux applications.
The documentation you're referring to is the Spring Framework doc; Spring Framework does support that use case, but without Spring Boot.
you can extend SpringBootServletInitializer, add add reactive servlet on onStartup method
Before migrating to Spring Boot 2.1, we had a couple of controller tests in our services utilizing #WebMvcTest in combination with #AutoConfigureMockMvc:
#WebMvcTest(SomeController.class)
#AutoConfigureMockMvc(secure = false)
public class SomeControllerTests { ... }
This had the effect that the Spring Security configuration was disabled and you could run MVC tests without mocking OAuth/JWT.
In Spring Boot 2.1, the secured attribute is deprecated and the release notes mention that
[...] #WebMvcTest looks for a WebSecurityConfigurer bean [...].
In order to avoid the deprecated secured attribute and loading of our WebSecurityConfigurer we rewrote our tests to:
#WebMvcTest(
value = SomeController.class,
excludeFilters = #ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = WebSecurityConfigurer.class),
excludeAutoConfiguration = MockMvcSecurityAutoConfiguration.class)
public class SomeControllerTests { ... }
The question is: is there a more compact way in Spring Boot 2.1 to define such tests?
Yes, rather than working around the fact the flag is deprecated, you should embrace the fact that this is going in that direction going forward.
As of Spring Boot 2.1, if you have Spring Security, your tests will be secured using your custom configuration. What is the actual problem with that?
If you don't want to authenticate for certain tests, just use Spring Security's test infrastructure and add #WithMockUser.
Encountered the same scenario and what helped was using the below annotations instead of #WebMvcTest. In this case, #WithMockUser did not help.
#WebAppConfiguration
#Import({MockMvcAutoConfiguration.class})
#EnableConfigurationProperties({ResourceProperties.class, WebMvcProperties.class})
Classes that existed in controllers / value of #WebMvcTest goes into value of #Import annotation.
Source: https://github.com/spring-projects/spring-boot/issues/14227#issuecomment-688824627
Is #EnableTransactionManagement required in Spring Boot?
I did some research. Some folks say you don't need it, as Spring Boot has it already enabled, others say you do have to use it explicitly. So how is it?
Probably you're also using Spring Data. Calls on Spring Data repositories are by default surrounded by a transaction, even without #EnableTransactionManagement. If Spring Data finds an existing transaction, the existing transaction will be re-used, otherwise a new transaction is created.
#Transactional annotations within your own code, however, are only evaluated when you have #EnableTransactionManagement activated (or configured transaction handling some other way).
You can easily trace transaction behavior by adding the following property to your application.properties:
logging.level.org.springframework.transaction.interceptor=TRACE
(see Showing a Spring transaction in log)
According to > https://spring.io/guides/gs/managing-transactions/
Spring Boot will detect spring-jdbc on the classpath and h2 and will create a DataSource and a JdbcTemplate for you automatically. Because such infrastructure is now available and you have no dedicated configuration, a DataSourceTransactionManager will also be created for you: this is the component that intercepts the #Transactional annotated method.
You can also use spring-boot-starter-actuator to list your beans created in your context and you will find it
bean": "transactionManager"
Little old post but the answers given previously were not straight forward when I was searching for it.
#EnableTransactionManagement is optional in Spring boot, provided that spring-data* or spring-tx are found in classpath. How it works? As below:
Spring boot adds a spring-boot-autoconfigure.jar in the classpath. Go to the META-INF's spring.factories file and you can see org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration entry there. This initializes the transaction auto configuration for you.
Note that the class has following lines: (snippet)
#Configuration
#ConditionalOnClass({PlatformTransactionManager.class})
#AutoConfigureAfter({JtaAutoConfiguration.class, HibernateJpaAutoConfiguration.class, DataSourceTransactionManagerAutoConfiguration.class, Neo4jDataAutoConfiguration.class})
#EnableConfigurationProperties({TransactionProperties.class})
public class TransactionAutoConfiguration {
..
}
Have a look at TransactionAutoConfiguration to see that it enables transaction support if the PlatformTransactionManager is available in classpath. EnableTransactionManagementConfiguration is also configured there.
No. #EnableTransactionManagement is on by default, see that: https://github.com/jkubrynski/spring-boot/commit/9d219ef7a004c58a88bbbef82a520a22961c9402
#EnableTransactionManagement is conditionally turned on/off based of the dependency jars we add in the classpath. If we use spring data jpa starter it is turned on.
In the class org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration, there is such code(Spring Boot 1.5+):
#Configuration
#EnableTransactionManagement(proxyTargetClass = false)
#ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "false", matchIfMissing = false)
public static class JdkDynamicAutoProxyConfiguration {
}
#Configuration
#EnableTransactionManagement(proxyTargetClass = true)
#ConditionalOnProperty(prefix = "spring.aop", name = "proxy-target-class", havingValue = "true", matchIfMissing = true)
public static class CglibAutoProxyConfiguration {
}
The default is spring.aop.proxy-target-class=true, enabling CGLIB proxy by default.
If you want to use JDK proxy, set spring.aop.proxy-target-class=false instead.
In my spring boot application i configure two different instances of MQQueueConnectionFactory (different id) as it is a need of the application. For that i have added ibm client jars.
I have also added spring-jms dependency in my code as i wanted JmsTemplate etc classes. After adding this dependency, JmsAutoConfiguration finds JmsTemplate in classpath and tries to configure beans. In this process, it tries to inject bean of type ConnectionFactory and this is where the code fails and i start getting the error. Below is the code from JmsAutoConfiguration
#Configuration
#ConditionalOnClass(JmsTemplate.class)
#ConditionalOnBean(ConnectionFactory.class)
#EnableConfigurationProperties(JmsProperties.class)
#Import(JmsAnnotationDrivenConfiguration.class)
public class JmsAutoConfiguration {
#Autowired
private JmsProperties properties;
#Autowired
private ConnectionFactory connectionFactory;
#Autowired(required = false)
private DestinationResolver destinationResolver;
Do i have a facility to switch off JmsAutoconfiguration feature of spring boot by any chance? If not then what is the alternative solution for this?
You can add the auto configurations, which you want to disable, to the SpringBootApplication annotation:
#SpringBootApplication(exclude = JmsAutoConfiguration.class)
FYI, use this to disable ActiveMQ
#SpringBootApplication(exclude = ActiveMQAutoConfiguration.class)
if want to control it via the properties (in this case a application.yml) then you can do something like this.
spring:
autoconfigure:
exclude: org.springframework.boot.autoconfigure.jms.JmsAutoConfiguration
In my case it worked after excluding both classes :
#EnableAutoConfiguration(exclude={JmsAutoConfiguration.class, ActiveMQAutoConfiguration.class})