Spring 学习笔记 - Part2

学习资源来自B站黑马程序员: https://www.bilibili.com/video/BV1Fi4y1S7ix/?p=20&share_source=copy_web&vd_source=c76bb3d6e0326c966bf1bf32db90eb22

Spring 管理第三方数据源

在pom.xml 导入依赖

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
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.16</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.32</version>
</dependency>

<!-- https://mvnrepository.com/artifact/c3p0/c3p0 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>

</dependencies>

配置文件resources/applicationContext.xml中配置数据库连接

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!-- 管理DruidDataSource 对象-->
<bean id="dataSource2" class = "com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///spring_db"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</bean>

<!-- 管理c3p0 DataSource 对象-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.cj.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql:///spring_db"/>
<property name="user" value="root"/>
<property name="password" value="123456"/>
<property name="maxPoolSize" value="10"/>
</bean>

主程序调用

1
2
3
4
5
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
DataSource dataSource = (DataSource) ctx.getBean("dataSource");
System.out.println(dataSource);
}

加载properties配置信息

但properties配置文件

把相关参数提取到properties文件中配置。

  • 开启context命名空间
  • 使用context命名空间加载properties文件
  • 使用${} 读取加载的属性值

jdbc.properties内容如下

1
2
3
4
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_db
jdbc.username=root
jdbc.password=123456

applicationContext.xml内容如下

下面context第5、11、12、17行,为修改的

2025是注册数据库,2729是注入一个参数,主函数用来调用查看,用的setter注入。

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"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd

http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
">
<!-- 1. 相当于创建了一个叫做context的命名空间。-->

<!-- 2. 使用context的命名空间加载properties文件-->
<!-- system-properties-mode="NEVER" 表示不加载系统变量,为了防止和系统变量重名,导致调用错误。-->
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>

<!-- 3. 使用属性占位符${}读取properties文件中的属性-->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>

<bean id="bookDao" class="com.dao.impl.BookDaoImpl">
<property name="name" value="${jdbc.driver}"/>
</bean>

</beans>

接口

1
2
3
public interface BookDao {
public void save();
}

接口的实现 --> setter 注入

1
2
3
4
5
6
7
8
9
10
11
12
public class BookDaoImpl implements BookDao {
private String name;

public void setName(String name) {
this.name = name;
}

@Override
public void save() {
System.out.println("book dao save ... "+ name);
}
}

主函数调用

1
2
3
4
5
6
7
public class App {
public static void main(String[] args) {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
bookDao.save();
}
}

多properties配置文件

在读取时用 "," 隔开

1
<context:property-placeholder location="jdbc.properties , jdbc2.properties" system-properties-mode="NEVER"/>

**也可以用通配符 "*"**

1
<context:property-placeholder location="*.properties" system-properties-mode="NEVER"/>

建议加上类路径

1
<context:property-placeholder location="classpath:*.properties" system-properties-mode="NEVER"/>

**如果不是本工程的配置文件, 在classpath后面再加一个 "*"**

一般用下面这种写法。

1
<context:property-placeholder location="classpath*:*.properties" system-properties-mode="NEVER"/>

容器

容器创建

  • 方式一:路径加载配置文件
1
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
  • 方式二:文件路径加载配置文件
1
ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\applicationContext.xml");
  • 方式三:读取web下的资源文件
1
XmlWebApplicationContext ctx = new XmlWebApplicationContext();
  • 加载多个配置文件
1
ApplicationContext ctx = new ClassPathXmlApplicationContext("bean1.xml","bean2.xml"); 

获取bean

  • 方式一:使用bean名称获取
1
BookDao bookDao = (BookDao) ctx.getBean("bookDao");
  • 方式二:使用bean名称获取并指定类型
1
BookDao bookDao = ctx.getBean("bookDao",BookDao.class);
  • 方式三:使用bean类型获取,容器中只能有一个BookDao类型的bean
1
BookDao bookDao = ctx.getBean(BookDao.class);

容器层次结构

早期bean,了解即可

总览 BeanFactory 体系,按照接口的抽象层次,大体可以分层四层:

  • 第一层:BeanFactory
  • 第二层:HierarchicalBeanFactoryListableBeanFactoryAutowireCapableBeanFactory
  • 第三层:ConfigurableBeanFactory,此外还有一个关联性较强SingletonBeanRegistry
  • 第四层:ConfigurableListableBeanFactory

BeanFactory初始化

  • 类路径加载配置文件
1
2
3
4
Resource resources = new ClassPathResource("applicationContext.xml");
BeanFactory bf = new XmlBeanFactory(resources);
BookDao bookDao = bf.getBean("bookDao",BookDao.class);
bookDao.save();

注意:BeanFactory创建完毕后,所有的bean均为延时加载

延时加载好处:当为了追求传输效率就会需要什么就再去创建什么时,就会体现出延迟加载的好处,有一个缓冲时间。

如果想用ApplicationContext做延迟加载,直接在applicationContext.xml的bean里面增加参数 lazy-init="true"

核心容器总结

  • BeanFactory是IoC容器的顶层接口,初始化BeanFactory对象时,加载的bean延时加载
  • ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载。(常用)
  • ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
  • ApplicationContext接口常用初始化类
    • ClassPathXmlApplicationContext
    • FileSystemXmlApplicationContext

bean相关

依赖注入

推荐使用setter注入,构造器注入不常用。按类型,按索引装配也不常用。