【Spring 6】- 1 - Spring入门

【Spring 6 笔记】 - 1 - Spring入门

阅读以下代码:

UserController:

public class UserController {

    private UserService userService = new UserServiceImpl();

    public void login(){
        String username = "admin";
        String password = "123456";
        boolean success = userService.login(username, password);
        if (success) {
            // 登录成功
        } else {
            // 登录失败
        }
    }
}

UserDaoImplForMySQL:

public class UserDaoImplForMySQL implements UserDao {
    public User selectByUsernameAndPassword(String username, String password) {
        // 连接MySQL数据库,根据用户名和密码查询用户信息
        return null;
    }
}

可以看出,UserDaoImplForMySQL中主要是连接MySQL数据库进行操作。如果更换到Oracle数据库上,则需要再提供一个UserDaoImplForOracle,如下:

UserDaoImplForOracle:

public class UserDaoImplForOracle implements UserDao {
    public User selectByUsernameAndPassword(String username, String password) {
        // 连接Oracle数据库,根据用户名和密码查询用户信息
        return null;
    }
}

很明显,以上的操作正在进行功能的扩展,添加了一个新的类UserDaoImplForOracle来应付数据库的变化,这里的变化会引起连锁反应吗?当然会,如果想要切换到Oracle数据库上,UserServiceImpl类代码就需要修改,如下:
UserServiceImpl:

public class UserServiceImpl implements UserService {

    //private UserDao userDao = new UserDaoImplForMySQL();
    private UserDao userDao = new UserDaoImplForOracle();

    public boolean login(String username, String password) {
        User user = userDao.selectByUsernameAndPassword(username, password);
        if (user != null) {
            return true;
        }
        return false;
    }
}

这样一来就违背了开闭原则OCP。

1、OCP开闭原则

什么是OCP?

OCP是软件七大开发原则当中最基本的一个原则:开闭原则

对扩展开放。

对修改关闭。

OCP原则是最核心的,最基本的。其他的六个原则都是为这个原则服务的。

完整的 七大软件设计原则


1. SRP:单一职责原则(Single Responsibility Principle)

一个类应该只有一个引起它变化的原因。
即:一个类只负责一项职责。


2. OCP:开闭原则(Open/Closed Principle)

软件实体(类、模块、函数等)应该 对扩展开放,对修改关闭
通过抽象和多态实现功能扩展,而不改动已有代码。


3. LSP:里氏替换原则(Liskov Substitution Principle)

子类必须能够替换其父类,而不影响程序的正确性。
如果 ST 的子类型,那么程序中任何使用 T 的地方都可以透明地使用 S


4. ISP:接口隔离原则(Interface Segregation Principle)

客户端不应该被迫依赖它不使用的接口。

将臃肿的大接口拆分为更小、更具体的接口,让实现类只关注自己需要的方法。


5. DIP:依赖倒置原则(Dependency Inversion Principle)

高层模块不应该依赖低层模块,两者都应该依赖抽象;抽象不应该依赖细节,细节应该依赖抽象。
面向接口编程,而非面向实现。

SOLID = SRP + OCP + LSP + ISP + DIP(首字母大写)


6. LoD:迪米特法则(Law of Demeter),又称 最少知道原则

一个对象应当对其他对象有尽可能少的了解。
“只与你的直接朋友通信”,降低类之间的耦合度。
例如:a.getB().getC().doSomething() 违反了 LoD,应改为 a.doSomethingOnC()


7. CARP / CRP:合成复用原则(Composite Reuse Principle)

尽量使用 组合/聚合,而不是 继承 来达到复用的目的。
继承是“白箱复用”,破坏封装;组合是“黑箱复用”,更灵活、更安全。

OCP开闭原则的核心是什么?

只要你在扩展系统功能的时候,没有修改以前写好的代码,那么你就是符合OCP原则的。

反之,如果在扩展系统功能的时候,你修改了之前的代码,那么这个设计就是失败的,违背OCP原则

当进行系统功能扩展的时候,如果动了之前稳定的程序,修改了之前的程序,之前所有程序都需要进行重新测试。这是不想看到的,因为非常麻烦。

在这里插入图片描述

