Spring----(1)Spring的配置

Sring配置

  • 1 Spring相关概念
    • 1.1 Spring Framework系统架构
    • 1.2 Spring Framework 学习线路
    • 1.3 Spring Framework核心概念
  • 2 入门案例
    • 2.1 IoC入门案例
    • 2.2 DI入门案例
  • 3 核心容器Bean
    • 3.1 bean配置
      • 3.1.1 bean基础配置
      • 3.1.2 bean的别名配置
      • 3.1.3 bean的作用范围
    • 3.2 bean实例化
      • 3.2.1 实例化bean的三种方式1----构造方法(常用)
      • 3.2.2 实例化bean的三种方式2----静态工厂(了解)
      • 3.2.3 实例化bean的三种方式3----实例工厂(了解)与FactoryBean(常用)
      • 3.2.4 实例化bean的第四种方式----FactoryBean(常用)
    • 3.3 bean生命周期
  • 4 依赖注入
    • 4.1 setter注入
      • 4.1.1 setter注入----引用类型
      • 4.1.2 setter注入----简单类型
    • 4.2 构造器注入
      • 4.2.1 构造器注入----引用类型
      • 4.2.2 构造器注入----简单类型
      • 4.2.3 构造器注入----参数适配(了解)
    • 4.3 依赖自动装配
    • 4.4 集合注入
  • 5 案例----数据源对象的管理(了解)
    • 5.1 实现Driud管理
    • 5.2 实现C3P0管理
    • 5.3 加载porperties文件
  • 6 容器
  • 7 核心容器总结
    • 7.1 容器相关
    • 7.2 bean相关
    • 7.3 依赖注入相关

1 Spring相关概念

1.1 Spring Framework系统架构

在这里插入图片描述

  • 核心层
    Core Container:核心容器
  • AOP层:
    AOP:面向切面编程。它依赖核心层容器,目的是在不改变原有代码的前提下对其进行功能增强
    Aspects:AOP思想实现
  • Web层: web开发
  • 数据层:
    Data Access:数据访问
    Data Integration:数据集成,
    Transactions:事务,Spring中事务管理是Spring AOP的一个具体实现
  • Test层: 单元测试与集成测试

1.2 Spring Framework 学习线路

在这里插入图片描述

1.3 Spring Framework核心概念

业务层需要调用数据层的方法,需要在业务层new数据层的对象,如果数据层的实现类发生变化,那么业务层的代码也需要跟着改变,发生变更后,都需要进行编译打包和重部署,所以,编写的过程中存在的问题是:耦合度高
解决方案:不使用new产生对象,转换为由外部提供对象。即Ioc

  • IoC ( Inversion of Control ):控制反转
    使用对象时, 由主动new产生对象转换为由外部提供对象,此过程中对象创建控制权由程序转移到外部,此思想称为控制反转
  • Spring技术对IoC思想进行了实现
    Spring提供了一个容器, 称为IoC容器,用来充当IoC思想中的心外部
    IoC容器负责对象的创建、 初始化等-系列工作, 被创建或被管理的对象在 IoC容器中统称为Bean
  • DI ( Dependency Injection ):依赖注入
    在容器中建立bean与bean之间的依赖关系的整个过程,称为依赖注入

2 入门案例

2.1 IoC入门案例

  • 思路分析
    在这里插入图片描述
  • 代码实现
  1. 导入spring依赖坐标spring-context
        <dependency><groupId>org.springframeworkgroupId><artifactId>spring-contextartifactId><version>5.2.10.RELEASEversion>dependency>
  1. 定义Spring管理的类(接口)
public interface BookService {void save();
}
public class BookServiceImpl implements BookService {private BookDao bookDao = new BookDaoImpl();public void save(){System.out.println("book service save...");bookDao.save();}
}
  1. 创建Spring配置文件,配置对应类作为Spring管理的bean
    bean标签表示配置bean,id属性表示给bean起名字,class属性表示给bean定义类型

applicationContext.xml:


<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="bookDao" class="com.zs.dao.impl.BookDaoImpl">bean><bean id="bookService" class="com.zs.service.impl.BookServiceImpl">bean>
beans>
  1. 初始化IoC容器(Spring核心容器/Spring容器),通过容器获取bean
public class App2 {public static void main(String[] args) {//获取IOC容器ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");//获取BeanBookService bookService = (BookService) ctx.getBean("bookService");bookService.save();}
}

Spring的IoC入门案例已经完成。但是在BookServiceImpl的类中依然存在BookDaoImpl对象的new操作,它们之间的耦合度还是比较高,这就需要用到下面的DI:依赖注入

2.2 DI入门案例

