持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第21天,点击查看活动详情
Spirng管理数据库和引入外部文件
在pom.xml添加依赖
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.3</version>
</dependency>
<!-- 数据源 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.31</version>
</dependency>
创建一个jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC&characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456
配置bean 利用context:property-placeholder引入jdbc文件
<!--引入jdbc.properties,之后就可以通过${key}的方式访问value-->
<context:property-placeholder location="jdbc.properties"></context:property-placeholder>
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driver}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
</beans>
测试
@Test
public void testDatasource() throws SQLException {
ApplicationContext ioc=new ClassPathXmlApplicationContext("spring-datasource.xml");
DruidDataSource dataSource = ioc.getBean(DruidDataSource.class);
System.out.println("dataSource.getConnection() = " + dataSource.getConnection());
}
看是否连接成功
bean的作用域
<!--scope:设置bean的作用域
scope="singleton|prototype"
singleton(单例):表示获取改bean所对应的对象都是同一个
prototype(多例):表示获取该bean所对应的对象都不是同一个
如果是在WebApplicationContext幻境下还会有另外两个作用域(但不常用)
request 在一个请求范围内有效
|session 在一个会话范围内有效-->
<bean id="student" class="com.atguigu.spring.pojo.Student" scope="prototype">
<property name="sid" value="1001"></property>
<property name="sname" value="占山"></property>
</bean>
注意:
- 若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
- 若bean的作用域为多例时,生命周期的三个步骤会在回去bean时执行
bean的生命周期
具体的生命周期过程
bean对象创建(调用无参构造器) 给bean对象设置属性 bean对象初始化之前操作(由bean的后置处理器负责) bean对象初始化(需在配置bean时指定初始化方法) bean对象初始化之后操作(由bean的后置处理器负责) bean对象就绪可以使用 bean对象销毁(需在配置bean时指定销毁方法) IOC容器关闭
修改user类
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
public User() {
System.out.println("生命周期1:实例化");
}
public User(Integer id, String username, String password, Integer age) {
this.id = id;
this.username = username;
this.password = password;
this.age = age;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
System.out.println("生命周期2:依赖注入");
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + ''' +
", password='" + password + ''' +
", age=" + age +
'}';
}
public void initMethod(){
System.out.println("生命周期3:初始化");
}
public void destroyMethod(){
System.out.println("生命周期4:销毁");
}
}
spring-lifecycle的配置bean
<bean id="user" scope="prototype" class="com.atguigu.spring.pojo.User" init-method="initMethod" destroy-method="destroyMethod">
<property name="id" value="1"></property>
<property name="username" value="张三"></property>
<property name="password" value="123"></property>
<property name="age" value="15"></property>
</bean>
<bean id="MyBeanPostProcessor" class="com.atguigu.spring.process.MyBeanPostProcessor"></bean>
将scope设置为多例不会在创建ioc时创建 销毁不由ioc管理
/**
* 1.实例化
* 2.依赖注入
* 3.后置处理器的postProcessBeforeInitialization
* 4.初始化,需要通过bean的init-method属性
* 5.后置处理的postProcessAfterInitialization
* 6.IOC容器关闭时销毁 需要通过bean的destroy-method属性指定销毁的方法
* 注意:
* 若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
* 若bean的作用域为多例时,生命周期的三个步骤会在回去bean时执行
* @author zzw
* @version 1.0
* Create by 2022/10/16 19:26
*/
@Test
public void test(){
//ConfigurableApplicationContext是ApplicationContext的子接口
//其中扩展了刷新和关闭容器的方法
// 将scope设置为多例不会在创建ioc时创建 销毁不由ioc管理
ConfigurableApplicationContext ioc=new ClassPathXmlApplicationContext("spring-lifecycle.xml");
User user = ioc.getBean(User.class);
System.out.println(user);
ioc.close();
}
后置处理器
bean的后置处理器会在生命周期的初始化前后添加额外的操作,需要实现BeanPostProcessor接口,且配置到IOC容器中,需要注意的是,bean后置处理器不是单独针对某一个bean生效,而是针对IOC容器中所有bean都会执行
生命周期的过程中的细节以及多例和单例的区别:
1.实例化
2.依赖注入
3.后置处理器的postProcessBeforeInitialization
4.初始化,需要通过bean的init-method属性
5.后置处理的postProcessAfterInitialization
6.IOC容器关闭时销毁 需要通过bean的destroy-method属性指定销毁的方法
注意:
若bean的作用域为单例时,生命周期的前三个步骤会在获取IOC容器时执行
若bean的作用域为多例时,生命周期的三个步骤会在回去bean时执行
FactoryBean
接口FactoryBean
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package org.springframework.beans.factory;
import org.springframework.lang.Nullable;
public interface FactoryBean<T> {
String OBJECT_TYPE_ATTRIBUTE = "factoryBeanObjectType";
@Nullable
T getObject() throws Exception;
@Nullable
Class<?> getObjectType();
default boolean isSingleton() {
return true;
}
}
public class UserFactoryBean implements FactoryBean<User> {
@Override
public User getObject() throws Exception {
return new User();
}
@Override
public Class<?> getObjectType() {
return User.class;
}
}
实现FatoryBean接口
配置FatoryBean
@Test
public void testFactoryBean(){
ApplicationContext ioc =new ClassPathXmlApplicationContext("spring-factory.xml");
User user = ioc.getBean(User.class);
System.out.println(user);
}
description:
- factoryBean是一个接口,需要创建一个类实现该接口
- 其中有三个方法:
- getObject():通过一个对象交给IOC容器管理
- getObjectType():设置所提供对象的类型
- isSingleton():所提供的对象是否单例
- 当把FactoryBean的实现类配置为bean时,会将当前类中getObject()所返回的对象那个交给IOC容器管理