Sunday, February 9, 2014

Spring çatısında Profile kullanımı

Spring 3.1 ile gelen yeniliklerden biri, değişik ortamlar için farklı ayarlar kullanmamıza olanak sağlayan profil tanımlamasıdır. Yazılım bir dizi etkinlik sonucu ortaya çıkar. Yazılım yaşam döngüsü olarak adlandırılan bu süreçte, yazılımın farklı ortamlarda çalıştırılır: geliştirme ortamı, test ortamı, üretim ortamı. Bu farklı ortamların ayarlarını her bir ortam için geliştirdiğimiz profillerde tanımlıyoruz. Profilleri Spring çatısının XML tabanlı yapılandırma dosyasında tanımlayabileceğimiz gibi @Profile damgasını kullanarak Java tabanlı olarak da tanımlayabiliriz.

1. XML tabanlı yapılandırma dosyasında profil tanımlama

spring-config.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xmlns:util="http://www.springframework.org/schema/util"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
 <beans profile="prod">
  <context:component-scan base-package="com.example.service" />
  <context:component-scan base-package="com.example.dao">
    <context:exclude-filter type="regex" expression=".*InMemory.*"/>
  </context:component-scan>
  <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
   <property name="dataSource" ref="dataSource" />
  </bean>
  <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
   <property name="driverClassName" value="com.mysql.jdbc.Driver" />
   <property name="url" value="jdbc:mysql://localhost:3306/customerdb" />
   <property name="username" value="root" />
   <property name="password" value="root" />
  </bean>
 </beans>
 <beans profile="dev">
  <context:annotation-config />
  <context:component-scan base-package="com.example.service" />
  <context:component-scan base-package="com.example.dao">
    <context:exclude-filter type="regex" expression=".*Jdbc.*"/>  
  </context:component-scan>
  <bean id="123456789101" class="com.example.domain.Customer">
   <property name="firstName" value="Jack" />
   <property name="lastName" value="Shephard" />
   <property name="identityNo" value="123456789101" />
  </bean>
  <bean id="109876543210" class="com.example.domain.Customer">
   <property name="firstName" value="Kate" />
   <property name="lastName" value="Austen" />
   <property name="identityNo" value="109876543210" />
  </bean>
 </beans>
</beans>

com.example.domain.Customer.java:
package com.example.domain;

public class Customer {
 private String firstName;
 private String lastName;
 private String identityNo;

 public Customer() {
 }

 public String getFirstName() {
  return firstName;
 }

 public void setFirstName(String firstName) {
  this.firstName = firstName;
 }

 public String getLastName() {
  return lastName;
 }

 public void setLastName(String lastName) {
  this.lastName = lastName;
 }

 public String getIdentityNo() {
  return identityNo;
 }

 public void setIdentityNo(String identityNo) {
  this.identityNo = identityNo;
 }

 @Override
 public String toString() {
  return "Customer [firstName=" + firstName + ", lastName=" + lastName
    + ", identityNo=" + identityNo + "]";
 }

 @Override
 public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result
    + ((identityNo == null) ? 0 : identityNo.hashCode());
  return result;
 }

 @Override
 public boolean equals(Object obj) {
  if (this == obj)
   return true;
  if (obj == null)
   return false;
  if (getClass() != obj.getClass())
   return false;
  Customer other = (Customer) obj;
  if (identityNo == null) {
   if (other.identityNo != null)
    return false;
  } else if (!identityNo.equals(other.identityNo))
   return false;
  return true;
 }
}

com.example.dao.CustomerDao.java:
package com.example.dao;

import com.example.domain.Customer;

public interface CustomerDao {
 void addCustomer(Customer customer);
 void deleteCustomer(String id);
 void updateCustomer(Customer customer);
 Customer findCustomerById(String id);
}

com.example.dao.CustomerInMemoryDao.java:
package com.example.dao;

import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Repository;
import com.example.domain.Customer;

@Repository("custdao")
@Profile("dev")
public class CustomerInMemoryDao implements CustomerDao {
 @Autowired
 private Map<String, Customer> customers;

 public CustomerInMemoryDao() {
 }

 public void setCustomers(Map<String, Customer> customers) {
  this.customers = customers;
 }

 public void addCustomer(Customer customer) {
  customers.put(customer.getIdentityNo(), customer);
 }