  • 思路分析
    在这里插入图片描述
  • 代码实现:
  1. 删除用new的形式创建的代码
public class BookServiceImpl implements BookService {//删除业务层中使用new的方式创建的dao对象private BookDao bookDao;public void save(){System.out.println("book service save...");bookDao.save();}
}
  1. 提供依赖对象对应的setter方法
public class BookServiceImpl implements BookService {//删除业务层中使用new的方式创建的dao对象private BookDao bookDao;public void save(){System.out.println("book service save...");bookDao.save();}//提供对应的set方法public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}
}
  1. 配置service与dao之间的关系
    property标签表示配置当前bean的属性
    name属性表示配置哪一个具体的属性
    ref属性表示参照那个bean

<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="bookDao" class="com.zs.dao.impl.BookDaoImpl"/><bean id="bookService" class="com.zs.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/>bean>
beans>

3 核心容器Bean

3.1 bean配置

3.1.1 bean基础配置

在这里插入图片描述

3.1.2 bean的别名配置

在这里插入图片描述

注意:
在这里插入图片描述

3.1.3 bean的作用范围

在这里插入图片描述

  1. 为什么bean默认为单例 ?
    bean为单例的意思是在Spring的IOC容器中只会有该类的一个对象
    bean对象只有一个就避免了对象的频繁创建与销毁,达到了bean对象的复用,性能高

  2. 适合交给容器进行管理的bean:表现层对象;业务层对象;数据层对象;工具对象

  3. 不适合交给容器进行管理的bean:封装实体的域对象

3.2 bean实例化

3.2.1 实例化bean的三种方式1----构造方法(常用)

  • bean的本质是对象,创建bean使用构造方法完成
  • 提供可访问的构造方法
public class BookDaoImpl implements BookDao {public BookDaoImpl() {System.out.println("book dao constructor is running ....");}public void save() {System.out.println("book dao save ...");}}
  • 配置
    <bean id="bookDao" class="com.zs.dao.impl.BookDaoImpl"/>
  • 无参方法如果不存在,将抛出异常BeanCreationException

3.2.2 实例化bean的三种方式2----静态工厂(了解)

  • 静态工厂
public class OrderDaoFactory {public static OrderDao getOrderDao(){return new OrderDaoImpl();}
}
  • 配置
<bean id="orderDao" class="com.itheima.factory.OrderDaoFactory" factory-method="getOrderDao"/>

这种方式一般是用来兼容早期的一些老系统,所以了解为主。

3.2.3 实例化bean的三种方式3----实例工厂(了解)与FactoryBean(常用)

  • 实例工厂
public class UserDaoFactory {public UserDao getUserDao(){return new UserDaoImpl();}
}
  • 配置

<bean id="userFactory" class="com.itheima.factory.UserDaoFactory"/>

<bean id="userDao" factory-method="getUserDao" factory-bean="userFactory"/>
  • 运行测试结果
public class AppForInstanceUser {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");UserDao userDao = (UserDao) ctx.getBean("userDao");userDao.save();}
}

3.2.4 实例化bean的第四种方式----FactoryBean(常用)

  • FactoryBean
public class UserDaoFactoryBean implements FactoryBean<UserDao> {//代替原始实例工厂中创建对象的方法public UserDao getObject() throws Exception {//返回dao实现类的实例return new UserDaoImpl();}//返回所创建类的Class对象public Class<?> getObjectType() {//返回dao接口的字节码return UserDao.class;}
}
  • 配置
<bean id="userDao" class="com.itheima.factory.UserDaoFactoryBean"/>
  • FactoryBean设置单例、非单例:
    将isSingleton()方法进行重写,修改返回为false(默认为true单例)
public class UserDaoFactoryBean implements FactoryBean<UserDao> {//代替原始实例工厂中创建对象的方法public UserDao getObject() throws Exception {return new UserDaoImpl();}public Class<?> getObjectType() {return UserDao.class;}public boolean isSingleton() {return false;}
}

3.3 bean生命周期

  • 生命周期:从创建到消亡的完整过程,例如人从出生到死亡的整个过程就是一个生命周期

  • bean生命周期:bean对象从创建到销毁的整体过程
    在这里插入图片描述

  • bean生命周期控制:在bean创建后到销毁前做一些事情。

