Python wechat ordering applet course video
https://edu.csdn.net/course/detail/36074
Python actual combat quantitative transaction financial management system
https://edu.csdn.net/course/detail/35475
Content of this article
- Two important concepts of Environment abstraction
- @Use of Profile
- @Use of PropertySource
Two important concepts of Environment abstraction
The Environment interface represents the interface of the current application running Environment. Model two key aspects of the application Environment: profiles and properties. Methods related to property access are exposed through the PropertyResolver super interface. The configuration of Environment objects must be completed through the ConfigurableEnvironment interface, which is returned from all AbstractApplicationContext subclasses getEnvironment() method
Environment and configuration files
A configuration file is a named, logical group of bean definitions that are registered with the container only when a given configuration file is active. Beans can be assigned to configuration files, whether defined in XML or through annotation @ Profile; The role of the environment objects associated with profiles is to determine which profiles (if any) are currently active and which profiles (if any) should be active by default.
Environment and attributes
Attributes play an important role in almost all applications and can be derived from a variety of sources: attribute files, JVM system attributes, system environment variables, JNDI, servlet context parameters, attribute objects, map s, etc. The function of environment objects related to attributes is to provide users with a convenient service interface for configuring attribute sources and parsing attributes from them.
Beans managed in ApplicationContext can be registered as EnvironmentAware or @ Inject Environment to directly query the configuration file status or resolve properties. However, in most cases, application level beans do not need to interact directly with the Environment. Instead, they may have to replace the ${...} property value with a property placeholder configurator, such as PropertySourcesPlaceholderConfigurer, which itself is EnvironmentAware and is registered by default when using context: Property placeholder from Spring 3.1, Or register in the container through Java beans.
For the analysis of propertysources placeholderconfigurer, you can read the previous article: Spring series 14: extension point of IoC container
Interface source code overview
Interface inheritance relationship
The interface source code is as follows, which provides the interface methods related to the configuration file, and its inherited PropertyResolver provides the interface related to properties.
public interface Environment extends PropertyResolver { // List of currently active profiles // Set the system property value spring profiles. Active = XXX to activate // Or call ConfigurableEnvironment#setActiveProfiles(String...) activation String[] getActiveProfiles(); // When the active profile is not explicitly set, the default profile set returns to the active state. String[] getDefaultProfiles(); // Returns whether the activity profile matches the given Profiles boolean acceptsProfiles(Profiles profiles); }
PropertyResolver is an interface that resolves properties for any underlying source. The main interface methods are as follows. A very important implementation class is PropertySourcesPlaceholderConfigurer.
public interface PropertyResolver { // Include attributes boolean containsProperty(String key); // Get property value String getProperty(String key); // Get attribute value with default value String getProperty(String key, String defaultValue); // Get property value T getProperty(String key, Class targetType); // Get attribute value with default value T getProperty(String key, Class targetType, T defaultValue); // Get property value String getRequiredProperty(String key) throws IllegalStateException; // Get property value T getRequiredProperty(String key, Class targetType) throws IllegalStateException; // Parse ${...} in the given text placeholder String resolvePlaceholders(String text); // Parse ${...} in the given text placeholder String resolveRequiredPlaceholders(String text) throws IllegalArgumentException; }
ConfigurablePropertyResolver is the configuration interface that most PropertyResolver types will implement. Provides tools for accessing and customizing the ConversionService used when converting attribute values from one type to another.
public interface ConfigurablePropertyResolver extends PropertyResolver { ConfigurableConversionService getConversionService(); void setConversionService(ConfigurableConversionService conversionService); // How does the default "${" of placeholder prefix come from void setPlaceholderPrefix(String placeholderPrefix); // Set the placeholder suffix. How does the default "}" come from void setPlaceholderSuffix(String placeholderSuffix); // Set placeholder value separator. How does the default ":" come from void setValueSeparator(@Nullable String valueSeparator); void setIgnoreUnresolvableNestedPlaceholders(boolean ignoreUnresolvableNestedPlaceholders); void setRequiredProperties(String... requiredProperties); void validateRequiredProperties() throws MissingRequiredPropertiesException; }
ConfigurableEnvironment is the configuration interface that most environment types will implement. Provides tools for setting up activity and default profiles and operating the underlying property sources. The client is allowed to set and verify the required properties, custom transformation services, etc. through the ConfigurablePropertyResolver super interface.
public interface ConfigurableEnvironment extends Environment, ConfigurablePropertyResolver { void setActiveProfiles(String... profiles); void addActiveProfile(String profile); void setDefaultProfiles(String... profiles); MutablePropertySources getPropertySources(); // Key system properties () Map getSystemProperties(); // Critical system environment System#getenv() Map getSystemEnvironment(); void merge(ConfigurableEnvironment parent); }
@Use of Profile
@Profile indicates that a component is eligible to register when one or more profiles are active. You can set one or more active profiles in the following ways:
- Programming method: ConfigurableEnvironment#setActiveProfiles(String...)
- Startup parameters: - dspring profiles. active=“profile1,profile2”
- xml configuration method:
Use case
Let's look at a practical scenario: different environments require different types of data sources to be injected into the container. The dev environment uses H2, the production environment prod uses Mysql, and the default environment uses HSQL.
Define data sources in different environments and identify @ Profile
@Configuration @ComponentScan public class AppConfig { // Test environment data source H2 @Profile("dev") @Bean public DataSource devDataSource() { DataSource dataSource = new DataSource(); dataSource.setType("H2"); dataSource.setUrl("jdbc:h2:xxxxxx"); return dataSource; } // Production environment data source mysql @Profile("prod") @Bean public DataSource prodDataSource() { DataSource dataSource = new DataSource(); dataSource.setType("mysql"); dataSource.setUrl("jdbc:mysql:xxxxxx"); return dataSource; } // HSQL for default environment @Profile("default") @Bean public DataSource defaultDataSource() { DataSource dataSource = new DataSource(); dataSource.setType("HSQL"); dataSource.setUrl("jdbc:HSQL:xxxxxx"); return dataSource; } }
To test the program, first do not specify the profile
@org.junit.Test public void test\_profile() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(); // context.getEnvironment().setActiveProfiles("prod"); context.register(AppConfig.class); context.refresh(); DataSource dataSource = context.getBean(DataSource.class); System.out.println(dataSource.getType()); context.close(); } // Output results HSQL
The results show that the HSQL corresponding to the default environment registered in the container
Specify profile as prod and observe the output
context.getEnvironment().setActiveProfiles("prod") // result mysql
From the results, we can see that the mysql corresponding to the prod environment registered in the container.
Support logical operators
Support and or non operation combination
- !
- &
- |
Combination & and | must use parentheses
Counterexample: Production & US East | EU Central
Positive example: Production & (US East | EU central)
Use @ Profile to customize composite annotations
Define combined annotation
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Profile("production") public @interface Production { }
use
@Configuration @Production public class MyConfiguration { }
If the @ Configuration class is marked with @ Profile, all @ Bean methods and @ Import annotations associated with the class will be bypassed unless one or more specified profiles are active.
Specify a profile using xml
The of the profile element in the tag can specify the profile.
xml version="1.0" encoding="UTF-8"? <beans profile="prod" xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean class="com.crab.spring.ioc.demo13.DataSource" id="dataSource"> <property name="type" value="mysql"/> <property name="url" value="jdbc:mysql/xxxxx"/> bean> beans>
PropertySource abstraction
Spring's Environment abstraction provides search operations on a configurable attribute source hierarchy. Let's see how the case obtains properties from the spring container.
@org.junit.Test public void test\_property\_source() { ApplicationContext ctx = new GenericApplicationContext(); Environment env = ctx.getEnvironment(); boolean containsMyProperty = env.containsProperty("my-property"); System.out.println("Does my environment contain the 'my-property' property? " + containsMyProperty); }
PropertySource is a simple abstraction of any key value pair source. Spring's StandardEnvironment is configured with two PropertySource objects:
- One represents a set of JVM system properties (System.getProperties())
- One represents a set of system environment variables (System.getenv())
public class StandardEnvironment extends AbstractEnvironment { /** System environment property source name: {@value}. */ public static final String SYSTEM\_ENVIRONMENT\_PROPERTY\_SOURCE\_NAME = "systemEnvironment"; /** JVM system properties property source name: {@value}. */ public static final String SYSTEM\_PROPERTIES\_PROPERTY\_SOURCE\_NAME = "systemProperties"; // Customize a set of attribute sources suitable for any standard @Override protected void customizePropertySources(MutablePropertySources propertySources) { propertySources.addLast( new PropertiesPropertySource(SYSTEM_PROPERTIES_PROPERTY_SOURCE_NAME, getSystemProperties())); propertySources.addLast( new SystemEnvironmentPropertySource(SYSTEM_ENVIRONMENT_PROPERTY_SOURCE_NAME, getSystemEnvironment())); } }
The order of priority for finding whether an attribute exists in the attribute source is as follows, from high to low:
- ServletConfig parameters (web context)
- ServletContext parameters (web.xml context-param entries)
- JNDI environment variables (java:comp/env/ entries)
- JVM system properties (-D command-line arguments)
- JVM system environment (operating system environment variables)
Custom PropertySource
Custom MyPropertySource implementation Property provides a Property source based on the Map Property key value pair
/** * Custom PropertySource * @author zfd * @version v1.0 * @date 2022/1/22 22:13 * @For me, please pay attention to the official account of crab Java notes for more technical series. */ public class MyPropertySource extends PropertySource> { public MyPropertySource(String name, Map source) { super(name, source); } public MyPropertySource(String name) { super(name); } @Override public Object getProperty(String name) { return this.source.get(name); } }
Add to the Spring container environment with the highest priority
@org.junit.Test public void test\_custom\_property\_source() { ConfigurableApplicationContext ctx = new GenericApplicationContext(); MutablePropertySources sources = ctx.getEnvironment().getPropertySources(); Map map = new HashMap<>(); map.put("my-property", "xxx"); sources.addFirst(new MyPropertySource("myPropertySource",map)); // true boolean containsMyProperty = ctx.getEnvironment().containsProperty("my-property"); System.out.println("Does my environment contain the 'my-property' property? " + containsMyProperty); }
@PropertySource usage
Compared with the above programmatic addition of PropertySource, the @ PropertySource annotation provides a convenient and declarative mechanism for adding PropertySource to the Spring environment. Look directly at the case.
app.properties configuration
testBean.name=xxx
Configuration class
@Configuration // Injection profile @PropertySource("classpath:demo13/app.properties") public class AppConfig3 { @Autowired private Environment env; @Bean public TestBean testBean() { TestBean testBean = new TestBean(); testBean.setName(env.getProperty("testBean.name")); return testBean; } }
Observation of test results
@org.junit.Test public void test\_property\_source\_annotation() { AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig3.class); TestBean testBean = context.getBean(TestBean.class); System.out.println(testBean.getName()); } // result xxx
@The configuration file specified in PropertySource can also use the placeholder ${...}. If the attribute value in the environment is my config. If the path already exists, it will be parsed. Otherwise, the default value demo13 will be used.
@Configuration // Injection profile @PropertySource("classpath:${my.config.path:demo13}/app.properties") public class AppConfig3 {}
summary
This paper introduces two important concepts of Environment abstraction in Spring: Bean definition, configuration file and attribute source. It also introduces the use of @ Profile and @ PropertySource.
Source address of this article: https://github.com/kongxubihai/pdf-spring-series/tree/main/spring-series-ioc/src/main/java/com/crab/spring/ioc/demo13
Knowledge sharing, please indicate the source of reprint. There is no order in learning, and the one who reaches is the first!