手撕Spring5框架(十一)Spring5新特性

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();//转账操作
    }


}

猜你喜欢

转载自blog.csdn.net/java_cxrs/article/details/108632500