  • 生命周期控制方式一:
    提供生命周期控制方法

public class BookDaoImpl implements BookDao {public void save() {System.out.println("book dao save ...");}public void init(){System.out.println("init...");}public void destroy(){System.out.println("destroy...");}
}
  • 配置生命周期控制方法
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl" init-method="init" destroy-method="destory"/>
  • 运行结果:
    在这里插入图片描述

init方法执行了,但是destroy方法却未执行。原因:Spring的IOC容器是运行在JVM中,运行main方法后,JVM启动,Spring加载配置文件生成IOC容器,从容器获取bean对象,然后调方法执行;main方法执行完后,JVM退出,这个时候IOC容器中的bean还没有来得及销毁就已经结束了;所以没有调用对应的destroy方法。
在这里插入图片描述

  • 解决方法一:使用close()方法在虚拟机退出之前将容器关闭(比较暴力)
    由于ApplicationContext中没有close方法,需要将ApplicationContext更换成ClassPathXmlApplicationContext,再调用ctx的close()方法
public class App2 {public static void main(String[] args) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();ctx.close();}
}

在这里插入图片描述

  • 解决方法二:设置关闭钩子,注册钩子关闭容器
    容器启动后加了个标记,让JVM在退出之前回调此函数来关闭容器
public class App2 {public static void main(String[] args) {ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");ctx.registerShutdownHook();BookDao bookDao = (BookDao) ctx.getBean("bookDao");bookDao.save();//ctx.close();}
}

两种方式的区别::
close()是在调用的时候强制关闭,如果后面还有IOC的相关代码会报错
registerShutdownHook()是在JVM退出前调用关闭,可以放在任何位置
当然两种方法我们都不用写,我们最终做的是web应用,关闭容器应该伴随Tomcat关闭一块的

  • 生命周期控制方式二:
    接口控制(了解)
public class BookServiceImpl implements BookService, InitializingBean, DisposableBean {private BookDao bookDao;public void save(){System.out.println("book service save...");bookDao.save();}//提供对应的set方法public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}@Overridepublic void destroy() throws Exception {System.out.println("service destroy...");}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("service init...");}
}

在这里插入图片描述

  • 小细节
    对于InitializingBean接口中的afterPropertiesSet方法,即属性设置之后
    对于BookServiceImpl来说,bookDao是它的一个属性,setBookDao方法是Spring的IOC容器为其注入属性的方法
    试验:
public void setBookDao(BookDao bookDao) {System.out.println("set...");this.bookDao = bookDao;}

结果:
在这里插入图片描述

  • 小结
    在这里插入图片描述

4 依赖注入

  • 思考
    在这里插入图片描述
  • 依赖注入方式
    setter注入:简单类型和引用类型 .
    构造器注入:简单类型和引用类型

4.1 setter注入

4.1.1 setter注入----引用类型

  • 在bean中定义引用类型属性并提供可访问的set方法
public class BookServiceImpl implements BookService {private BookDao bookDao;public void setBookDao(BookDao bookDao) {this.bookDao = bookDao;}
}
  • 配置中使用property标签ref属性注入引用类型对象
<bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/>
bean><bean id="bookDao" class="com.itheima.dao.imipl.BookDaoImpl"/>

4.1.2 setter注入----简单类型

  • 在bean中定义简单类型属性并提供可访问的set方法
public class BookDaoImpl implements BookDao {private String databaseName;private int connectionNum;public void setConnectionNum(int connectionNum) {this.connectionNum = connectionNum;}public void setDatabaseName(String databaseName) {this.databaseName = databaseName;}public void save() {System.out.println("book dao save ..."+databaseName+","+connectionNum);}
}
  • 配置中使用property标签value属性注入简单类型数据

<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="bookDao" class="com.itheima.dao.impl.BookDaoImpl"><property name="databaseName" value="mysql"/><property name="connectionNum" value="10"/>bean><bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><property name="bookDao" ref="bookDao"/><property name="userDao" ref="userDao"/>bean>
beans>

4.2 构造器注入

4.2.1 构造器注入----引用类型