 public void deleteCustomer(String id) {
  customers.remove(id);
 }

 public void updateCustomer(Customer customer) {
  if (customers.containsKey(customer.getIdentityNo())) {
   customers.put(customer.getIdentityNo(), customer);
  }
 }

 public Customer findCustomerById(String id) {
  return customers.get(id);
 }
}

com.example.dao.CustomerJdbcDao.java:
package com.example.dao;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
import com.example.domain.Customer;

@Repository("custdao")
@Profile("prod")
public class CustomerJdbcDao implements CustomerDao {
 private static final String SQL_INSERT_CUSTOMER = "INSERT INTO CUSTOMERS(IDENTITYNO,FIRSTNAME,LASTNAME) VALUES ( ? , ? , ?)";
 private static final String SQL_SELECT_CUSTOMER_BY_ID = "SELECT * FROM CUSTOMERS WHERE IDENTITYNO=?";
 private static final String SQL_DELETE_CUSTOMER_BY_ID = "DELETE FROM CUSTOMERS WHERE IDENTITYNO=?";
 private static final String SQL_UPDATE_CUSTOMER_BY_ID = "UPDATE CUSTOMERS SET FIRSTNAME = ? , LASTNAME = ? WHERE IDENTITYNO = ?";

 @Autowired
 private JdbcTemplate jdbcTemplate;

 public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
  this.jdbcTemplate = jdbcTemplate;
 }

 public CustomerJdbcDao() {
 }

 @Override
 public void addCustomer(Customer customer) {
  jdbcTemplate.update(
    SQL_INSERT_CUSTOMER,
    new Object[] { customer.getIdentityNo(),
      customer.getFirstName(), customer.getLastName() });
 }

 @Override
 public void deleteCustomer(String id) {
  jdbcTemplate.update(SQL_DELETE_CUSTOMER_BY_ID, new Object[] { id });
 }

 @Override
 public void updateCustomer(Customer customer) {
  jdbcTemplate.update(SQL_UPDATE_CUSTOMER_BY_ID,
    new Object[] { customer.getFirstName(), customer.getLastName(),
      customer.getIdentityNo() });
 }

 @Override
 public Customer findCustomerById(String id) {
  return jdbcTemplate.queryForObject(SQL_SELECT_CUSTOMER_BY_ID,
    new Object[] { id }, new BeanPropertyRowMapper<Customer>(
      Customer.class));
 }
}

com.example.TestXmlConfigProfileApp.java:
package com.example;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.example.dao.CustomerDao;
import com.example.domain.Customer;

public class TestXmlConfigProfileApp {
 public static void main(String[] args) {
  System.setProperty("spring.profiles.active", "prod");
  ConfigurableApplicationContext context = new ClassPathXmlApplicationContext(
    "spring-config.xml");
  CustomerDao custDao = (CustomerDao) context.getBean("custdao");
  Customer jack = custDao.findCustomerById("123456789101");
  System.out.println(jack);
  Customer kate = custDao.findCustomerById("109876543210");
  System.out.println(kate);
  context.close();
 }
}

