作者:sumviewbk_405 | 来源:互联网 | 2023-09-11 18:06
Spring4.1对核心部分没有很亮点的增强,主要还是一些改进和增强;本文将一一道来。1、DirectFieldAccessorSpring内部大量使用BeanWrapper进行属性取ࠆ
Spring 4.1对核心部分没有很亮点的增强,主要还是一些改进和增强;本文将一一道来。
1、DirectFieldAccessor
Spring内部大量使用BeanWrapper进行属性取值赋值(setter/getter),不过到目前为止没有简单的办法去获取对象字段值;之前都是通过ReflectionUtils获取Field然后进行操作;Spring 4.1提供了DirectFieldAccessor来完成此功能:
Java代码
-
- DirectFieldAccessor accessor = new DirectFieldAccessor(bean);
-
- accessor.setAutoGrowNestedPaths(true);
-
- accessor.setPropertyValue("bean2.name", "zhangsan");
-
- System.out.println(accessor.getPropertyValue("bean2.name"));
在Spring MVC中也可以通过如下方式给对象字段绑定数据:
Java代码
- @RequestMapping("/directField")
- public String directFieldInject(MyUser user) {
- System.out.println(user);
- return user.toString();
- }
-
- @InitBinder
- public void initBinder(DataBinder dataBinder) {
- dataBinder.initDirectFieldAccess();
- }
2、Yaml支持
YAML类似于JSON,做配置文件还是不错的,需要添加org.yaml.snakeyaml依赖。目前支持把YAML文本转换成Map和Properties:
yaml.txt
Java代码
- env:
- one:
- name: zhangsan
-
- two:
- - a: 1
- b: 2
- - c: "3"
- d: 4
- three:
yaml-override.txt
Java代码
- env:
- three: 11
配置文件
Java代码
- "yamlMap" class="org.springframework.beans.factory.config.YamlMapFactoryBean">
- "resources">
classpath:yaml.txt
classpath:yaml-override.txt
"resolutionMethod" value="FIRST_FOUND"/>
"yamlProperties" class="org.springframework.beans.factory.config.YamlPropertiesFactoryBean">
"resources">
classpath:yaml.txt
classpath:yaml-override.txt
"resolutionMethod" value="FIRST_FOUND"/>
在应用中使用:
Java代码
- @Autowired
- private ApplicationContext ctx;
-
- @Autowired
- @Qualifier("yamlProperties")
- private Properties yamlProperties;
- @Test
- public void testYmlMap() {
-
-
- System.out.println(this.yamlMap);
- Map yamlMap = ctx.getBean("yamlMap", Map.class);
-
- Map env = (Map) yamlMap.get("env");
- Map one = (Map) env.get("one");
- Assert.assertEquals("zhangsan", one.get("name"));
-
- List
- Assert.assertEquals(1, two.get(0).get("a"));
- Assert.assertEquals("3", two.get(1).get("c"));
-
- Assert.assertEquals(null, env.get("three"));
-
-
-
- Assert.assertEquals("zhangsan", yamlProperties.getProperty("env.one.name"));
-
- Assert.assertEquals(1, yamlProperties.get("env.two[0].a"));
- Assert.assertEquals("3", yamlProperties.getProperty("env.two[1].c"));
- Assert.assertEquals("", yamlProperties.getProperty("env.three"));
-
-
-
-
- }
该特性是从Spring Boot引入,可以直接参考其文档。
此处需要注意不能:
Java代码
- @Autowired
- @Qualifier("yamlMap")
- private Map yamlMap;
原因请参考 Map依赖注入(http://jinnianshilongnian.iteye.com/blog/1989379)。
3、SmartInitializingSingleton
所有非lazy单例Bean实例化完成后的回调方法:
Java代码
- public class MySmartInitializingSingleton implements SmartInitializingSingleton {
-
- @Override
- public void afterSingletonsInstantiated() {
- System.out.println("单例Bean实例化完成了");
- }
- }
4、Base64Utils
其会自动根据反射来决定是使用Java 8 的 java.util.Base64还是Apache Commons Codec的org.apache.commons.codec.binary.Base64。
Java代码
- @Test
- public void test() {
-
- String str = "123";
- String str2 = new String(Base64Utils.decodeFromString(Base64Utils.encodeToString(str.getBytes())));
- Assert.assertEquals(str, str2);
- }
5、SpEL编译模式
SpEL支持把解释型的SpEL转换为字节码进行编译模式下执行:
Java代码
- @Test
- public void test() {
- SpelParserConfiguration configuration =
- new SpelParserConfiguration(SpelCompilerMode.MIXED, getClass().getClassLoader());
- SpelExpressionParser parser = new SpelExpressionParser(configuration);
-
- SpelExpression expression = parser.parseRaw("new String('haha')");
- Assert.assertEquals("haha", expression.getValue());
-
-
-
- SpelCompiler spelCompiler = SpelCompiler.getCompiler(getClass().getClassLoader());
- CompiledExpression compiledExpression = spelCompiler.compile((SpelNodeImpl) expression.getAST());
- Assert.assertEquals("haha", compiledExpression.getValue(null, null));
- }
SpelCompilerMode.MIXED指定了是混合模式,其在解释型和编译型之间转换, 其编译规则是这样的:
Java代码
- private void checkCompile(ExpressionState expressionState) {
- this.interpretedCount++;
- SpelCompilerMode compilerMode = expressionState.getConfiguration().getCompilerMode();
- if (compilerMode != SpelCompilerMode.OFF) {
- if (compilerMode == SpelCompilerMode.IMMEDIATE) {
- if (this.interpretedCount > 1) {
- compileExpression();
- }
- }
- else {
-
- if (this.interpretedCount > INTERPRETED_COUNT_THRESHOLD) {
- compileExpression();
- }
- }
- }
- }
默认情况下,编译模式是禁用的,想要全局开启可以通过配置classpath:spring.properties配置文件,然后SpelParserConfiguration会在类加载时读取spring.expression.compiler.mode属性来配置:
Java代码
- private static final SpelCompilerMode defaultCompilerMode;
-
- static {
- String compilerMode = SpringProperties.getProperty("spring.expression.compiler.mode");
- defaultCompilerMode = (compilerMode != null ?
- SpelCompilerMode.valueOf(compilerMode.toUpperCase()) : SpelCompilerMode.OFF);
- }
5、BackOff退避算法实现
在如连接网络的应用中,网络是不稳定的有时候会连接断开,因此为了保证断开重连接;还有如系统之间互联,相互之间发生消息,如果某个服务器因为不确定因此连接不上,也需要断开重连;则需要一定的规则;常见的规则有:
1、按照固定时间间隔重试,比如100毫秒;这种方式在网络不稳定时重连可能造成某一时间点流量同时发送,阻塞网络;或者造成发送一些无意义的请求;
2、按照指数时间间隔重试,比如刚开始100毫秒,下一次200毫秒等;比如支付宝和第三方集成时就是类似方式。
固定时间间隔重试:
Java代码
- @Test
- public void testFixedBackOff() {
- long interval = 100;
- long maxAttempts = 10;
- BackOff backOff = new FixedBackOff(interval, maxAttempts);
- BackOffExecution execution = backOff.start();
-
- for(int i = 1; i <= 10; i++) {
-
- System.out.println(execution.nextBackOff());
- }
- Assert.assertEquals(BackOffExecution.STOP, execution.nextBackOff());
- }
interval是重试间隔,maxAttempts是最大重试次数,如果重试到了maxAttempts,则execution.nextBackOff()=BackOffExecution.STOP。
指数时间间隔重试:
Java代码
- @Test
- public void testExponentialBackOff() {
- long initialInterval = 100;
- long maxInterval = 5 * 1000L;
- long maxElapsedTime = 50 * 1000L;
- double multiplier = 1.5;
- ExponentialBackOff backOff = new ExponentialBackOff(initialInterval, multiplier);
- backOff.setMaxInterval(maxInterval);
-
- backOff.setMaxElapsedTime(maxElapsedTime);
-
- BackOffExecution execution = backOff.start();
-
- for(int i = 1; i <= 18; i++) {
- System.out.println(execution.nextBackOff());
- }
- Assert.assertEquals(BackOffExecution.STOP, execution.nextBackOff());
- }
initialInterval是初始重试间隔,maxInterval是最大的重试间隔, multiplier是递增倍数,maxElapsedTime是重试的最大时长。
Spring4新特性
Spring4新特性——泛型限定式依赖注入
Spring4新特性——核心容器的其他改进
Spring4新特性——Web开发的增强
Spring4新特性——集成Bean Validation 1.1(JSR-349)到SpringMVC
Spring4新特性——Groovy Bean定义DSL
Spring4新特性——更好的Java泛型操作API
Spring4新特性——JSR310日期API的支持
Spring4新特性——注解、脚本、任务、MVC等其他特性改进
源码下载
https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-others
https://github.com/zhangkaitao/spring4-1-showcase/tree/master/spring4.1-mvc