可以很明显的看出,上层是依赖下层的。UserController依赖UserServiceImpl,而UserServiceImpl依赖UserDaoImplForMySQL,这样就会导致下面只要改动上面必然会受牵连(跟着也会改),所谓牵一发而动全身。这样也就同时违背了另一个开发原则:依赖倒置原则。

2、依赖倒置原则(DIP原则)

什么是依赖倒置原则?

面向接口编程,面向抽象编程, 不要面向具体编程

上层不再依赖下层,下面改动了,上面的代码不会受到牵连。

依赖倒置原则的目的

降低程序的耦合,提高扩展力。(软件七大开发原则都是在为解耦合服务

什么叫做符合依赖倒置?

上 不依赖 下 就是符合。

什么叫做违背依赖倒置?

上 依赖 下 就是违背。

只要 “下” 一改动,“上” 就受到牵连

专业点说就是:

高层模块不应依赖低层模块,二者都应依赖抽象(接口或抽象类)。抽象不应依赖细节,细节应依赖抽象。

依赖倒置原则(DIP)强调:高层模块(如业务逻辑)不应依赖低层模块(如数据库访问实现),而应共同依赖抽象(如接口)。这样当下层实现变化时,上层无需修改,从而降低耦合、提升可维护性。

我们上面的代码确实已经面向接口编程了,但对象的创建是:new UserDaoImplForOracle()显然并没有完全面向接口编程,还是使用到了具体的接口实现类。

下面代码才算是完全面向接口编程,才符合依赖倒置原则。

public class UserServiceImpl implements UserService {

    //private UserDao userDao = new UserDaoImplForMySQL();
    //private UserDao userDao = new UserDaoImplForOracle();

    private UserDao userDao;

    public boolean login(String username, String password) {
        User user = userDao.selectByUsernameAndPassword(username, password);
        if (user != null) {
            return true;
        }
        return false;
    }
}

这样userDao是null,在执行的时候就会出现空指针异常。所以我们要解决这个问题。解决空指针异常的问题,其实就是解决两个核心的问题:

  • 第一个问题:谁来负责对象的创建。【也就是说谁来:new UserDaoImplForOracle()/new UserDaoImplForMySQL()】
  • 第二个问题:谁来负责把创建的对象赋到这个属性上。【也就是说谁来把上面创建的对象赋给userDao属性】

如果把以上两个核心问题解决了,就可以做到既符合OCP开闭原则,又符合依赖倒置原则。

很荣幸的通知你:Spring框架可以做到。

在Spring框架中,它可以帮助我们new对象,并且它还可以将new出来的对象赋到属性上。换句话说,Spring框架可以帮助我们创建对象,并且可以帮助我们维护对象和对象之间的关系。

Spring可以new出来UserDaoImplForMySQL对象,也可以new出来UserDaoImplForOracle对象,并且还可以让new出来的dao对象和service对象产生关系(产生关系其实本质上就是给属性赋值)。

很显然,这种方式是将对象的创建权/管理权交出去了,不再使用硬编码的方式了。同时也把对象关系的管理权交出去了,也不再使用硬编码的方式了。像这种把对象的创建权交出去,把对象关系的管理权交出去,被称为控制反转(IOC)。

3、当前程序的设计,显然既违背OCP,又违背DIP,怎么办?

可以采用 “控制反转” 这种编程思想来解决这个问题

4、什么是控制反转(Ioc)?

控制反转(IoC):Inversion of Control

反转是什么呢?

反转是两件事:

第一件事:我不在程序中采用硬编码的方式来new对象了。(new对象我不管了,new对象的权力交出去了。)

第二件事:我不在程序中采用硬编码的方式来维护对象的关系了。(对象之间关系的维护,我也不管了,交出去了。)

控制反转:是一种编程思想,或者叫做一种新型的设计模式。由于出现的比较新,没有被纳入GoF23种设计模式范围内。

控制反转的核心是:将对象的创建权交出去,将对象和对象之间关系的管理权交出去,由第三方容器来负责创建与维护

控制反转常见的实现方式:依赖注入(Dependency Injection,简称DI)

通常,依赖注入的实现又包括两种方式:

  • set方法注入
  • 构造方法注入

而Spring框架就是一个实现了IoC思想的框架。

5、Spring框架

Spring框架实现了**控制反转(IoC)**这种思想。

Spring框架可以帮你new对象。

Spring框架可以帮你维护对象和对象之间的关系。

Spring是一个实现了IoC思想的容器

控制反转的实现方式有多种,其中比较重要的叫做:依赖注入(Dependency Injection 简称DI)。

依赖注入(DI),又包括常见的两种方式

第一种:set注入(执行set方法给属性赋值)

第二种:构造方法注入(执行构造方法给属性赋值)

依赖注入 中 “依赖”是什么意思? “注入” 是什么意思?

依赖: A对象和B对象的关系

注入:是一种手段,通过这种手段,可以让A对象和B对象产生关系。

依赖注入: 对象A和对象B之间的关系,靠注入的手段来维护。

而注入包括:set注入和构造注入。

Spring特点:

1.控制反转

Spring通过一种称作控制反转(IoC)的技术促进了松耦合。当应用了IoC,一个对象依赖的其它对象会通过被动的方式传递进来,而不是这个对象自己创建或者查找依赖对象。你可以认为IoC与JNDI相反——不是对象从容器中查找依赖,而是容器在对象初始化时不等对象请求就主动将依赖传递给它。

2.面向切面

Spring提供了面向切面编程的丰富支持,允许通过分离应用的业务逻辑与系统级服务(例如审计(auditing)和事务(transaction)管理)进行内聚性的开发。应用对象只实现它们应该做的——完成业务逻辑——仅此而已。它们并不负责(甚至是意识)其它的系统级关注点,例如日志或事务支持。

3.容器

Spring包含并管理应用对象的配置和生命周期,在这个意义上它是一种容器,你可以配置你的每个bean如何被创建——基于一个可配置原型(prototype),你的bean可以创建一个单独的实例或者每次需要时都生成一个新的实例——以及它们是如何相互关联的。然而,Spring不应该被混同于传统的重量级的EJB容器,它们经常是庞大与笨重的,难以使用。

6、Spring 8大模块

Spring Core : 控制反转(IoC)。

Spring AOP :面向切面编程。

Spring Web MVC :Spring自己提供了一套MVC框架。

Spring Webflux : Spring提供的响应式web框架。

Spring Web :支持集成常见的Web框架, struts,webwork…

Spring Dao :提供了单独的支持JDBC操作的API。

Spring ORM :支持集成常见的ORM框架,Mybatis,Hibernate…

Spring Context :国际化消息(I18N),事件传播,验证支持,企业服务,Velocity和FreeMarker集成的支持…

JAR文件描述
spring-aop-6.0.2.jar这个jar 文件包含在应用中使用Spring 的AOP 特性时所需的类
spring-aspects-6.0.2.jar提供对AspectJ的支持,以便可以方便的将面向切面的功能集成进IDE中
spring-beans-6.0.2.jar这个jar 文件是所有应用都要用到的,它包含访问配置文件、创建和管理bean 以及进行Inversion ofControl / Dependency Injection(IoC/DI)操作相关的所有类。如果应用只需基本的IoC/DI 支持,引入spring-core.jar 及spring-beans.jar 文件就可以了。
spring-context-6.0.2.jar这个jar 文件为Spring 核心提供了大量扩展。可以找到使用Spring ApplicationContext特性时所需的全部类,JDNI 所需的全部类,instrumentation组件以及校验Validation 方面的相关类。
spring-context-indexer-6.0.2.jar虽然类路径扫描非常快,但是Spring内部存在大量的类,添加此依赖,可以通过在编译时创建候选对象的静态列表来提高大型应用程序的启动性能。
spring-context-support-6.0.2.jar用来提供Spring上下文的一些扩展模块,例如实现邮件服务、视图解析、缓存、定时任务调度等
spring-core-6.0.2.jarSpring 框架基本的核心工具类。Spring 其它组件要都要使用到这个包里的类,是其它组件的基本核心,当然你也可以在自己的应用系统中使用这些工具类。
spring-expression-6.0.2.jarSpring表达式语言。
spring-instrument-6.0.2.jarSpring3.0对服务器的代理接口。
spring-jcl-6.0.2.jarSpring的日志模块。JCL,全称为"Jakarta Commons Logging",也可称为"Apache Commons Logging"。
spring-jdbc-6.0.2.jarSpring对JDBC的支持。
spring-jms-6.0.2.jar这个jar包提供了对JMS 1.0.2/1.1的支持类。JMS是Java消息服务。属于JavaEE规范之一。
spring-messaging-6.0.2.jar为集成messaging api和消息协议提供支持
spring-orm-6.0.2.jarSpring集成ORM框架的支持,比如集成hibernate,mybatis等。
spring-oxm-6.0.2.jar为主流O/X Mapping组件提供了统一层抽象和封装,OXM是Object Xml Mapping。对象和XML之间的相互转换。
spring-r2dbc-6.0.2.jarReactive Relational Database Connectivity (关系型数据库的响应式连接) 的缩写。这个jar文件是Spring对r2dbc的支持。
spring-test-6.0.2.jar对Junit等测试框架的简单封装。
spring-tx-6.0.2.jar为JDBC、Hibernate、JDO、JPA、Beans等提供的一致的声明式和编程式事务管理支持。
spring-web-6.0.2.jarSpring集成MVC框架的支持,比如集成Struts等。
spring-webflux-6.0.2.jarWebFlux是 Spring5 添加的新模块,用于 web 的开发,功能和 SpringMVC 类似的,Webflux 使用当前一种比较流程响应式编程出现的框架。
spring-webmvc-6.0.2.jarSpringMVC框架的类库
spring-websocket-6.0.2.jarSpring集成WebSocket框架时使用

注意:

如果你只是想用Spring的IoC功能,仅需要引入:spring-context即可。将这个jar包添加到classpath当中。

如果采用maven只需要引入context的依赖即可。

当加入spring context的依赖之后,会关联引入其他依赖:

spring aop:面向切面编程

spring beans:IoC核心

spring core:spring的核心工具包

spring jcl:spring的日志包

spring expression:spring表达式

7、Spring配置文件

bean标签
id属性:唯一标识
class属性:要创建对象所在类的全路径(包名称+类名)

​ 文件名可以自定义 ,比如 spring.xml
​ 最好是放在类路径当中,方便日后的移植
​ 放在resources根目录下,就相当于是放到了类的根目录下

在配置文件中配置bean,这样Spring才可以帮助我们管理这个对象

​ 底层是map集合 所以id不能重复

private final Map<String, BeanDefinition> beanDefinitionMap;

在这里插入图片描述

spring.xml如下所示:

<?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">

<!--完成User对象的创建-->
<!--这就是Spring的配置文件-->
<bean id="user" class="com.zzz.User"></bean>
</beans>

8、Spring怎么实例化对象的?

默认情况下Spring会通过反射机制,调用类的无参数构造方法来实例化对象

所以要想让Spring 帮助我们创建对象,必须保证无参数构造方法是存在的

实现原理如下:

//通过dom4j解析spring.xml配置文件,从中获取class的全限定类名
//通过反射机制调用无参数构造方法创建对象
Class clazz = Class.forName("com.zzz.pojo.User");
clazz.getDeclaredConstructor().newInstance();

id重复:

<?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="com.zzz.User"></bean>
<bean id="user" class="com.zzz.Vip"></bean>
</beans>

报错信息:

org.springframework.beans.factory.parsing.BeanDefinitionParsingException: Configuration problem: Bean name 'user' is already used in this <beans> element

没有无参构造:

public class User {
//    public User() {

//    }

	public User(String name) {

	}
}

报错信息:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'user' defined in class path resource [bean.xml]: Failed to instantiate [com.zzz.pojo.User]: No default constructor found

9、配置文件的名字和位置

名字是自定义的,配置文件的位置可以在resources目录下任意位置:

在这里插入图片描述

@Test
public void test(){
    //默认路径就是resources
    ApplicationContext applicationContext =
            new ClassPathXmlApplicationContext("bean.xml", "spring.xml", "xml/beans.xml");
    //获取创建的对象
    User user = (User) applicationContext.getBean("user");

    System.out.println(user);
    //调用方法
    user.add();

    Vip Vip = (Vip) applicationContext.getBean("Vip");
    System.out.println(Vip);

    User user2 = (User) applicationContext.getBean("user2");
    System.out.println(user2);

}

10、Bean除了配置自定义类,可以使用JDK中的类吗?

spring配置文件中配置的bean可以为任意类,只要这个类不是抽象的,并且提供了无参数构造方法。

spring的配置文件可以有多个,在ClassPathXmlApplicationContext构造方法的参数上传递文件路径即可。

spring.xml:

<?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="nowTime" class="java.util.Date"></bean>

</beans>
@Test
public void test(){
ApplicationContext applicationContext =
        new ClassPathXmlApplicationContext("bean.xml", "spring.xml", "xml/beans.xml");

Date nowTime = (Date) applicationContext.getBean("nowTime");
    System.out.println(nowTime);

}

运行程序:

在这里插入图片描述

11、getBean()返回的类型是Object类型,如果要访问子类中的特有属性和方法时,还需要向下转型,有其他方法吗?

Date nowTime = (Date) applicationContext.getBean("nowTime");

Date nowTime = applicationContext.getBean("nowTime",Date.class);

12、ClassPathXmlApplicationContext是从类路径中加载配置文件,如果没有在类路径当中,又应该如何加载配置文件呢?

<?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="nowTime" class="java.util.Date"/>
</beans>
@Test
public void testXmlPath() {
    ApplicationContext applicationContext = new FileSystemXmlApplicationContext("D://spring.xml");

    Date nowTime =  applicationContext.getBean("nowTime",Date.class);
    System.out.println(nowTime);
}

运行测试程序:

在这里插入图片描述

没有在类路径的话,需要使用FileSystemXmlApplicationContext类进行加载配置文件。

这种方式较少用。一般都是将配置文件放到类路径当中,这样可移植性更强。

13、ApplicationContext的超级父接口是BeanFactory

Spring有两个核心接口:BeanFactory 和 ApplicationContext,其中ApplicationContext是BeanFactory 的子接口。它们代表Spring容器,Spring容器是生成Bean实例的工厂,并管理容器中的Bean,Bean是Spring管理的基本单位,在基于spring的javaEE应用中,所有的组件都被当成bean来处理

BeanFactory beanFactory = new ClassPathXmlApplicationContext("spring.xml");
Object vipBean = beanFactory.getBean("vipBean");
System.out.println(vipBean);

ApplicationContext的超级父接口是BeanFactory(Bean工厂,就是能够生产Bean对象的一个工厂对象)

BeanFactory是IoC容器的顶级接口,ApplicationContext是BeanFactory的子接口。

Spring的IoC容器底层实际上使用了:工厂模式

Spring底层的IoC是怎么实现的?

XML解析 + 工厂模式 + 反射机制

Spring中ApplicationContext的三种不同实现:

1)FileSystemXmlApplicationContext

