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.
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.
No comments:
Post a Comment