依赖注入,自动装配,数据源,容器
依赖注入方式
- 思考:向一个类中传递数据的方式有几种?
- 普通方法(set方法)
- 构造方法
- 思考:依赖注入描述了再容器中建立bean与bean之间依赖关系的过程,如果bean运行需要的是数字或字符串呢?
- 引用类型
- 简单类型(基本数据类型与String)
- 依赖注入方法
- setter注入
- 简单类型
publicclassBookDaoImplimplementsBookDao {
privateintconnectionNumber;
publicvoidsetConnectionNumber(intconnectionNumber){
this.connectionNumber=connectionNumber;
}
}
- 配置中使用properry标签value属性注入简单类型数据
<beanid="bookDao"class="com.wangxh.dao.impl.BookDaoImpl">
<propertyname="connectionNumber"value="10"/>
</bean>
- 引用类型
- 构造器注入
- 简单类型
- 在bean中定义引用类型属性并提供可访问的构造方法
publicclassBookDaoImplimplemetsBookDao{
privateintconnectionNumber;
publicvoidsetConnectionNumber(intconnectionNumber){
this.connectionNumber=connectionNumber;
}
}
- 配置中使用constructor-arg标签value属性注入简单类型数据
<beanid="bookDao"class="com.wangxh.dao.impl.BookDaoImpl">
<constructor-argname="connectionNumber"value="10"/>
</bean>
- 配置中使用constructor-arg标签ref属性注入引用类型对象
<beanid="bookService"class="com.wangxh.service.impl.BookServiceImpl">
<constructor-argname="bookDao"ref="bookDao"/>
</bean>
<beanid = "bookDao"class="com.wangxh.dao.impl.BookDaoImpl"/>
- 引用类型
- 在bean中定义引用类型属性并提供可访问的构造方法
publicclassBookServiceImplimplementBookService{
privateBookDaobookDao;
publicBookServiceImpl(BookDaobookDao){
this.bookDao=bookDao;
}
}
- 配置中使用constructor-arg标签ref属性注入引用类型对象
<beanid="bookService"class="com.wangxh.service.impl.BookServiceImpl">
<constructor-argname="bookDao"ref="bookDao"/>
</bean>
<beanid = "bookDao"class="com.wangxh.dao.impl.BookDaoImpl"/>
- 构造器注入-参数适配(了解)
- 依赖注入方式选择
- 强制依赖使用构造器惊醒,使用setter注入有概率不进行注入导致null对象出现
- 可选依赖使用setter注入进行,灵活性强
- Spring框架倡导使用构造器,第三方框架内部大多数采用构造器注入的形式进行数据初始化,相对严谨
- 如果有必要可以两者同时使用,使用构造器注入完成强制依赖的注入,使用setter注入完成可选依赖的注入
- 实际开发过程还要根据实际情况分析,如果受控对象没有setter方法就必须使用构造器注入
- 自己开发的模块推荐使用setter注入
依赖自动装配
- IOC容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程称为自动装配
- 自动装配方式
- 按类型(常用)
- 按名称
- 按构造方法
- 不启用自动装配
- 配置中使用bean标签autowire属性设置自动装配的类型
<beanid="bookDao"class="com.wangxh.impl.BookDaoImpl"/>
<beanid="bookService"class="com.wangxh.service.impl.BookServiceImpl"autowire="byType"/>
- 自动装配用于引用类型依赖注入,不能对简单类型进行操作
- 使用按类型装配时(byType)必须保障容器中相同类型的bean唯一,推荐使用
- 使用按名称装配时(byName)必须保障容器中具有指定名称的bean,因变量名与配置耦合,不推荐使用
- 自动装配优先级低于setter注入与构造器注入,同时出现时自动装配配置失效
数据源对象管理
- Spring管理第三方资源
- DruidDataSource
- 导入druid坐标
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
- 配置数据源
<beanid="dataSource"class="com.alibaba.druid.pool.DruidDataSource">
<propertyname="driverClassName"value="com.mysql.jdbc.Driver"/>
<propertyname="url"value="jdbc:mysql://localhost::3306/spring_db"/>
<propertyname="username"value="root"/>
<propertyname="password"value="root"/>
</bean>
- ComboPooledDataSource
- 导入坐标
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
- 配置数据源
<beanid="dataSource"class="com.mchange.v2.c3p0.ComboPooledDataSource">
<propertyname="driverClass"value="com.mysql.jdbc.Driver"/>
<propertyname="jdbcUrl"value="jdbc:mysql://localhost::3306/spring_db"/>
<propertyname="user"value="root"/>
<propertyname="password"value="root"/>
<propertyname="maxPoolSize"value="10"/>
</bean>
加载properties
- 开启context命名空间
<?xmlversion="1.0" encoding="UTF-8"?>
<beansxmlns="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/contexthttp://www.springframework.org/schema/context/spring-context.xsd
">
这里修改的5个地方:1复制了2行的xmls修改成第3行那样,然后还有xsi里面的那个http复制了一份然后将里面的beans修改成了context
<!-- 1.开启context命名空间-->
<!-- 2.使用context空间加载properties文件-->
<context:property-placeholderlocation="jdbc.properties"/>
<!-- 3.使用属性占位符${}读取properties文件中的属性-->
<beanid="dataSource"class="com.alibaba.druid.pool.DruidDataSource">
<propertyname="driverClassName"value="${jdbc.driver}"/>
<propertyname="url"value="${jdbc.url}"/>
<propertyname="username"value="${jdbc.username}"/>
<propertyname="password"value="${jdbc.password}"/>
</bean>
5个小知识点
- 不加载系统属性
<context:property-placeholderlocation="jdbc.properties"system-properties-mode="NEVER"/>
- 加载多个properties文件
<context:property-placeholderlocation="jdbc.properties,msg.properties"/>
- 加载所有properties文件
<context:property-placeholderlocation="*.properties"/>
- 加载properties文件标准格式
<context:property-placeholderlocation="classpath:*.properties"/>
- 从类路径或jar包中搜索并加载properties文件
<context:property-placeholderlocation="classpath*:*.properties"/>
容器
- 创建容器
- 方式一:类路劲加载配置文件
ApplicationContextctx=newClassPathXmlApplicationContext("applicationContext.xml");
- 方式二:文件路径加载配置文件
ApplicationContextctx=newFileSystemXmlApplicationContext("D:\\applicationContext.xml");
//加载多个配置文件
ApplicationContextctx=newClassPathXmlApplicationContext("bean1.xml","bean2.xml");
- 获取bean
- 方式一:使用bean名称获取
BookDaobookDao= (BookDao) ctx.getBean("bookDao");
- 方式二:使用bean名称获取并指定类型
BookDaobookDao=ctx.getBean("bookDao",BookDao.class);
- 方式三:使用bean类型获取
BookDaobookDao= ctx.getBean(BookDao.class);