这种方式是通过程序在初始化的时候,导入Bean配置文件,然后得到Bean实例。

ApplicationContext ctx = newFileSystemXmlApplicationContext("spring-config.xml"); //当前路径加载单个配置文件

String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};

ApplicationContext ctx = new FileSystemXmlApplicationContext(locations ); //同时加载多个配置文件

ApplicationContext ctx = new FileSystemXmlApplicationContext("D:/project/bean.xml");//根据具体路径加载文件

对于FileSystemXmlApplicationContext:

默认表示的是两种:

1.没有盘符的是项目工作路径,即项目的根目录;

2.有盘符表示的是文件绝对路径.

注意:如果要使用classpath路径,需要前缀classpath:

2)ClassPathXmlApplicationContext

ApplicationContext ctx = new ClassPathXmlApplicationContext("bean.xml");//加载单个配置文件

String[] locations = {"bean1.xml", "bean2.xml", "bean3.xml"};

ApplicationContext ctx = newClassPathXmlApplication(locations);//同时加载多个配置文件。

//或者用通配符同时加载多个配置文件:

ApplicationContext ac = new ClassPathXmlApplicationContext("classpath:/*.xml");

注:其中FileSystemXmlApplicationContextClassPathXmlApplicationContext与BeanFactory的xml文件定位方式一样是基于路径的。