Uygulamayı "prod" profilinde çalıştırdığımızda oluşan ekran görüntüsü aşağıda verilmiştir:
Feb 09, 2014 3:10:12 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2ef7d41f: startup date [Sun Feb 09 03:10:12 EET 2014]; root of context hierarchy
Feb 09, 2014 3:10:12 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
Feb 09, 2014 3:10:13 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@49ea903c: defining beans [customerSrv,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,custdao,jdbcTemplate,dataSource,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
Customer [firstName=Jin, lastName=Kwon, identityNo=123456789101]
Customer [firstName=Sun, lastName=Kwon, identityNo=109876543210]
Feb 09, 2014 3:10:13 AM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@2ef7d41f: startup date [Sun Feb 09 03:10:12 EET 2014]; root of context hierarchy
Feb 09, 2014 3:10:13 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@49ea903c: defining beans [customerSrv,org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,custdao,jdbcTemplate,dataSource,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy

Uygulamayı "dev" profilinde çalıştırdığımızda oluşan ekran görüntüsü aşağıda verilmiştir:
Feb 09, 2014 3:14:41 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2ef7d41f: startup date [Sun Feb 09 03:14:40 EET 2014]; root of context hierarchy
Feb 09, 2014 3:14:41 AM org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
INFO: Loading XML bean definitions from class path resource [spring-config.xml]
Feb 09, 2014 3:14:41 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6cf49909: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,customerSrv,custdao,123456789101,109876543210,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy
Customer [firstName=Jack, lastName=Shephard, identityNo=123456789101]
Customer [firstName=Kate, lastName=Austen, identityNo=109876543210]
Feb 09, 2014 3:14:42 AM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.support.ClassPathXmlApplicationContext@2ef7d41f: startup date [Sun Feb 09 03:14:40 EET 2014]; root of context hierarchy
Feb 09, 2014 3:14:42 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6cf49909: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,customerSrv,custdao,123456789101,109876543210,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor]; root of factory hierarchy

2. @Profile damgasını kullanarak Java tabanlı profil tanımlama

com.example.AppConfig.java:
package com.example.config;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Profile;

@Configuration
@Profile({"prod","dev"})
@Import(value = { AppConfigDev.class, AppConfigProd.class })
public class AppConfig {
}

com.example.config.AppConfigDev.java:
package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import com.example.domain.Customer;

@Configuration
@Profile("dev")
@ComponentScan({ "com.example.service", "com.example.dao" })
public class AppConfigDev {
 @Bean(name = "123456789101")
 public Customer customer1() {
  Customer cust = new Customer();
  cust.setFirstName("Jack");
  cust.setLastName("Shephard");
  cust.setIdentityNo("123456789101");
  return cust;
 }

 @Bean(name = "109876543210")
 public Customer customer2() {
  Customer cust = new Customer();
  cust.setFirstName("Kate");
  cust.setLastName("Austen");
  cust.setIdentityNo("109876543210");
  return cust;
 }
}

com.example.config.AppConfigProd.java:
package com.example.config;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.core.JdbcTemplate;

@Configuration
@Profile("prod")
@ComponentScan({ "com.example.service", "com.example.dao" })
public class AppConfigProd {
 @Bean
 public JdbcTemplate jdbcTemplate() {
  BasicDataSource dataSource = new BasicDataSource();
  dataSource.setDriverClassName("com.mysql.jdbc.Driver");
  dataSource.setUrl("jdbc:mysql://localhost:3306/customerdb");
  dataSource.setUsername("root");
  dataSource.setPassword("root");
  return new JdbcTemplate(dataSource);
 }
}

com.example.TestAppConfig.java:
package com.example;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import com.example.config.AppConfig;
import com.example.dao.CustomerDao;
import com.example.domain.Customer;

public class TestAppConfig {

 public static void main(String[] args) {
  ConfigurableApplicationContext context = new AnnotationConfigApplicationContext();
  context.getEnvironment().setActiveProfiles("prod");
  ((AnnotationConfigApplicationContext) context)
    .register(AppConfig.class);
  context.refresh();
  CustomerDao custDao = (CustomerDao) context.getBean("custdao");
  Customer jack = custDao.findCustomerById("123456789101");
  System.out.println(jack);
  Customer kate = custDao.findCustomerById("109876543210");
  System.out.println(kate);
  context.close();
 }
}

Uygulamayı "dev" profilinde çalıştırdığımızda oluşan ekran görüntüsü aşağıda verilmiştir:
Feb 09, 2014 3:47:57 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@8bfaf9f: startup date [Sun Feb 09 03:47:57 EET 2014]; root of context hierarchy
Feb 09, 2014 3:47:58 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3843d287: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,appConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,customerSrv,custdao,com.example.config.AppConfigDev,109876543210,123456789101]; root of factory hierarchy
Customer [firstName=Jack, lastName=Shephard, identityNo=123456789101]
Customer [firstName=Kate, lastName=Austen, identityNo=109876543210]
Feb 09, 2014 3:47:58 AM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@8bfaf9f: startup date [Sun Feb 09 03:47:57 EET 2014]; root of context hierarchy
Feb 09, 2014 3:47:58 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3843d287: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,appConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,customerSrv,custdao,com.example.config.AppConfigDev,109876543210,123456789101]; root of factory hierarchy

