第一个Spring及日志整合
第一个Spring
1、软件版本
1. JDK13
2. Meven3.6.3
3. IDEA2019
4. SpringFramework 5.2.5
官网:https://spring.io/projects/spring-framework#overview
官方下载地址:https://repo.spring.io/release/org/springframework/spring/
Github:https://github.com/spring-projects/spring-framework
2、环境搭建
Spring Context的jar包
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
<!-- 暂时不用 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.2.5.RELEASE</version>
</dependency>
Spring的配置文件
1. 配置文件的放置位置:任意位置没有硬性要求
2. 配置文件的命名 :没有硬性要求 建议: applicationContext.xml
思考:日后应用Spring框架时,需要进行配置文件路径的设置。
3、spring的核心API
ApplicationContext
1. 作用: Spring提供的ApplicationContext这个工厂,用于对象的创建
2. 好处:解耦合
ApplicationContext接口类型
1. 接口:屏蔽实现的差异
2. 非web环境 : ClassPathXmlApplicationContext (main junit)
3. web环境:XmlWebApplicationContext
重量级资源
1. ApplicationContext工厂的对象占用大量内存。
2. 不会频繁的创建对象:一个应用只会创建一个工厂对象。
3. ApplicationContext工厂:一定是线程安全的(多线程并发访问)
4、程序开发
1. 创建类型
2. 配置文件的配置 applicationContext.xml
<bean id="person" class="com.company.basic.Person"/>
3. 通过工厂类,获得对象
ApplicationContext
| - ClassPathXmlApplicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
Person person = (Person) ctx.getBean("person");
applicationContext.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">
<!--id属性名字(唯一)
class属性配置全限定名名
-->
<bean id="person" class="com.company.basic.Person"/>
</beans>
Test
/**
* 用于测试: 测试spring的第一个程序
*
*/
@Test
public void test2(){
// 1. 获取Spring的工厂(此时在resources下的根目录)
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
// 2. 通过工厂类创建对象
Person person = (Person) ctx.getBean("person");
System.out.println(person); // com.company.basic.Person@3bb9a3ff
}
5、细节分析
名词解释
Spring工厂创建的对象,叫做bean或者组件(componet)
测试Spring工厂提供的各种方法
/**
* 用于测试:测试Spring的各种方法
*
*/
@Test
public void test3(){
// 获取Spring的工厂(此时在resources下的根目录)
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
//================================= 各种方法 =================================
// 通过工厂类创建对象
Person person2 = (Person) ctx.getBean("person");
System.out.println(person2); // com.company.basic.Person@3bb9a3ff
// 使用这种方法获取对象,就不需要强制转换
Person person = ctx.getBean("person", Person.class);
System.out.println("person = " + person);
// 当前Spring的配置文件中只能有一个 <bean class 是Person类型
// 一个以上会报错:No qualifying bean of type 'com.company.basic.Person' available:
// expected single matching bean but found 2: person,person1
Person person1 = ctx.getBean(Person.class);
System.out.println("bean = " + person1);
// 获取的是Spring工厂配置文件中所有bean标签的id值 person person1
String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
}
//根据类型获得Spring配置文件中对应的id值 id = person id = person1
String[] beanNamesForType = ctx.getBeanNamesForType(Person.class);
for (String id : beanNamesForType) {
System.out.println("id = " + id);
}
// 用于判断是否存在指定id值的bean,不能判断name值
if (ctx.containsBeanDefinition("person")) {
System.out.println("true = " + true);
}else {
System.out.println("false = " + false);
}
//用于判断是否存在指定id值得bean,也可以判断name值
if (ctx.containsBean("person")) {
System.out.println("true = " + true);
}else {
System.out.println("false = " + false);
}
}
配置文件中需要的细节
1. 配置class文件
<bean class="com.company.basic.Person"/>
a) 上述情况配置文件:没有设置id值: com.company.basic.Person#0
b) 应用场景: 如果这个bean只需要使用一次,那么就可以省略id值
如果这个bean会使用多次,或者被其他bean引用则需要设置id值
2. name属性
作用:用于在Spring的配置文件中,为bean对象定义别名(小名)
<bean id="person" name="p,p1" class="com.company.basic.Person"/>
相同:
1.ctx.getBean("id|name" )-->object
2.<bean id=" " class=" "
等效
<bean name="" class=""
区别:
1. 别名可以定义多个,但是id属性只能有一一个值
2. XML的id属性的值,命名要求:必须以字母开头,字母 数字 下划线 连字符 不能以特殊字符开头 /person
name属性的值,命名没有要求 /person
name属性会应用在特殊命名的场景下: /person ( spring+struts1)
XML发展到了今天: ID属性的限制,不存在 /person
3. 代码
// 用于判断是否存在指定id值的bean,不能判断name值
if (ctx.containsBeanDefinition("person")) {
System.out.println("true = " + true);
}else {
System.out.println("false = " + false);
}
//用于判断是否存在指定id值得bean,也可以判断name值
if (ctx.containsBean("p")) {
System.out.println("true = " + true);
}else {
System.out.println("false = " + false);
}
代码
/**
* 用于测试:测试spring的id属性
*
*/
@Test
public void test5(){
// 配置文件:没有设置id
// <bean class="com.company.basic.Person"/>
ApplicationContext ctx = new ClassPathXmlApplicationContext("/applicationContext.xml");
String[] beanDefinitionNames = ctx.getBeanDefinitionNames();
for (String beanDefinitionName : beanDefinitionNames) {
System.out.println("beanDefinitionName = " + beanDefinitionName);
// beanDefinitionName = com.company.basic.Person#0
}
}
6、Spring工厂的底层实现原理(非源码)
spring工厂可以调用私有的构造方法创建对象
7、思考
问题:未来在开发过程中,是不是所有的对象,都会交给Spring工厂来创建呢?
回答:理论上是的,但是有特例:实体对象(entity )是不会交给Spring创建,它是由持久层框架进行创建。
Spring5.x与日志框架的整合
Spring与日志框架进行整合,日志框架就可以在控制台中,输出Spring框架运行过程中的一些重要的信息。
好处:便于了解Spring框架的运行过程,利于程序的调试
如何整合
默认
- Spring1.2.3早期都是于commons- logging. jar
- Spring5.x 默认整合的日志框架logback log4j2
如何让Spring5. x整合log4j
- 1.引入log4j jar包
- 2.引入log4j.properties配置文件
pom.xml
<!--门面模式| 整合log4j | 屏蔽默认的日志框架 -->
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
</dependency>
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
log4j.properties
# resources文件夹根目录下
### 配置根
log4j.rootLogger = debug,console
### 日志输出到控制台显示
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.layout=org.apache.log4j.PatternLayout
### 年月日时分秒、类、行号、方法名、换行
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n