本文主要是介绍Spring6全面详解,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Spring6全面详解
自2022年11月,Spring6正式发布。在Spring6中,对于JDK的要求最低为 17+。(17 - 19)
部分文本摘抄于尚硅谷视频(bilibili)做了一定的排版和个人的理解。如果不是很熟悉,可以去看
Spring5全面详解 内容大约十万字左右, 对于Spring5的使用整理的较为全面,也都有解释部分,Spring6只是看以下是否具有一些特性上的更换。所以可能并没有Spring5的内容详细。但本篇大约在8-10万字左右。持续进行编写。
1. Spring6概述
1.1 Spring核心模块
在spring6中,Core的核心模块有以下内容
- IOC
- Container
- Events
- Resources
- i18n
- Validation
- Data Binding
- Type Conversion
- SpEL
- 10.AOP
- AOT(静态编译)
1.1.1 Spring Core
SpringCore提供了IOC,DI,Bean配置装载创建的核心实现。核心概念:Beans,BeanFactory,BeanDefinitons,ApplicationContext。
- Spring-Core(IOC和DI的基本实现)
- Spring-Beans (BeanFactory和Bean的装配管理(BeanFactory))
- Spring-Context(SpringContext上下文,即IOC容器(ApplicationContext)
- Spring-Expression (Spring表达式语言)
1.1.2 Spring Aop
- Spring-Aop 面向切面编程的应用模块,整合ASM,CGLib,JDK Proxy。
- Spring-Aspect 集成AspectJ,Aop应用框架。
- Spring-Instrument 动态Class Loading模块。
1.1.3 Spring Data Access
- Spring-JDBC 属于是Spring对Jdbc的封装,用于简化JDBC的使用方法。
- Spring-Orm 是Java对象与数据库数据映射的框架。
- Spring-Oxm 是对象与Xml文件的映射框架。
- Spring-Jms 是Spring对 Java Message Service(Java消息服务)的封装,用于服务间的相互通信。
- Spring-Tx 是Spring的事务管理。
1.1.4 Spring Web
- Spring-Web 是最基础的Web支持,建立于Spring-Context之上,通过Servlet和Listener来初始化Ioc容器。
- Spring-WebMvc 实现了Web Mvc。
- Spring-WebSocket 与前端的双工通信协议。
- Spring-WebFlux 是Spring5.0+提供的,用于取代传统是Java Servlet,非阻塞式Reactive Web框架,异步,非阻塞,事件驱动服务。
1.1.5 Spring Message
- Spring-Messaging 是Spring4.0+提供的,用于为Spring集成一些基础的报文传送服务。
1.1.6 Spring Test
- Spring-Test 对于测试的支持,主要是针对于Junit的封装。
2. Spring6体验
2.1 引入Spring相关的依赖需求
<dependencies><!-- 引入spring --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>6.0.3</version></dependency><!-- 引入Junit --><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.13.2</version><scope>test</scope></dependency><!-- 引入LomBok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.26</version></dependency></dependencies>
2.2 创建实体类和对应的XML配置文件
新建一个包,里面包含一个User实体类。 pojo -> User.java。然后User内含有以下代码。
package org.example.pojo;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;@AllArgsConstructor
@NoArgsConstructor
@Data
@ToString
public class User {private String username;private String password;private Integer age;private String phoneNumber;}
然后去创建对应的Spring配置文件。可以在Idea中快捷去创建对应的配置文件。右键resources的包,然后new —>
XML Configuration File。即可。创建完成后, 使Spring对我们的User类进行托管。
<?xml version="1.0" encoding="UTF-8"?>
<beans 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 id="user" class="org.example.pojo.User"><property name="username" value="张三" /><property name="password" value="123456" /><property name="age" value="18" /><property name="phoneNumber" value="12368965432" /></bean></beans>
在完成上述步骤后,在一个具有Main方法的类中,去进行测试。
package org.example;import org.example.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {// 通过Xml加载获取Ioc容器对象。ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");// 通过Ioc容器获取Bean对象User user = applicationContext.getBean("user", User.class);// 打印对象内容,查看内容是否对的上。[User(username=张三, password=123456, age=18, phoneNumber=12368965432)]System.out.println(user);}
}
2.3 根据全包类名通过反射创建对象
Class<?> aClass = Class.forName("org.example.pojo.User");User userClass = (User) aClass.getDeclaredConstructor().newInstance();
2.4 Spring创建好的对象放在哪里?
会放在一个Map集合里,该属性存在于 DefaultListableBeanFactory 类中。属性名称为:
private final Map<String, BeanDefinition> beanDefinitionMap;
在该Map<String, BeanDefinition> 中。
- Key 代表唯一标识
- Value 代表该类的定义(描述)
3. Log4j2日志整合
3.1 Log4j2重要组件
3.1.1 日志信息的优先级
日志日志的优先级从高到低有 TRACE < DEBUG < INFO < WARN < ERROR < FATAL
- TRACE:追踪,是日志的最低级别,相当于追踪程序的执行。
- DEBUG:调试,一般在开发中,都将其设置为最低的级别。
- INFO:信息,输出重要的信息,使用较多。
- WARN:警告,输出警告的信息。
- ERROR:错误,输出错误的信息。
- FALTAL:重大错误。
上面这些内容主要用于指定程序日志的重要程度,优先级高的日志信息会覆盖掉优先级低的日志信息,如果你在程序中使用一条INFO级别的日志信息,则DEBUG和TRACE不会显示。
3.1.2 日志信息输出的目的地
一般来说指的是,把日志输出到控制台,或者把日志输出到文件内进行本地存储。
3.1.3 日志信息输出的格式
就是决定了你输出日志的时候,日志以什么样的形式进行输出。
3.2 引入log4j2的依赖
<!-- 引入log4j2 -->
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-core</artifactId><version>2.20.0</version>
</dependency><!-- 引入log4j2的实现,slf4j2-impl -->
<dependency><groupId>org.apache.logging.log4j</groupId><artifactId>log4j-slf4j2-impl</artifactId><version>2.20.0</version>
</dependency>
3.3引入log4j2配置文件
首先固定名称为:log4j2.xml 文件必须放到类根路径下。
<?xml version="1.0" encoding="UTF-8"?>
<configuration><loggers><!--level指定日志级别,从低到高的优先级:TRACE < DEBUG < INFO < WARN < ERROR < FATALtrace:追踪,是最低的日志级别,相当于追踪程序的执行debug:调试,一般在开发中,都将其设置为最低的日志级别info:信息,输出重要的信息,使用较多warn:警告,输出警告的信息error:错误,输出错误信息fatal:严重错误--><root level="DEBUG"><appender-ref ref="spring6log"/><appender-ref ref="RollingFile"/><appender-ref ref="log"/></root></loggers><appenders><!--输出日志信息到控制台--><console name="spring6log" target="SYSTEM_OUT"><!--控制日志输出的格式--><PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss SSS} [%t] %-3level %logger{1024} - %msg%n"/></console><!--文件会打印出所有信息,这个log每次运行程序会自动清空,由append属性决定,适合临时测试用--><File name="log" fileName="d:/spring6_log/test.log" append="false"><PatternLayout pattern="%d{HH:mm:ss.SSS} %-5level %class{36} %L %M - %msg%xEx%n"/></File><!-- 这个会打印出所有的信息,每次大小超过size,则这size大小的日志会自动存入按年份-月份建立的文件夹下面并进行压缩,作为存档--><RollingFile name="RollingFile" fileName="d:/spring6_log/app.log"filePattern="log/$${date:yyyy-MM}/app-%d{MM-dd-yyyy}-%i.log.gz"><PatternLayout pattern="%d{yyyy-MM-dd 'at' HH:mm:ss z} %-5level %class{36} %L %M - %msg%xEx%n"/><SizeBasedTriggeringPolicy size="50MB"/><!-- DefaultRolloverStrategy属性如不设置,则默认为最多同一文件夹下7个文件,这里设置了20 --><DefaultRolloverStrategy max="20"/></RollingFile></appenders>
</configuration>
在配置完成后,他是自动实现的。你在重新去执行Main方法的时候,就会看到对应的日志信息。同时目录下还会生成两个.log文件。
2023-03-02 10:41:18 889 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2b72cb8a
2023-03-02 10:41:18 997 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 1 bean definitions from class path resource [applicationContext.xml]
2023-03-02 10:41:19 024 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user'
User(username=张三, password=123456, age=18, phoneNumber=12368965432)
3.4 手动使用log日志
我们可以在我们的代码中,加入Log日志的使用。需要我们定义一个成员变量。
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;private final Logger logger = LoggerFactory.getLogger(Main.class);
完整代码
package org.example;import org.example.pojo.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {private static final Logger logger = LoggerFactory.getLogger(Main.class);public static void main(String[] args) throws Exception {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");User user = applicationContext.getBean("user", User.class);System.out.println(user);logger.info("我们执行了Main方法");}
}
得到的日志结果为:
2023-03-02 10:46:07 133 [main] DEBUG org.springframework.context.support.ClassPathXmlApplicationContext - Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@490caf5f
2023-03-02 10:46:07 209 [main] DEBUG org.springframework.beans.factory.xml.XmlBeanDefinitionReader - Loaded 1 bean definitions from class path resource [applicationContext.xml]
2023-03-02 10:46:07 225 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'user'
User(username=张三, password=123456, age=18, phoneNumber=12368965432)
2023-03-02 10:46:07 263 [main] INFO org.example.Main - 我们执行了Main方法
在方法内,不止可以使用info方法,其他级别的都可以使用,有DEBUG,有ERROR等各种级别的方法供来调用。
4. IOC容器
IOC是 Inversion of Control 的简写,译为 “控制反转”,他不是一门技术,而是一种设计思想,是一个重要的面向对象编程法则,能够指导我们设计出低耦合,优良的程序。
Spring通过Ioc来控制对象之间的创建和初始化,控制对象与对象之间的依赖关系,我们从IOC容器中获取到的Java对象称为Spring Bean对象。它与使用 new 关键字创建的Java对象没有任何区别。
4.1 控制反转
- 控制反转是一种设计思想。
- 是为了减少程序的耦合度,提高扩展能力。
- 控制反转的内容将对象的创建权交给Spring Ioc来进行管理。将对象与对象之间的关系交给Ioc管理。
- 通过DI(Dependency Injection) 依赖注入实现控制反转。
4.2 依赖注入
DI(Dependency Injection) 依赖注入实现控制反转。
常见的DI注入方式主要是以下两种:
- 构造器注入
- Set方法注入
所以结论是,IOC是一种控制反转的思想,DI是对于控制反转思想的实现。
4.3 IOC容器在Spring的实现
Spring 的Ioc 容器就是IOC思想的一个落地实现。IOC内管理的内容组件称为Bean,在创建Bean之前,需要先创建IOC容器。对于IOC容器的实现,Spring提供了两种实现方式。
4.3.1 BeanFactory
该接口是针对于IOC的基本实现,但是该接口不面向开发人员,用于Spring内部开发使用。
4.3.2 ApplicationContext
BeanFactory的子接口,拥有比BeanFactory更多的特性,做了很多增强,面向开发人员,在绝大部分场景下,我们选择使用ApplicationContext,而不是使用底层的BeanFactory。
4.4 手写IOC容器(通过反射)
4.4.1 获取Class对象的三种方式
- 通过对象名称 + .class : User.class
- 通过全类名来加载类 : Class.forName(“全包类名”)
- 通过对象来获取class对象 : new User().getClass()
// 获取Class对象的多种方式
@Test
public void test01() throws ClassNotFoundException {// 第一种方式 通过对象 .classClass<User> userClass = User.class;// 第二种方式 通过forName来获取class对象Class<?> aClass = Class.forName("org.example.pojo.User");// 第三种方式,通过new对象来获取classClass<? extends User> aClass1 = new User().getClass();// 通过反射创建对象User user = userClass.getDeclaredConstructor().newInstance();System.out.println(user);}
4.4.2 通过反射获取对象的构造方法
有两种获取全部构造器的方式,分别是
- getConstructors()
- 获取该类中的所有的有参构造无参构造,但是只能获取public修饰的构造方法,private修饰的则无法访问
- getDeclaredConstructors()
- 与第一个不同且增强,可以获取到private修饰的构造方法,也可以获取到public修饰的构造方法。
代码示例
// 通过反射获取构造方法。
@Test
public void test02() throws Exception {Class<User> userClass = User.class;// 第一种获取方式(针对public修饰过的构造方法)Constructor<?>[] constructors = userClass.getConstructors();for (Constructor<?> constructor : constructors) {System.out.println("构造器名称: " + constructor.getName() + "\n参数个数: " + constructor.getParameterCount());}// 第二种获取方式(可以获取到private修饰的构造方法)Constructor<?>[] declaredConstructors = userClass.getDeclaredConstructors();for (Constructor<?> declaredConstructor : declaredConstructors) {System.out.println("构造器名称: " + declaredConstructor.getName() + "\n参数个数: " + declaredConstructor.getParameterCount());}}
这篇关于Spring6全面详解的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!