Uygulamayı "prod" profilinde çalıştırdığımızda oluşan ekran görüntüsü aşağıda verilmiştir:
Feb 09, 2014 3:50:05 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@60a2f435: startup date [Sun Feb 09 03:50:05 EET 2014]; root of context hierarchy
Feb 09, 2014 3:50:06 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6cb2b9ec: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,appConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,customerSrv,custdao,com.example.config.AppConfigProd,jdbcTemplate]; root of factory hierarchy
Customer [firstName=Jin, lastName=Kwon, identityNo=123456789101]
Customer [firstName=Sun, lastName=Kwon, identityNo=109876543210]
Feb 09, 2014 3:50:07 AM org.springframework.context.support.AbstractApplicationContext doClose
INFO: Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@60a2f435: startup date [Sun Feb 09 03:50:05 EET 2014]; root of context hierarchy
Feb 09, 2014 3:50:07 AM org.springframework.beans.factory.support.DefaultSingletonBeanRegistry destroySingletons
INFO: Destroying singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@6cb2b9ec: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,appConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,customerSrv,custdao,com.example.config.AppConfigProd,jdbcTemplate]; root of factory hierarchy

Projeyi maven projesi olarak bu adresten indirebilirsiniz.

Saturday, February 8, 2014

Spring çatısında properties dosyası kullanımı

Spring çatısı, uygulama geliştirirken karşılaştığımız iki temel problem için çözüm sunmaktadır:

  • Hizmet alan ve hizmet veren sınıflar arasında Java arayüzü (=interface) aracılığı ile tanımlanan bağımlılıkların yürütme zamanında çözülmesi
  • Yazılımın yapılandırılmasında kullanılan parametrelerin, kodun dışına çıkarılması. Böylelikle, bu parametrelerin, kodun yeniden derlenmesi gerekmeksizin değiştirilebilmesini sağlamak. 
Uygulamanın değişmesi olası parametrelerini ya XML tabanlı Spring yapılandırma dosyasına ya da anahtar-değer ikilisi olarak tanımlanan Java properties dosyasına taşıyoruz. Spring çatısında Java properties dosyasını kullanmanın değişik yöntemleri bulunmaktadır. Şimdi bu yöntemlere sırayla bakalım.

1. XML tabanlı Spring yapılandırma dosyası kullanmak:

 com.example.SimpleService.java:
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.example.service;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

@Service()
public class SimpleService {
 @Value("${user}")
 private String username;
 @Value("${password}")
 private String password;

 public SimpleService() {
 }

 public String getUsername() {
  return username;
 }

 public String getPassword() {
  return password;
 }

 public void setUsername(String username) {
  this.username = username;
 }

 public void setPassword(String password) {
  this.password = password;
 }

}

spring-config.xml:
1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
    <context:annotation-config/>
 <context:property-placeholder location="classpath*:resources/config.properties" />
 <context:component-scan base-package="com.example.service"/>
</beans>

resources/config.properties:
1
2
user=root
password=secret

com.example.TestProperties.java:
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
package com.example.service;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestProperties {
 public static void main(String[] args) {
  ConfigurableApplicationContext context= new ClassPathXmlApplicationContext("spring-config.xml");
  SimpleService srv= context.getBean(SimpleService.class);
  System.out.println(srv.getUsername());
  System.out.println(srv.getPassword());
 }
}

Uygulamayı çalıştırdığımızda aşağıdaki çıktıyı elde ediyoruz:
1
2
3
4
5
6
Feb 08, 2014 7:34:07 AM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@22a92801: startup date [Sat Feb 08 07:34:07 EET 2014]; root of context hierarchy
Feb 08, 2014 7:34:07 AM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@15a7f14f: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,appConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,simpleService,placeHolderConfigurer]; root of factory hierarchy
root
secret

2. Spring damgalarını kullanarak salt Java sınıfları ile yapılandırma

com.example.config.AppConfig.java:
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
package com.example.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;

@Configuration
@PropertySource(value = "classpath:resources/config.properties")
@ComponentScan(value = { "com.example.service" })
public class AppConfig {
 @Bean
 public static PropertySourcesPlaceholderConfigurer placeHolderConfigurer() {
  return new PropertySourcesPlaceholderConfigurer();
 }
}

com.example.TestConfigProperties.java:
1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
package com.example.service;

import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

import com.example.config.AppConfig;

public class TestConfigProperties {
 public static void main(String[] args) {
  ConfigurableApplicationContext context= new AnnotationConfigApplicationContext(AppConfig.class);
  SimpleService srv= context.getBean(SimpleService.class);
  System.out.println(srv.getUsername());
  System.out.println(srv.getPassword());
 }
}

