JDK 8+和Java EE7+以上版本
-
整个框架的代码基于java8
-
通过使用泛型等特性提高可读性
-
对java8提高直接的代码支撑
-
运行时兼容JDK9
-
Java EE 7API需要Spring相关的模块支持
-
运行时兼容Java EE8 API
-
取消的包,类和方法
-
包 beans.factory.access
-
包 dbc.support.nativejdbc
-
从spring-aspects 模块移除了包mock.staicmock,不在提AnnotationDrivenStaticEntityMockingControl支持
-
许多不建议使用的类和方法在代码库中删除
核心特性
JDK8的增强:
-
访问Resuouce时提供getFile或和isFile防御式抽象
-
有效的方法参数访问基于java 8反射增强
-
在Spring核心接口中增加了声明default方法的支持一贯使用JDK7 Charset和StandardCharsets的增强
-
兼容JDK9
-
Spring 5.0框架自带了通用的日志封装
-
持续实例化via构造函数(修改了异常处理)
-
Spring 5.0框架自带了通用的日志封装
-
spring-jcl替代了通用的日志,仍然支持可重写
-
自动检测log4j 2.x, SLF4J, JUL(java.util.Logging)而不是其他的支持
-
访问Resuouce时提供getFile或和isFile防御式抽象
-
基于NIO的readableChannel也提供了这个新特性
核心容器
-
支持候选组件索引(也可以支持环境变量扫描)
-
支持@Nullable注解
-
函数式风格GenericApplicationContext/AnnotationConfigApplicationContext
-
基本支持bean API注册
-
在接口层面使用CGLIB动态代理的时候,提供事物,缓存,异步注解检测
-
XML配置作用域流式
-
Spring WebMVC
-
全部的Servlet 3.1 签名支持在Spring-provied Filter实现
-
在Spring MVC Controller方法里支持Servlet4.0 PushBuilder参数
-
多个不可变对象的数据绑定(Kotlin/Lombok/@ConstructorPorties)
-
支持jackson2.9
-
支持JSON绑定API
-
支持protobuf3
-
支持Reactor3.1 Flux和Mono
整合日志框架
spring5整合log4j2日志工具
首先我们还是用事务管理中创建的项目,也就是转账的例子给它增加记录日志的功能。
第一步,引入相关依赖
<!-- log4j2日志相关jar包引用-->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.30</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.11.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.11.2</version>
</dependency>
<!--用于slf4j与log4j2保持桥接 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.11.2</version>
</dependency>
第二步,创建log4j2.xml配置文件
<?xml version="1.0" encoding="UTF-8"?>
<!--
日志输出级别,共有8个级别,按照从低到高为:All < Trace < Debug < Info < Warn < Error < Fatal < OFF.
-->
<Configuration status="warn">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="Console"/>
</Root>
</Loggers>
</Configuration>
第三步,创建Logger对象,输入日志信息。
package org.learn.spring5.service.impl;
import org.learn.spring5.dao.UserDao;
import org.learn.spring5.service.UserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserServiceImpl implements UserService {
private static final Logger log= LoggerFactory.getLogger(UserServiceImpl.class);
@Autowired
private UserDao userDao;
public void transferAccount() {
log.info("执行了 transferAccount 方法");
//小明转账100,减少100元
userDao.reduceMoney();
int i = 10/0;
//小红账户增加100元
userDao.addMoney();
}
}
执行测试程序
import org.junit.Test;
import org.learn.spring5.service.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpring5 {
/**
* Spring5整合log4j2
*/
@Test
public void testAccount() {
ApplicationContext context = new ClassPathXmlApplicationContext("bean1.xml");
UserService userService = context.getBean("userServiceImpl", UserService.class);
userService.transferAccount();//转账操作
}
}
返回结果
19:05:51.899 [main] INFO com.alibaba.druid.pool.DruidDataSource - {dataSource-1} inited
19:05:52.254 [main] INFO org.learn.spring5.service.impl.UserServiceImpl - 执行了 transferAccount 方法
结果表明,我们的日志信息按照log4j2配置文件设置的格式成功输出,log4j2框架整合成功。
Nullable注解和函数式风格编程
@NonNull
使用在字段,方法参数或方法的返回值。表示不能为空
@NonNullFields
使用在包级别,并且是该包下类的字段不能为空。
当一个类中的字段使用了太多的NonNull时可以考虑使用@NonNullFields注解,使用该注解必须先定义一个名为package-info.java
的文件,例如:
package-info.java
@NonNullApi
@NonNullFields
package org.springframework.mail;
import org.springframework.lang.NonNullApi;
import org.springframework.lang.NonNullFields;
@Nullable
使用在字段,方法参数或方法的返回值。表示可以为空。
当一个类的包被@NonNullFields
或@NonNullApi
注解,而我们想要从包级别指定的非null约束中免除某些字段,方法,返回值时可以使用@Nullable
@NonNullApi
和@NonNullFields
一样使用在包级别,但是区别是它作用是该包下的类的方法参数和返回值不能为空
当一个类中的方法参数和返回值使用了太多的NonNull时可以考虑使用@NonNullFields注解,使用该注解必须先定义一个名为package-info.java
的文件,形式同上。
-
函数式风格编程
函数式风格创建对象,并交给Spring进行管理
1.创建GenericApplicationContext对象
2.调用context的registerBean方法注册对象
3.获取在Srping注册的对象
@Test
public void test2() {
//1.手动实例化对象
User user = new User();
//2.创建GenericApplicationContext对象
GenericApplicationContext context = new GenericApplicationContext();
context.refresh();
//3.调用context的registerBean方法注册对象
context.registerBean("user1", User.class, () -> new User());
User bean = (User) context.getBean("user1");
System.out.println(bean);
}
整合JUnit5单元测试框架
第一步,引入相关依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.8.RELEASE</version>
</dependency>
<!-- junit5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
第二步,创建测试类,添加junit5注解
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.learn.spring5.service.UserService;
import org.learn.spring5.service.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit.jupiter.SpringExtension;
@ExtendWith(SpringExtension.class)
@ContextConfiguration("classpath:bean1.xml")
public class TestSpring5 {
@Autowired
private UserService userService;
/**
* Spring5整合junit5
*/
@Test
public void testAccount() {
userService.transferAccount();//转账操作
}
}