ClassPathXmlApplicationContextFileSystemXmlApplicationContext的区别如下:

1.classpath:前缀是不需要的,默认就是指项目的classpath路径下面;

2.如果要使用绝对路径,需要加上file:前缀表示这是绝对路径;

3)XmlWebApplicationContext:

在B/S系统中,通常在web.xml初始化bean的配置文件,然后由WebAppliCationContextUtil得到ApplicationContext

ServletContext servletContext =request.getSession().getServletContext();

ApplicationContext ctx = WebApplicationContextUtils.getWebApplicationContext(servletContext);

例子如下:

public static void main(String[] args) {

    ApplicationContext factory = null;

    //用classpath路径,用ClassPathXmlApplicationContext类时,有没有classpath:前缀都是一样的。

    factory = new ClassPathXmlApplicationContext("classpath:appcontext.xml");

    factory = new ClassPathXmlApplicationContext("appcontext.xml");

    // ClassPathXmlApplicationContext使用了file前缀是可以使用绝对路径的。

    factory = new ClassPathXmlApplicationContext("file:F:/workspace/example/src/appcontext.xml");
    
    // 可以同时加载多个文件
    
	String[] xmlCfg = new String[] { "classpath:base.bean1.xml","app.bean1.xml"}; 
    
    factory = new ClassPathXmlApplicationContext(xmlCfg);

	//使用通配符加载所有符合要求的文件
	
    ApplicationContext appCt = new ClassPathXmlApplicationContext("*.bean1.xml");


    // 用文件系统的路径,默认为项目工作路径 即项目的根目录

    factory = new FileSystemXmlApplicationContext("src/appcontext.xml");

    factory = new FileSystemXmlApplicationContext("webRoot/WEB-INF/appcontext.xml");
    
    // 使用了classpath:前缀,这样,FileSystemXmlApplicationContext也能够读取classpath下的相对路径

    factory = new FileSystemXmlApplicationContext("classpath:appcontext.xml");

    // 加不加file前缀都是一样的。

    factory = new FileSystemXmlApplicationContext("file:F:/workspace/example/src/appcontext.xml");

    factory = new FileSystemXmlApplicationContext("F:/workspace/example/src/appcontext.xml");
    
    // 可以同时加载多个文件
	String[] xmlCfg = new String[] { "src/config/bean1.xml","classpath:app.bean1.xml"}; 
    
    factory = new FileSystemXmlApplicationContext(xmlCfg);

	// 使用通配符加载所有符合要求的文件
    
	factory = new FileSystemXmlApplicationContext("classpath:*.bean1.xml");

    HelloClient hw = (HelloClient) factory.getBean("helloworldbean");
}

