Spring ShedLock without Database - spring

I want to disable ShedLock with a configuration yml property. So i don't have to create the table shedlock, if it is not necessary. Is there a way to disable Shedlock usage?
I tried to remove #Bean lockProvider but then I got this message:
No qualifying bean of type 'net.javacrumbs.shedlock.core.LockProvider

If you are using ShedLock in combination with the shedlock-spring dependency, there probably is a #EnableSchedulerLock somewhere in your application. Move the LockProvider bean setup together with the annotation to a separate #Configuration class and add a #ConditionalOnProperty annotation, for example:
#Configuration
#EnableSchedulerLock
#ConditionalOnProperty(value = "shedlock.enabled", matchIfMissing = true)
public class ShedLockConfig {
#Bean
public LockProvider lockProvider(DataSource dataSource) {
// ...
}
}
And add the property
shedlock:
enabled: true
To your application.yml

Related

spring boot: disable #Bean definition from external #Configuration class

I'm using a libreary that contains a #Configuration class which's setting this bean:
#Configuration
public abstract class BaseConfig {
#Bean
public ISchedulerService schedulerService() {
return new HapiSchedulerServiceImpl().setDefaultGroup(HAPI_DEFAULT_SCHEDULER_GROUP);
}
// other beans
}
I need to replace the #Bean definition by my own.
Is there anyway to disable this concreate #Bean definition?
I know, I'm able to disable a #Configuration class using for example:
#SpringBootApplication(exclude = {BaseConfig.class})
However, it's goinf to disable all other #Bean definitions.
Any idea?
Maybe you can use #Primary for your new configuration, but that can lead to another issues. If you can modify the BaseConfig then you can probably use something like
#Bean
#ConditionalOnMissingBean
public ISchedulerService schedulerService() {
return new HapiSchedulerServiceImpl().setDefaultGroup(HAPI_DEFAULT_SCHEDULER_GROUP);
}
and then you should be safe to define your own config.
Did you try enable bean overriding? In your application.properties:
spring.main.allow-bean-definition-overriding=true
But it is difficult to guess which bean will have priority because the bean creation order is determined by dependency relationships mostly influenced in runtime.
If you can modify BaseConfig, you probably should use one of the #Condition... annotation like the #bilak said.

#ConfigurationProperites not binding to property source after upgrading to Spring Cloud Hoxton.SR7

I have a #ConfigurationProperties class that is no longer binding to a YML property source that gets resolved via Spring Cloud Config after upgrading to Hoxton.SR7. This code works fine using Hoxton.SR4 with the latest Spring Boot 2.2.9.RELEASE. Now, my properties are not bound and I'm receiving NPEs when I try to reference them. Following is a snapshot of my code:
#Configuration
public class MyConfiguration {
#Bean
public MyPropertiesBean myPropertiesBean() {
return new MyPropertiesBean();
}
}
#ConfigurationProperties(prefix = "com.acme.properties")
#Validated
public class MyPropertiesBean {
...
}
In src/main/resources/META-INF/spring.factories:
org.springframework.boot.autoconfigure.EnableAutoConfiguration=com.acme.MyConfiguration
Any ideas why my #ConfigurationProperties class doesn't bind after upgrading Spring Cloud to Hoxton.SR7?
You're mixing two ways of binding properties: class and method.
Using a method and #Bean annotation:
#Configuration
public class MyConfiguration {
#Bean
#ConfigurationProperties(prefix = "com.acme.properties")
#Validated
public MyPropertiesBean myPropertiesBean() {
return new MyPropertiesBean();
}
}
This will create MyPropertiesBean and store it inside the application context for you to inject.
Class level bean declaration also creates a bean for you:
#Configuration
#ConfigurationProperties(prefix = "com.acme.properties")
#Validated
public class MyPropertiesBean {
...
}
This will also store a bean.
Although, you should be getting a runtime error when you try to inject MyPropertiesBean as now in your case there's two beans of the same type and Spring cannot resolve with only the type.

Spring Boot Persistence

