Home > Java > Java Tutorial > body text

Detailed explanation of Profile for getting started with Spring

黄舟
Release: 2017-03-07 09:54:48
Original
1871 people have browsed it

What is spring profile? Simply speaking, a profile is a set of configurations. Different profiles provide different combinations of configurations. When the program is running, you can choose which profiles to use to adapt to the environment. The following article mainly introduces the relevant information about the actual implementation of Profile in Spring. Friends in need can refer to it.

Preface

The Profile function in Spring has actually been out as early as Spring 3.1. It can be understood as what we have in the Spring container The logical group name of the defined beans. Only when these profiles are activated, the beans corresponding to the profiles will be registered in the Spring container.

When you see the keyword Profile, maybe you have never looked at it directly, or you may have some vague impressions in your mind. For example, in addition to the Profile in Springmvc here, there is also the Profile tag in maven.

From a literal meaning, Profile means profile, so under what circumstances will the profile function be used, and what is the specific meaning of profile?

For example, for the database For configuration issues, from the perspective of development, you can use the embedded database and load test data (code examples will be given later). But in the eyes of testing, a database connection pool may be equipped like this

@Bean(destroyMethod="close")
public DataSource dataSource () {
 BasicDataSource dataSource = new BasicDataSource();
 dataSource.setUrl("jdbc:h2:tcp://dbserver/~/test");
 dataSource.setDriverClassName("org.h2.Driver");
 dataSource.setUsername("sa");
 dataSource.setPassword("password");
 dataSource.setInitialSize(20);
 dataSource.setMaxActive(30);
 return dataSource; 
}
Copy after login

Of course, there are also configurations in the production environment, etc. What else can you say about this kind of configuration method that lets a hundred flowers bloom? It silently deploys corresponding configuration files for this set of environments. We have always done this without profiles.

But now with Profile, we have one more choice, a more intelligent and worry-free configuration method. Through Profile configuration, Spring can decide whether to create a bean during the running phase according to the environment. The following is an example, mainly starting from the configuration and activation of Profile beans.

Profile bean configuration

Configuration through annotation @Profile

For the above example In the first case, in the development environment we configure a data source like this

@Bean(destroyMethod = "shutdown")
public DataSource embeddedDataSource() {
 return new EmbeddedDatabaseBuilder()
 .addScript("classpath:schema.sql")
 .addScript("classpath:test-data.sql")
 .build();
 }
Copy after login

Here EmbeddedDatabaseBuilder will be used to create an embedded database, and the schema is defined in In the schema.sql file under the class file

schema.sql

create table Things (
 id identity,
 name varchar(100)
);
Copy after login

a Things table is defined here Contains two fields

In addition to the schema file, test data also needs to be loaded through test-data.sql

test-data.sql

insert into Things (name) values ('A')
Copy after login

I don’t know whether this @Bean is created in a development environment or a product environment. So we can use the annotation @Profile here to help us label this bean.

The bean profile function was introduced in Spring version 3.1, which allows you to define different beans into one or more profiles, and then when deploying the application, tell which profile to activate, the corresponding bean will be created.

For example here

@Configuration
@Profile("dev")
public class DevelopmentProfileConfig {

 @Bean(destroyMethod = "shutdown")
 public DataSource embeddedDataSource() {
 return new EmbeddedDatabaseBuilder()
 .setType(EmbeddedDatabaseType.H2)
 .addScript("classpath:schema.sql")
 .addScript("classpath:test-data.sql")
 .build();
 }
}
Copy after login

pass @Profile("dev") for the EmbedderDataSource bean Mark the bean to be created in the dev environment.

Note: 1. @Profile is loaded at the class level. If the dev profile is not activated, then all the corresponding beans in the class will not be created.

2. If the current dev environment is is activated, then beans that do not use @Profile will be created. If they are marked as other profiles such as prod, the corresponding beans will not be created

3. Starting from 3.2, @Profile can not only load classes At the level, you can also load the method. The specific code is as follows

package com.myapp;

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;

@Configuration
public class DataSourceConfig {
 
 @Bean(destroyMethod = "shutdown")
 @Profile("dev")
 public DataSource embeddedDataSource() {
 return new EmbeddedDatabaseBuilder()
 .setType(EmbeddedDatabaseType.H2)
 .addScript("classpath:schema.sql")
 .addScript("classpath:test-data.sql")
 .build();
 }