  • 在bean中定义引用类型属性并提供可访问的构造方法
public class BookServiceImpl implements BookService{private BookDao bookDao;public BookServiceImpl(BookDao bookDao) {this.bookDao = bookDao;}public void save() {System.out.println("book service save ...");bookDao.save();}
}
  • 配置中使用constructor-arg标签ref属性注入引用类型对象
    name属性的值为构造函数中构造方法形参的参数名

<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="bookDao" class="com.itheima.dao.impl.BookDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><constructor-arg name="bookDao" ref="bookDao"/>bean>
beans>

4.2.2 构造器注入----简单类型

public class BookDaoImpl implements BookDao {private String databaseName;private int connectionNum;public BookDaoImpl(String databaseName, int connectionNum) {this.databaseName = databaseName;this.connectionNum = connectionNum;}public void save() {System.out.println("book dao save ..."+databaseName+","+connectionNum);}
}
  • 在bean中定义简单类型属性并提供可访问的set方法
public class BookDaoImpl implements BookDao {private String databaseName;private int connectionNum;public BookDaoImpl(String databaseName, int connectionNum) {this.databaseName = databaseName;this.connectionNum = connectionNum;}public void save() {System.out.println("book dao save ..."+databaseName+","+connectionNum);}
}
  • 配置中使用constructor-arg标签value属性注入简单类型数据

<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="bookDao" class="com.itheima.dao.impl.BookDaoImpl"><constructor-arg name="databaseName" value="mysql"/><constructor-arg name="connectionNum" value="666"/>bean><bean id="userDao" class="com.itheima.dao.impl.UserDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl"><constructor-arg name="bookDao" ref="bookDao"/><constructor-arg name="userDao" ref="userDao"/>bean>
beans>

当构造函数中方法的参数名发生变化后,配置文件中的name属性也需要跟着变,存在高耦合的问题
解决方案(有缺点,了解即可):参数名发生变化的情况并不多,并且解决方案有缺点类型限制或顺序限制

4.2.3 构造器注入----参数适配(了解)

  • 配置中使用constructor-arg标签type属性设置按形参类型注入
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"><constructor-arg type="int" value="10"/><constructor-arg type="java.lang.String" value="mysql"/>
bean>
  • 配置中使用constructor-arg标签index属性设置按形参位置注入
<bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"><constructor-arg index="1" value="100"/><constructor-arg index="0" value="mysql"/>
bean>

依赖注入方式选择:
在这里插入图片描述

4.3 依赖自动装配

  • IoC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
  • 自动装配方式:按类型(常用);按名称;按构造方法;不启用自动装配
  • 按类型注入:

<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 class="com.itheima.dao.impl.BookDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byType"/>beans>

需要注入属性的类中对应属性的setter方法不能省略
被注入的对象必须要被Spring的IOC容器管理
按类型注入必须保障容器中相同类型的bean唯一,否则会报NoUniqueBeanDefinitionException

  • 按名称注入

<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 class="com.itheima.dao.impl.BookDaoImpl"/><bean id="bookService" class="com.itheima.service.impl.BookServiceImpl" autowire="byName"/>beans>

4.4 集合注入

  • BookDaoImpl:
public class BookDaoImpl implements BookDao {private int[] array;private List<String> list;private Set<String> set;private Map<String,String> map;private Properties properties;public void save() {System.out.println("book dao save ...");System.out.println("遍历数组:" + Arrays.toString(array));System.out.println("遍历List" + list);System.out.println("遍历Set" + set);System.out.println("遍历Map" + map);System.out.println("遍历Properties" + properties);}//setter方法
}
  • 集合注入:

<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="bookDao" class="com.zs.dao.impl.BookDaoImpl"><property name="array"><array><value>100value><value>200value><value>300value>array>property><property name="list"><list><value>itcastvalue><value>itheimavalue><value>boxueguvalue><value>chuanzhihuivalue>list>property><property name="set"><set><value>itcastvalue><value>itheimavalue><value>boxueguvalue><value>boxueguvalue>set>property><property name="map"><map><entry key="country" value="china"/><entry key="province" value="henan"/><entry key="city" value="kaifeng"/>map>property><property name="properties"><props><prop key="country">chinaprop><prop key="province">henanprop><prop key="city">kaifengprop>props>property>bean>
beans>

5 案例----数据源对象的管理(了解)

了解即可,开发中更多用注解开发。

5.1 实现Driud管理

  1. 导入依赖
<dependencies><dependency><groupId>org.springframeworkgroupId><artifactId>spring-contextartifactId><version>5.2.10.RELEASEversion>dependency><dependency><groupId>com.alibabagroupId><artifactId>druidartifactId><version>1.1.16version>dependency>dependencies>
  1. 配置数据源对象作为spring管理的bean
    Ctrl+b跟进到DruidDataSource类,按Ctrl+f12查看发现适合用setter方法注入

<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"><property name="driverClassName" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql://localhost:3306/spring_db"/><property name="username" value="root"/><property name="password" value="root"/>bean>
beans>
  1. 从IOC容器中获取对应的bean对象
public class App {public static void main(String[] args) {ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");DataSource dataSource = (DataSource) ctx.getBean("dataSource");System.out.println(dataSource);}
}

运行一下,测试结果:
在这里插入图片描述

5.2 实现C3P0管理