How does SpringBoot fetch the DataSource configuration from application.properties file.
Would the below configuration persist the entity ?
Module 1 contains Config file and application.properties file
Module 2 contains Repository and Service File
I have not configured any File with #Repository annotation as of now.
contextRepository.saveAndFlush(test);
Spring Boot Configuration class below:
#EnableSwagger2
#SpringBootApplication
#ComponentScan(basePackages={"ch.service"})
public class MyCodeConfiguration extends SpringBootServletInitializer {
//Module1
package ch.service.config;
#Bean
#Primary
#ConfigurationProperties(prefix = "spring.datasource")
public DataSource realDataSource() {
return DataSourceBuilder.create().build();
}
#Bean
#ConditionalOnMissingBean(PlatformTransactionManager.class)
public DataSourceTransactionManager transactionManager() {
DataSourceTransactionManager transactionManager = new DataSourceTransactionManager(realDataSource());
return transactionManager;
}
}
Service Class below.
//Module2
package ch.service.config;
#Service
public class CodeServiceImpl implements CodeService {
#Autowired
private ContextRepository contextRepository;
#Transactional
public void persistValues(Testbean test){
contextRepository.saveAndFlush(test);
}
}
Repository class below
//Module2
package ch.service.config.dao;
public interface ContextRepository extends JpaRepository<MyContext, Long> {
}
Error Below:
***************************
APPLICATION FAILED TO START
***************************
Description:
Parameter 0 of method transactionManager in org.springframework.boot.autoconfigure.transaction.jta.BitronixJtaConfiguration required a bean of type 'javax.transaction.TransactionManager' that could not be found.
- Bean method 'narayanaTransactionManager' not loaded because #ConditionalOnClass did not find required classes 'com.arjuna.ats.jta.UserTransaction', 'org.jboss.tm.XAResourceRecoveryRegistry'
Action:
Consider revisiting the conditions above or defining a bean of type 'javax.transaction.TransactionManager' in your configuration.
When you use Spring Boot you can use the following predefined DB configuration keys in application.properties to automatically configure the database.
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
Your rest of the code looks good. It should persist the data
To fix the Exception you are getting you have to have a Transaction Manager in your config.
#Bean
public PlatformTransactionManager transactionManager() {
return new JpaTransactionManager();
}
Ref : https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-sql.html
If your project has a data starter, for example :
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
And you want it to be connected to a non embedded database, you must setup the configuration in application.properties with spring.datasource.* keys
DataSourceProperties will pick up the configuration
All the spring boot key are here

Spring Boot Application with dependency having multiple datasources

I am trying to create a Spring Boot Application, with a dependency jar which has got context.xml configured with multiple datasources.
In My spring boot application, I added #ImportResource("context.xml") to the #Configuration class and now, I get an exception that
"No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 4: XXXDataSource,YYYDataSource,ZZZDataSource,aaaaDataSource".
I read the documentation on multiple datasources in Spring Boot, but unable to fix this issue. Not sure, how I can configure my class, as I cannot change the dependency jar to change the way datasources are configured.
Please help!
You can use the "Primary" attribute on your datasource bean to make your autowiring choose it by default.
<bean primary="true|false"/>
If you are using Java configuration, use the #Primary annotation instead.
http://docs.spring.io/spring-framework/docs/4.0.4.RELEASE/javadoc-api/org/springframework/context/annotation/Primary.html
#Component
public class FooService {
private FooRepository fooRepository;
#Autowired
public FooService(FooRepository fooRepository) {
this.fooRepository = fooRepository;
}
}
#Component
public class JdbcFooRepository {
public JdbcFooService(DataSource dataSource) {
// ...
}
}
#Primary
#Component
public class HibernateFooRepository {
public HibernateFooService(SessionFactory sessionFactory) {
// ...
}
}
If this still doesn't resolve the issue, you can name the bean, and use the #Qualifier annotation in your java classes, or use the "ref" attribute in your Spring XML configuration.
https://spring.io/blog/2014/11/04/a-quality-qualifier
#Autowired
#Qualifier( "ios") // the use is unique to Spring. It's darned convenient, too!
private MarketPlace marketPlace ;
If you require one of the datasources in the jar and are unable to modify the configuration, rather than importing the xml from the jar, copy the configurations you need into your own local spring context configuration.

Spring #Autowire field based on #Profile

I need to autowire fields based on the spring.profiles.active property.
The service is only created based on the profile but the since the service is autowired in other classes I am unable to use the #Profile annotations.
Is there a way to autowire fields based on profile.
You can create different services implementations per profiles.
In the example below I used mockito to mock the dataSource bean
Ex.
#Configuration
#ComponentScan
class YourConfig {
#Profile("production")
#Qualifier("datasource")
#Bean
public DataSource dataSourceProduction(){
return new DataSourceProduction()
}
#Profile("development")
#Qualifier("datasource")
#Bean
public DataSource dataSourceDevelopment(){
return mock(DataSourceProduction.class);
}

Resources