创建Maven聚合工程

入门案例开发步骤

创建父工程 spring6

子模块 spring-first

image-20230610174204493

第一步,引入spring相关依赖

1
2
3
4
5
6
7
8
9
10
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>6.0.2</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.3.1</version>
</dependency>

image-20230610174359351

第二步,创建类,定义属性和方法

1
2
3
4
5
6
public class User {

public void add(){
System.out.println("add...");
}
}

第三步,按照spring要求创建配置文件(xml格式)

image-20230610175953971

第四步,在spring配置文件配置相关信息

image-20230610180800464

第五步,进行最终测试

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public class TestUser {

@Test
public void testUserObject(){
//加载Spring的配置文件,对象创建
ApplicationContext context =
new ClassPathXmlApplicationContext("bean.xml");

//获取创建的对象
User user = (User)context.getBean("user");
System.out.println(user);

//使用对象调用方法进行测试
user.add();
}
}

如何返回创建的对象

1.加载bean.xml配置文件

2.对xml文件进行解析操作

3.获取xml文件bean标签属性值,id属性值和class属性值

4.使用反射根据类全路径创建对象

1
2
3
4
5
6
7
8
9
@Test
public void testObject1() throws Exception {
//获取类class对象
Class clazz = Class.forName("com.test.spring6.User");
//调用方法创建对象
//Object o = clazz.newInstance();
User user = (User) clazz.getDeclaredConstructor().newInstance();
System.out.println(user);
}

创建对象放到哪里了

查找DefaultlistableBeanFactory在下面Map集合中会存储好的对象

1
private final Map<String, BeanDefinition> beanDefinitionMap;

key:唯一标识

value:类的定义(描述信息)

Log4j2

Apache Log4j2是一个开源的日志记录组件,使用非常广泛。在工程中以易用方便代替了sout等打印语句,它是java日志输入工具

Log4j2主要由几个重要的组件构成

1.日志信息的优先级,日志信息的优先级从高到低有TRACE<DEBUG<INFO<WARN<ERROR<FATAL

TRACE 追踪,是最低的日志级别,相当于追踪程序的执行

DEBUG 调试,一般在开发中,都将其设置为最低的日志级别

INFO 信息,输出重要信息使用较多

WARN 警告,输出告警的信息

ERROR 错误,输出错误信息

FATAL 严重错误

级别高会自动屏蔽级别低的

2.日志信息的输出目的地,指定是打印控制台还是文件中

3.日志信息的输出格式

引入Log4j2依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<loggers>
<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="e:/springDEMO/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="e:/springDEMO/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>

测试

1
2
3
Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2d96543c
Loaded 1 bean definitions from class path resource [bean.xml]
Creating shared instance of singleton bean 'user'

手动使用日志

1
2
3
4
5
6
7
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//创建对象
private Logger logger = LoggerFactory.getLogger(TestUser.class);

//手动写日志
logger.info("#####执行调用");

IOC

基于XML管理bean

获取ben的三种方式

1
2
3
4
5
6
7
8
9
10
ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");
//1.根据id获取bean
User user1 = (User)context.getBean("user");
System.out.println("根据id获取bean" + user1);
//2.根据类型获取bean
User user2 = context.getBean(User.class);
System.out.println("根据类型获取bean" + user2);
//3.根据id和类型
User user3 = context.getBean("user", User.class);
System.out.println("根据id和类型获取bean" + user3);

根据类型获取bean时,要求IOC容器中指定类型的bean有且只能有一个

依赖注入

类有属性,创建对象过程中,向属性设置值

1
2
3
4
5
6
//set
Book book = new Book();
book.setBname("php");
book.setAuthor("李四");
//构造器
Book book1 = new Book("java","张三");

setter注入

1.创建类,定义属性,生成属性set方法

2.在spring配置文件配置

1
2
3
4
<bean id="book" class="com.test.spring6.iocxml.di.Book">
<property name="bname" value="前端开发"></property>
<property name="author" value="王五"></property>
</bean>
1
2
3
4
5
6
7
 @Test
public void testSetter(){
ApplicationContext context = new ClassPathXmlApplicationContext("beandi.xml");
Book book = context.getBean("book", Book.class);
System.out.println(book);
}
}

构造器注入

