11 Mart 2020 Çarşamba

SpringData Jdbc DriverManagerDataSource Sınıfı

Giriş
Şu satırı dahil ederiz.
import org.springframework.jdbc.datasource.DriverManagerDataSource;
JDBC DataSource arayüzünün Spring Bean olarak kullanılabilmesini sağlar. Bu sınıfı sadece test ortamında kullanılabilir. gerçek ortamda kullanmamak lazım. Açıklaması şöyle.
This class is not an actual connection pool; it does not actually pool Connections. It just serves as simple replacement for a full-blown connection pool, implementing the same standard interface, but creating new Connections on every call.
If you need a "real" connection pool outside of a J2EE container, consider Apache's Jakarta Commons DBCP or C3P0. Commons DBCP's BasicDataSource and C3P0's ComboPooledDataSource are full connection pool beans, supporting the same basic properties as this class plus specific settings (such as minimal/maximal pool size etc).
Bu sınıf örneğin org.springframework.orm.hibernate5.LocalSessionFactoryBean nesnesine geçilir.

XML
Şöyle yaparız.
<bean id="postgresDataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource"
  p:driverClassName="org.postgresql.Driver"
  p:url="jdbc:postgresql://localhost:5432/test?createDatabaseIfNotExist=true"
  p:username="test"
  p:password="test"/>

<bean id="sqlDataSource"
  class="org.springframework.jdbc.datasource.DriverManagerDataSource"
  p:driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"
  p:url="jdbc:sqlserver://localhost:1433;databaseName=test"
  p:username="test"
  p:password="test"/>
constructor
Örnek
Şöyle yaparız.
DriverManagerDataSource dataSource = new DriverManagerDataSource();
Örnek
Şöyle yaparızz
@Bean(name = "dataSource")
public DataSource creatDataSource() {
  DriverManagerDataSource ds = new DriverManagerDataSource();
  ds.setDriverClassName(driverClassName);
  ds.setUrl(url);
  ds.setUsername(username);
  ds.setPassword(password);
  return ds;
}
setDriverClassName metodu
Şöyle yaparız.
dataSource.setDriverClassName("org.mariadb.jdbc.Driver");
setUrl metodu
Şöyle yaparız.
dataSource.setUrl("jdbc:mysql://localhost:3306/rshared?autoReconnect=true");
setUsername metodu
Şöyle yaparız.
dataSource.setUsername("root");
setPassword metodu
Şöyle yaparız.
dataSource.setPassword("root");

10 Mart 2020 Salı

SpringBoot @ConditionalOnProperty Anotasyonu

Giriş
Belirtilen property belirtilen değere sahipse bean nesnesini yaratır. Böylece bazı ayarları değiştirerek uygulamayı açarsak davranışı değiştirebiriliz.

havingValue Alanı
name ile belirtilen alan havingValue ile belirttiğimiz değere sahipse bean yaratılır. Burada name ile belirtilen alanın application.properties içinde olduğu varsayılır

matchIfMissing Alanı
true ise name ile belirtilen property yok bean yaratılır

Örnek
Property yoksa bean yaratmak için şöyle yaparız.
@Configuration
public class LoggingConfiguration {
  @Configuration
  @ConditionalOnProperty(name = "logging.enabled", matchIfMissing = true)
  public static class Slf4jConfiguration {

    @Bean
    Logger logger() {
      return LoggerFactory.getLogger("sample");
    }
  }

  @Bean
  @ConditionalOnMissingBean
  Logger logger() {
    return new NOPLoggerFactory().getLogger("sample");
  }
}

name/value Alanı
application.properties dosyasındaki alanı belirtir.

Örnek
Eğer hiç bir havingValue değeri tanımlamazsak şöyle yaparız
@Configuration
@PropertySource("classpath:config/service/application.properties")
public class ApplicationConfig {
  @Bean
  @ConditionalOnProperty("client.one.host")
  public ServiceOneClient serviceClient(@Value("${client.one.host}") String host)) {
    return new ClientOneImpl(String.format("%s:%d", host, 80));
  }

  @Bean
  @ConditionalOnProperty("client.two.host")
  public ServiceTwoClient serviceClient(@Value("${client.two.host}") String host)) {
    return new ClientTwoImpl(String.format("%s:%d", host, 80));
  }
}
Örnek
havingValue ile transaction desteğini açıp kapatmak isteylim. Elimizde şöyle bir kod olsun.
// assuming this property is stored in Spring application properties file
@ConditionalOnProperty(name = "turnOffTransactions", havingValue = "true")) 
@Bean   
@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
public TransactionInterceptor transactionInterceptor(
         /* default bean would be injected here */
         TransactionAttributeSource transactionAttributeSource
) {
    TransactionInterceptor interceptor = new NoOpTransactionInterceptor();
    interceptor.setTransactionAttributeSource(transactionAttributeSource);
    return interceptor;
}
Şöyle yaparız. Böylece Spring transaction yaratmaz.
public class NoOpTransactionInterceptor extends TransactionInterceptor {

    @Override
    protected Object invokeWithinTransaction(
        Method method, 
        Class<?> targetClass, 
        InvocationCallback invocation
    ) throws Throwable {
        // Simply invoke the original unwrapped code
        return invocation.proceedWithInvocation();
    }
}
Örnek
application.properties dosyasında satır şöyle olsun.
admin.enabled=false
Şöyle yaparız.
@Configuration
@ConditionalOnProperty(name = "admin.enabled", havingValue=true)
public class AdminControllersConfiguration {

  @Bean 
  public AdminControllerFromModuleApi1 adminController() {
    return new AdminControllerFromModuleApi1();
  }
}
Örnek
Şöyle yaparız.
@Service
@ConditionalOnProperty(value = "polling.enabled", havingValue = "true")
public class MessageQueueService {

  @Scheduled(fixedDelay = INTERVAL_MS)
  public void execute() {
    ...
  }
}