 @Bean
 @Profile("prod")
 public DataSource jndiDataSource() {
 JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
 jndiObjectFactoryBean.setJndiName("jdbc/myDS");
 jndiObjectFactoryBean.setResourceRef(true);
 jndiObjectFactoryBean.setProxyInterface(javax.sql.DataSource.class);
 return (DataSource) jndiObjectFactoryBean.getObject();
 }

}
Copy after login

Configuration through xml configuration file

In addition to simplicity The annotation method can be declared in the xml configuration file. The specific configuration is as follows

datasource-config.xml




 
 
 
 
 
 
 
 
 
 
Copy after login

Two environments and corresponding profiles are declared here.

profile activation

Although we have configured the profile, how to activate the corresponding environment. Here we need two properties spring.profile.active and spring.profile.default.

If spring.profile.active is assigned, spring.profile.default will not take effect. If spring.profie.activeIf no value is assigned, the default value set by spring.profile.default will be used. Of course, if neither is set, only those beans defined in the corresponding profile will be created.

There are many ways to set these two properties:

As the initialization parameter of DispactcherServlet

As the Web application context parameter

As a JNDI entry

As an environment variable

As a JVM system property

On the integration test class, use the @ActiveProfiles annotation to set it

For example, we are on the web The code in .xml can be declared as follows




 //为上下文设置默认的profile
 
 spring.profile.default
 dev
 

...

 
 ...
 //为Serlvet设置默认的profile
 
  spring-profiles.default
  dev
 

...
Copy after login

This way you can specify which environment needs to be started and prepare the corresponding beans.

另外对于测试,spring为什么提供了一个简单的注解可以使用@ActiveProfiles,它可以指定运行测试的时候应该要激活那个profile。比如这里的测试类DevDataSourceTest

package profiles;

import static org.junit.Assert.*;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

import javax.sql.DataSource;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.myapp.DataSourceConfig;

public class DataSourceConfigTest {

 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes=DataSourceConfig.class)
 @ActiveProfiles("dev")
 public static class DevDataSourceTest {
 @Autowired
 private DataSource dataSource;
 
 @Test
 public void shouldBeEmbeddedDatasource() {
 assertNotNull(dataSource);
 JdbcTemplate jdbc = new JdbcTemplate(dataSource);
 List results = jdbc.query("select id, name from Things", new RowMapper() {
 @Override
 public String mapRow(ResultSet rs, int rowNum) throws SQLException {
  return rs.getLong("id") + ":" + rs.getString("name");
 }
 });
 
 assertEquals(1, results.size());
 assertEquals("1:A", results.get(0));
 }
 }

 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration(classes=DataSourceConfig.class)
 @ActiveProfiles("prod")
 public static class ProductionDataSourceTest {
 @Autowired
 private DataSource dataSource;
 
 @Test
 public void shouldBeEmbeddedDatasource() {
 // should be null, because there isn't a datasource configured in JNDI
 assertNull(dataSource);
 }
 }
 
 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:datasource-config.xml")
 @ActiveProfiles("dev")
 public static class DevDataSourceTest_XMLConfig {
 @Autowired
 private DataSource dataSource;
 
 @Test
 public void shouldBeEmbeddedDatasource() {
 assertNotNull(dataSource);
 JdbcTemplate jdbc = new JdbcTemplate(dataSource);
 List results = jdbc.query("select id, name from Things", new RowMapper() {
 @Override
 public String mapRow(ResultSet rs, int rowNum) throws SQLException {
  return rs.getLong("id") + ":" + rs.getString("name");
 }
 });
 
 assertEquals(1, results.size());
 assertEquals("1:A", results.get(0));
 }
 }

 @RunWith(SpringJUnit4ClassRunner.class)
 @ContextConfiguration("classpath:datasource-config.xml")
 @ActiveProfiles("prod")
 public static class ProductionDataSourceTest_XMLConfig {
 @Autowired(required=false)
 private DataSource dataSource;
 
 @Test
 public void shouldBeEmbeddedDatasource() {
 // should be null, because there isn't a datasource configured in JNDI
 assertNull(dataSource);
 }
 }

}
Copy after login

运行shouldBeEmbeddedDatasource方法,测试通过

总结

 以上就是Spring入门实战之Profile详解的内容,更多相关内容请关注PHP中文网(m.sbmmt.com)!



Related labels:
source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!