依赖注入方式
- 思考:向一个类中传递数据的方式有几种?
- 普通方法(set方法)
- 构造方法
- 思考:依赖注入描述了在容器种建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢?
- 引用类型
- 简单类型(基本数据类型与String)
- 依赖注入方式
- setter注入
- 简单类型
- 引用类型
- 构造器注入
- 简单类型
- 引用类型
- setter注入
setter注入
<?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">
<bean id="bookDaoImpl" class="com.xhj.dao.impl.BookDaoImpl"/>
<bean id="userDaoImpl" class="com.xhj.dao.impl.UserDaoImpl"/>
<bean id="bookServiceImpl" class="com.xhj.service.impl.BookServiceImpl">
<property name="bookDao" ref="bookDaoImpl"/>
<property name="userDao" ref="userDaoImpl"/>
<property name="name" value="xxx"/>
</bean>
</beans>
private BookDao bookDao;
private UserDao userDao;
private String name;
public void setName(String name) {
this.name = name;
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
public void setUserDao(UserDao userDao) {
this.userDao = userDao;
}
构造器注入
-
在bean中定义引用类型属性并提供可访问的构造方法
public class AppServiceImpl implements AppService { private BookDao bookDao; private UserDao userDao; public AppServiceImpl(BookDao bookDao, UserDao userDao) { this.bookDao = bookDao; this.userDao = userDao; } @Override public void save() { bookDao.save(); userDao.save(); System.out.println("app service save"); } }
-
配置中使用constructor-arg标签ref属性注入引用类型对象
<bean id="bookDao" class="com.xhj.dao.impl.BookDaoImpl"/> <bean id="userDao" class="com.xhj.dao.impl.UserDaoImpl"/> <bean id="appService" class="com.xhj.service.impl.AppServiceImpl"> <constructor-arg name="bookDao" ref="bookDao"/> <constructor-arg name="userDao" ref="userDao"/> </bean>
依赖注入方式选择
- 强制依赖使用构造器进行,使用setter注入有概率不进行注入导致null对象出现
- 可选依赖使用setter注入进行,灵活性强
- Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
- 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
- 实际开发过程中还要根据实际情况分析,如果受控制对象没有提供setter方法就必须使用构造器注入
- 自己开发的模块推荐使用setter注入
依赖自动装配
- Ioc容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
- 自动装配的方式
- 按类型(常用)
- 按名称
- 按构造方法
- 不启用自动装配
配置中使用bean标签autoware属性设置自动装配的类型
<bean id="bookDao" class="com.xhj.dao.impl.BookDaoImpl"/> <bean id="bookService" class="com.xhj.service.impl.BookServiceImpl" autowire="byType"/>
依赖自动装配特征
- 自动装配用于引用类型依赖注入,不能对简单类型操作
- 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造注入,同时出现时配置失效
集合注入
数组
List
Set
Map
Properties
<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.xhj.dao.impl.BookDaoImpl">
<property name="array">
<array>
<value>1</value>
<value>2</value>
<value>3</value>
<value>4</value>
</array>
</property>
<property name="list">
<list>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
<value>ddd</value>
</list>
</property>
<property name="set">
<set>
<value>aaa</value>
<value>aaa</value>
<value>aaa</value>
<value>aaa</value>
</set>
</property>
<property name="map">
<map>
<entry key="name" value="xxx"/>
<entry key="old" value="18"/>
<entry key="sex" value="boy"/>
</map>
</property>
<property name="properties">
<props>
<prop key="name">xxx</prop>
<prop key="old">18</prop>
<prop key="sex">boy</prop>
</props>
</property>
</bean>
</beans>
案例:数据源对象管理
<?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">
<!--管理DruidDataSource对象-->
<bean class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3305/mybatisDemo"/>
<property name="username" value="root"/>
<property name="password" value="00000"/>
</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:3305/mybatisDemo"/>
<property name="user" value="root"/>
<property name="password" value="00000"/>
</bean>
</beans>
加载properties文件
-
开启context命名空间
<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 ">
-
使用context命名空间,加载指定peoperties文件
<context:property-placeholder location="jdbc.properties"/>
-
使用${}读取加载的属性值
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"> <property name="driverClassName" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </bean>
不加载系统属性
<context:property-placeholder location="jdbc.properties" system-properties-mode="NEVER"/>
加载多个properties文件
<contxt:property-placeholder location="jdbc.properties,jdbc2.properties"/>
加载所有properties文件
<context:property-placeholder location="*.properties"/>
加载properties文件标准格式
<context:property-placeholder location="classpath:*.properties"/>
从类路径或jar包中搜索并加载properties文件
<context:property-placeholder location="classpath*:*.properties"/>
容器
容器创建
-
方式一:类路径加载配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
-
方式二:文件路径加载配置文件
ApplicationContext context = new FileSystemApplicationContext("D:\\applicationContext.xml");
-
方式三:加载多个配置文件
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml","applicationContext2.xml");
获取bean
-
方式一:使用bean名称获取
DataSource dataSource = (DataSource)context.getBean("dataSource");
-
方式二:使用bean名称获取并指定类型
DataSource dataSource = context.getBean("dataSource", DataSource.class);
-
方式三:使用bean类型获取
DataSource dataSource = context.getBean(DataSource.class);
容器类层次结构图
BeanFactory初始化(了解)
-
类路径加载配置文件
Resource resource=new ClassPathResource("applicationContext.xml"); BeanFactory beanFactory=new XmlBeanFactory(resource);
-
BeanFactory创建完毕后,所有的bean均为延迟加载
核心容器总结
- BeanFactory是Ioc容器的顶层接口,初始化BeanFactory对象时,加载的bean延迟加载
- ApplicationContext接口是Spring容器的核心接口,初始化时bean立即加载
- ApplicationContext接口提供基础的bean操作相关方法,通过其他接口扩展其功能
- ApplicationContext接口常用初始化类
- ClassPathApplicationContext
- FileSystemXmlApplicationContext