Uygulamayı çalıştırdığımızda aşağıdaki çıktıyı elde ediyoruz:
1
2
3
4
5
6
Feb 08, 2014 11:20:40 PM org.springframework.context.support.AbstractApplicationContext prepareRefresh
INFO: Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@16030e71: startup date [Sat Feb 08 23:20:40 EET 2014]; root of context hierarchy
Feb 08, 2014 11:20:41 PM org.springframework.beans.factory.support.DefaultListableBeanFactory preInstantiateSingletons
INFO: Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@15a7f14f: defining beans [org.springframework.context.annotation.internalConfigurationAnnotationProcessor,org.springframework.context.annotation.internalAutowiredAnnotationProcessor,org.springframework.context.annotation.internalRequiredAnnotationProcessor,org.springframework.context.annotation.internalCommonAnnotationProcessor,appConfig,org.springframework.context.annotation.ConfigurationClassPostProcessor.importAwareProcessor,simpleService,placeHolderConfigurer]; root of factory hierarchy
root
secret

Monday, November 18, 2013

PL/SQL'de "table of index by" Kullanımı

PL/SQL'de şehirlere göre telefon alan kodlarını saklamak için en uygun veri tipi  table of kullanmak olacaktır:

type t_alan_kodu is table of integer index by varchar2(64);
v_tel_kodu t_alan_kodu;

Daha sonra v_tel_kodu değişkenine tüm illerin alan kodlarını anahtar-değer ikililerini aşağıdaki gibi yerleştirmek gerekir:

v_tel_kodu('ADANA') := 322;
v_tel_kodu('K.MARAŞ') := 344;
v_tel_kodu('ADIYAMAN') := 416; 
v_tel_kodu('KOCAELİ') := 262;
v_tel_kodu('AFYON') := 272;
v_tel_kodu('KONYA') := 332;
v_tel_kodu('AĞRI') := 472; 
v_tel_kodu('KÜTAHYA') := 274;
v_tel_kodu('AKSARAY') := 382;  
v_tel_kodu('MALATYA') := 422;
v_tel_kodu('AMASYA') := 358;
v_tel_kodu('MANİSA') := 236;
v_tel_kodu('ANKARA') := 312;
v_tel_kodu('MARDİN') := 482;
v_tel_kodu('ANTALYA') := 242;  
v_tel_kodu('MUĞLA') := 252;
v_tel_kodu('ARDAHAN') := 478;  
v_tel_kodu('MUŞ') := 436;
v_tel_kodu('ARTVİN') := 466;
v_tel_kodu('NEVŞEHİR') := 384;
v_tel_kodu('AYDIN') := 256;
v_tel_kodu('NİĞDE') := 388;
v_tel_kodu('BALIKESİR') := 266;
v_tel_kodu('ORDU') := 452;
v_tel_kodu('BARTIN') := 378;
v_tel_kodu('OSMANİYE') := 328;
v_tel_kodu('BATMAN') := 488;
v_tel_kodu('RİZE') := 464;
v_tel_kodu('BAYBURT') := 458;  
v_tel_kodu('SAKARYA') := 264;
v_tel_kodu('BİLECİK') := 228;  
v_tel_kodu('SAMSUN') := 362;
v_tel_kodu('BİNGÖL') := 426;
v_tel_kodu('SİİRT') := 484;
v_tel_kodu('BİTLİS') := 434;
v_tel_kodu('SİNOP') := 368;
v_tel_kodu('BOLU') := 374; 
v_tel_kodu('SİVAS') := 346;
v_tel_kodu('BURDUR') := 248;
v_tel_kodu('ŞANLIURFA') := 414;
v_tel_kodu('BURSA') := 224;
v_tel_kodu('ŞIRNAK') := 486;
v_tel_kodu('ÇANAKKALE') := 286;
v_tel_kodu('TEKİRDAĞ') := 282;
v_tel_kodu('ÇANKIRI') := 376;  
v_tel_kodu('TOKAT') := 356;
v_tel_kodu('ÇORUM') := 364;
v_tel_kodu('TRABZON') := 462;
v_tel_kodu('DENİZLİ') := 258;  
v_tel_kodu('TUNCELİ') := 428;
v_tel_kodu('DİYARBAKIR') := 412;  
v_tel_kodu('UŞAK') := 276;
v_tel_kodu('DÜZCE') := 380;
v_tel_kodu('VAN') := 432;
v_tel_kodu('EDİRNE') := 284;
v_tel_kodu('YALOVA') := 226;
v_tel_kodu('ELAZIĞ') := 424;
v_tel_kodu('YOZGAT') := 354;
v_tel_kodu('ERZİNCAN') := 446; 
v_tel_kodu('ZONGULDAK') := 372;
v_tel_kodu('ERZURUM') := 442;  
v_tel_kodu('ESKİŞEHİR') := 222;  
v_tel_kodu('GAZİANTEP') := 342;
v_tel_kodu('GİRESUN') := 454;  
v_tel_kodu('GÜMÜŞHANE') := 456;
v_tel_kodu('HAKKARİ') := 438;  
v_tel_kodu('HATAY') := 326;
v_tel_kodu('IĞDIR') := 476;
v_tel_kodu('ISPARTA') := 246;  
v_tel_kodu('İÇEL') := 324;   
v_tel_kodu('İSTANBUL-AVRUPA') := 212;
v_tel_kodu('İSTANBUL-ANADOLU') := 216;
v_tel_kodu('İZMİR') := 232;  
v_tel_kodu('KARABÜK') := 370;
v_tel_kodu('KARAMAN') := 338;
v_tel_kodu('KARS') := 474;
v_tel_kodu('KASTAMONU') := 366;
v_tel_kodu('KAYSERİ  ') := 352;
v_tel_kodu('KIRIKKALE') := 318;  
v_tel_kodu('KIRKLARELİ') := 288;
v_tel_kodu('KIRŞEHİR') := 386;   
v_tel_kodu('KİLİS') := 348;