  1. 导入坐标,从mvn的仓库中进行搜索

<dependency><groupId>c3p0groupId><artifactId>c3p0artifactId><version>0.9.1.2version>
dependency>
  1. 配置数据源对象作为spring管理的bean
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"><property name="driverClass" value="com.mysql.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/spring_db"/><property name="user" value="root"/><property name="password" value="root"/><property name="maxPoolSize" value="1000"/>
bean>
  1. 运行程序
    在这里插入图片描述
    问题:报的错为ClassNotFoundException,没有找到com.mysql.jdbc.Driver类。
    错误原因:缺少mysql的驱动包
    解决:在pom.xml把驱动包导入
<dependency><groupId>mysqlgroupId><artifactId>mysql-connector-javaartifactId><version>5.1.16version>
dependency>

运行:
在这里插入图片描述

总结:

  1. 数据连接池在配置属性的时候,除了可以注入数据库连接四要素外还可以配置很多其他的属性,按需配置
  2. Druid和C3P0在没有导入mysql驱动包的前提下,一个没报错一个报错,说明Druid在初始化的时候没有去加载驱动,而C3P0刚好相反
  3. Druid程序运行虽然没有报错,但是当调用DruidDataSource的getConnection()方法获取连接的时候,也会报找不到驱动类的错误

5.3 加载porperties文件

问题:上面的案例中,数据库的配置写在Spring的配置文件中不利于后期维护
解决:将配置信息写在porperties文件中,使用spring加载porperties文件
实现: 在Spring的配置文件中加载properties文件;使用加载到的值实现属性注入

具体实现:

  1. resources下创建一个jdbc.properties文件,并添加对应的属性键值对
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///spring_db?ssl=false
jdbc.username=root
jdbc.password=root
  1. 开启context命名空间
    在这里插入图片描述
  2. 使用context空间加载porperties文件
<context:property-placeholder location="jdbc.properties"/>
  1. 使用属性占位符${}读取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>

设置系统属性模式:
在properties文件中配置键值对的时候,如果key设置为username值为root666,在applicationContext.xml注入该属性


<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="jdbc.properties"/><bean id="bookDao" class="com.itheima.dao.impl.BookDaoImpl"><property name="name" value="${username}"/>bean>
beans>

运行程序输出的结果不是root666而是电脑的用户名
原因:标签会加载系统的环境变量,而且环境变量的值优先度更高
解决:设置系统属性模式为NEVER,表示不加载系统属性;也可以避免key设置为username


<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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
beans>

加载多个properties配置文件:
在这里插入图片描述

6 容器

  1. 容器的两种创建方式

方式一:类路径下的XML配置文件(推荐使用)

ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");

方式二:文件系统下的XML配置文件(耦合度较高,不推荐使用)

ApplicationContext ctx = new FileSystemXmlApplicationContext("D:\\workspace\\spring\\spring_10_container\\src\\main\\resources\\applicationContext.xml");
  1. Bean的三种获取方式

方式一:根据id获取

BookDao bookDao = (BookDao) ctx.getBean("bookDao");

方式二:

BookDao bookDao = ctx.getBean("bookDao"BookDao.class);

解决类型强转问题但是参数又多加了一个,相对来说没有简化多少

方式三:

BookDao bookDao = ctx.getBean(BookDao.class);

类似前面所学习的依赖注入中的按类型注入。必须要确保IOC容器中该类型对应的bean对象只能有一个

  1. 容器类层次结构图
    在这里插入图片描述
    ClassPathXmlApplicationContext实现ApplicationContext,ApplicationContext继承BeanFactory

  2. BeanFactory创建容器(了解)

public class AppForBeanFactory {public static void main(String[] args) {Resource resources = new ClassPathResource("applicationContext.xml");BeanFactory bf = new XmlBeanFactory(resources);BookDao bookDao = bf.getBean(BookDao.class);bookDao.save();}
}
  1. BeanFactory和ApplicationContext的区别
    BeanFactory是延迟加载,只有在获取bean对象的时候才会去创建
    ApplicationContext是立即加载,容器加载的时候就会创建bean对象
    ApplicationContext要想成为延迟加载,需要在bean中配置lazy-init=true

7 核心容器总结

7.1 容器相关

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

7.2 bean相关

在这里插入图片描述

7.3 依赖注入相关

在这里插入图片描述
参考文章


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部