1.创建类定义属性,生成有参构造方法

2.在spring中配置

1
2
3
4
<bean id="bookCon" class="com.test.spring6.iocxml.di.Book">
<constructor-arg name="bname" value="java开发"></constructor-arg>
<constructor-arg name="author" value="赵六"></constructor-arg>
</bean>
1
2
3
4
5
public void testConstrutor(){
ApplicationContext context = new ClassPathXmlApplicationContext("beandi.xml");
Book book = context.getBean("bookCon", Book.class);
System.out.println(book);
}

特殊值

mull

1
2
3
<property name="other">
<null/>
</property>

xml实体

1
<property name="bname" value="&lt;"></property>

CDATA节

1
2
3
<property name="other">
<value><![CDATA[A < B]]></value>
</property>

CDATA[] 中纯文本数据 < 不会被解析

特殊类型属性注入

对象类型属性注入

为对象类型属性赋值

部门类

1
2
3
4
5
6
7
8
9
10
//部门类
public class Dept {

private String dname;

public void info(){
System.out.println("部门名称:"+ dname);
}

}

员工类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
//员工类
public class Emp {

//表示员工属于某个部门
private Dept dept;

private String ename;
private Integer age;

public void work(){
System.out.println(ename + "emp work" +age+ "岁");
dept.info();
}
}

1.引用外部bean

1
2
3
4
5
6
7
8
9
10
11
12
13
<!--
引入外部bean
1创建两个类对象:dept和emp
2在emp的bean标签里面,使用标签property引入dept的bean
-->
<bean id="dept" class="com.test.spring6.iocxml.ditest.Dept">
<property name="dname" value="安全部门"></property>
</bean>
<bean id="emp" class="com.test.spring6.iocxml.ditest.Emp">
<property name="ename" value="张三"></property>
<property name="age" value="50"></property>
<property name="dept" ref="dept"> </property>
</bean>

2.引用内部bean

1
2
3
4
5
6
7
8
9
10
<bean id="emp" class="com.test.spring6.iocxml.ditest.Emp">
<property name="ename" value="张三"></property>
<property name="age" value="51"></property>
<!--内部bean方式注入-->
<property name="dept">
<bean id="dept" class="com.test.spring6.iocxml.ditest.Dept">
<property name="dname" value="安全部门"></property>
</bean>
</property>
</bean>

3.级联属性赋值

1
2
3
4
5
6
7
8
9
10
11
<bean id="dept" class="com.test.spring6.iocxml.ditest.Dept">
<property name="dname" value="技术部门"></property>
</bean>

<bean id="emp" class="com.test.spring6.iocxml.ditest.Emp">
<property name="ename" value="张三"></property>
<property name="age" value="52"></property>
<!--级联属性赋值-->
<property name="dept" ref="dept"></property>
<property name="dept.dname" value="测试部门"></property>
</bean>

数组类型注入

1
2
3
4
5
6
7
8
<!--数组类型属性-->
<property name="loves">
<array>
<value>like1</value>
<value>like2</value>
<value>like3</value>
</array>
</property>

集合类型注入

1.部门类添加集合private List<Emp> empList;

2.在部门方法中添加遍历员工姓名方法for (Emp emp:empList){System.out.println(emp.getEname());}

3.spring配置文件中,使用<list><ref>标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<bean id="dept" class="com.test.spring6.iocxml.ditest.Dept">
<property name="dname" value="网络部"></property>
<property name="empList">
<list>
<ref bean="emp1"></ref>
<ref bean="emp2"></ref>
</list>
</property>
</bean>
<bean id="emp1" class="com.test.spring6.iocxml.ditest.Emp">
<property name="ename" value="lisi"></property>
</bean>
<bean id="emp2" class="com.test.spring6.iocxml.ditest.Emp">
<property name="ename" value="wangwu"></property>
</bean>

Map类注入

private Map<String,Teacher> teacherMap;

1
2
3
4
5
6
7
8
<map>
<entry>
<key>
<value>1111</value>
</key>
<ref bean="text"></ref>
</entry>
</map>

引用集合类型

image-20230611195427047

添加约束

1
2
3
4
5
6
7
8
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/util
http://www.springframework.org/schema/beans/spring-util.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">

bean的作用域

bean的生命周期