三个实现类的区别:

FileSystemXmlApplicationContext:通过程序在初始化的时候,导入Bean配置文件,然后得到Bean实例。

XmlWebApplicationContext:在B/S系统中,通常在web.xml初始化bean的配置文件,然后由WebApplicationContextUtils得到ApplicationContext

例如:

ApplicationContext ctx = WebApplicationContextUtils.getRequiredWebApplicationContext(ServletContext sc);

ApplicationContext ctx =WebApplicationContextUtils.getWebApplicationContext(ServletContext sc);

其中 ServletContext sc 可以具体 换成 servlet.getServletContext()或者 this.getServletContext() 或者 request.getSession().getServletContext();
另外,由于spring是注入的对象放在ServletContext中的,所以可以直接在ServletContext取出WebApplicationContext 对象:

14、BeginInitBean的时机

不是在调用getBean()方法的时候创建对象,执行以下代码的时候,就会实例化对象

new ClassPathXmlApplicationContext("spring.xml");

15、Spring6启用Log4j2日志框架

从Spring5之后,Spring框架支持集成的日志框架是Log4j2.如何启用日志框架

第一步:引入Log4j2的依赖

<!--log4j2的依赖-->
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-core</artifactId>
  <version>2.19.0</version>
</dependency>
<dependency>
  <groupId>org.apache.logging.log4j</groupId>
  <artifactId>log4j-slf4j2-impl</artifactId>
  <version>2.19.0</version>
</dependency>

第二步:在类的根路径下提供log4j2.xml配置文件(文件名固定为:log4j2.xml,文件必须放到类根路径下。)

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

    <loggers>
        <!--
            level指定日志级别,从低到高的优先级:
                ALL < TRACE < DEBUG < INFO < WARN < ERROR < FATAL < OFF
        -->
        <root level="DEBUG">
            <appender-ref ref="spring6log"/>
        </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>
    </appenders>

</configuration>

第三步:使用日志框架

Logger logger = LoggerFactory.getLogger(FirstSpringTest.class);
logger.info("我是一条日志消息");
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值