İllere göre tüm alan kodları listelenmek istenirsek aşağıdaki kod kullanılabilir:


v_city := v_tel_kodu.first;
for i in 1..v_tel_kodu.count loop
    dbms_output.put_line(v_city || ': ' || v_tel_kodu(v_city));
    v_city := v_tel_kodu.next(v_city);
end loop;

Tuesday, November 12, 2013

PL/SQL'de Sayısal Loto Oynamak

PL/SQL'de sayısal loto için 1-49 aralığında biri birinden farklı 6 rakam çeken ve sıralı olarak konsola yazan kodu aşağıda bulabilirsiniz:
1:  SET serveroutput ON  
2:  DECLARE  
3:  type t_lottery  
4:  IS  
5:   TABLE OF binary_integer;  
6:   v_numbers t_lottery := t_lottery(50,50,50,50,50,50);  
7:   v_candidate binary_integer;  
8:  BEGIN  
9:   FOR i IN 1..6  
10:   LOOP  
11:    DECLARE  
12:     v_found BOOLEAN := false ;  
13:    BEGIN  
14:     LOOP  
15:      v_candidate := ROUND(dbms_random.value(1,49),0);  
16:      v_found := false;  
17:      FOR n IN 1..i  
18:      LOOP  
19:       IF (v_numbers(n)=v_candidate) THEN  
20:        v_found := true ;  
21:       END IF;  
22:      END LOOP;  
23:      EXIT  
24:     WHEN NOT v_found;  
25:     END LOOP;  
26:    END;  
27:    DECLARE  
28:     v_temp v_candidate%type;  
29:    BEGIN  
30:     FOR j IN 1..i  
31:     LOOP  
32:      IF v_numbers(j) > v_candidate THEN  
33:       v_temp := v_candidate;  
34:       v_candidate := v_numbers(j);  
35:       v_numbers(j) := v_temp;  
36:      END IF;  
37:     END LOOP;  
38:    END;  
39:   END LOOP;  
40:   FOR i IN v_numbers.first..v_numbers.last  
41:   LOOP  
42:    dbms_output.put(v_numbers(i) || ' ');  
43:   END LOOP;  
44:   dbms_output.new_line;  
45:  END;  

Örnek konsol çıktıları aşağıda verilmiştir:

anonymous block completed
12 19 29 35 38 43

anonymous block completed
15 19 22 27 39 44

anonymous block completed
17 19 21 26 30 39

anonymous block completed
9 12 25 31 32 44

anonymous block completed
19 21 27 38 44 47