一、自动装配
1.1 自动装配的定义及基本使用
自动装配定义:在Spring xml配置文件中,其他的bean的属性的set方法和已有bean一致,则可以利用自动装配autowire
关键字进行赋值初始化,但一般不建议使用,会导致逻辑混乱前后产生关联,不利于开发使用,具有byName
和byType
两种类型,均不建议使用,按类型装配时必须类型唯一,示例如下:
<bean id="address" class="com.spring.learn.autowire.Address" p:city="北京" p:street="长安街"/>
<bean id="car" class="com.spring.learn.autowire.Car" p:type="红旗" p:years="1"/>
<!-- 手工装配 -->
<!--bean id="personAutoWire" class="com.spring.learn.autowire.Person" p:name="gxm" p:age="12" p:car-ref="car"-->
<!-- 自动装配,实际为根据已有bean名字或者类型装配,
该bean的id需要和被自动装配的类的属性名的```setXXX```中的XXX一致,
即和```属性set方法```配置一致,不常用 -->
<bean id="personAuto" class="com.spring.learn.autowire.Person" autowire="byName"/>
1.2 缺点总结
byName和byType只能选择一种,自动装配会装配Bean的所有熟悉。
二、继承Bean的配置,减少重复劳动
2.1 Spring的Bean继承基本概念
- Spring 允许继承 bean 的配置, 被继承的 bean 称为父 bean. 继承这个父 Bean 的 Bean 称为子 Bean
- 子 Bean 从父
Bean 中继承配置, 包括 Bean 的属性配置
- 子 Bean 也可以
覆盖从父 Bean 继承过来的配置
- 父Bean可以作为模版或者实例,如果只作为模版可以设置
abstract为true
,此时Spring将不会实例化该Bean,此时抽象Bean也无法被autowire给其他Bean
<!-- 只被用于被继承,作为一个模版Bean -->
<bean id="address" class="com.spring.learn.bean_relation.Address" p:city="北京" p:street="长安街" abstract="true"/>
- 并非父Bean的所有属性都会被继承比如
autowire abstract
- 若一个Bean的类未指定,则该Bean必须是一个抽象的Bean
- 使用
parent
来指定继承哪个Bean
<!-- 只被用于被继承,作为一个模版Bean 不指定类名时可以直接p命名但IDEA会报错,不会影响运行,但最好按照如下格式 -->
<bean id="address" abstract="true">
<property name="city" value="北京"/>
<property name="street" value="长安街"/>
</bean>
<!-- 先继承父类属性,再进行重写 -->
<bean id="address2" class="com.spring.learn.bean_relation.Address" p:city="重庆" p:street="南山街道" parent="address"/>
三、Bean之间的依赖关系
- 使用关键字
depens-on
依赖于其他类,被依赖的前置类必须在该Bean实例化前初始化,如果依赖多个Bean可用逗号隔开,由于抽象Bean无法被实例化,故依赖抽象Bean将会报错 - 示例:
<!-- 先继承父类属性,再进行重写 -->
<!-- 要求配置person时,必须有已经实例化Car,依赖前面的car ,-->
<bean id="address2" class="com.spring.learn.bean_relation.Address"
p:city="重庆"
p:street="南山街道"
parent="address"
depends-on="car,personAuto"
/>
<!-- 如果配置含有抽象Bean address depends-on="address",则会报错-->
四、Bean的作用域
- Spring启动时加载全部的可实例化Bean,故每次获取均为同一对象,默认情况返回的Bean均为单例,证明如下:
/**
* Created with IntelliJ IDEA.
* User: gxm
* Date: 2020/4/9
* Time: 9:37
* To change this template use File | Settings | File Templates.
* Description:
**/
package com.spring.learn.bean_relation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Main {
public static void main(String[] args) {
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("bean-relation.xml");
Person autoWire = applicationContext.getBean("personAuto", Person.class);
System.out.println(autoWire);
// 获取address1
Address address1 = applicationContext.getBean("address2", Address.class);
// Address{city='重庆', street='南山街道'}
System.out.println(address1);
// 获取address2
Address address2 = applicationContext.getBean("address2", Address.class);
// 修改address1的值
address1.setCity("安徽");
// Address{city='安徽', street='南山街道'}
System.out.println(address2);
}
}
/*输出如下
Person{name='null', age=0, car=Car{type='红旗', years=1}, address=null}
Address{city='重庆', street='南山街道'}
Address{city='安徽', street='南山街道'}
可以证明其返回的对象是一个单例的对象
*/
-
可以利用Bean元素的scope设置Bean的作用域,scope的类别及区别如下:
五、引用外部属性文件
5.0 为什么需要添加外部属性文件
开发过程中有许多其他的框架所需要的配置,不可能每个都在Spring xml的文件中配置,比如log4j2、jdbc、mybatis等等,此时即可将每个框架的配置单独取出,然后在xml中引用即可,可完成快速更改配置,降低修改成本。
5.1 添加context的属性文件
注意在IDEA中util有个包context会导致冲突,可以改名或者删掉util中的schema引用。
导入context schema:
xmlns:context="http://www.springframework.org/schema/context"
导入schema位置及解析文件路径,``schemaLocation中```添加如下:
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
配置xml文件如下
<!-- 传统方式 直接对c3p0进行配置 -->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="root"/>
<property name="password" value="123456789"/>
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://192.168.0.240:3306/MeasureAgent"/>
<property name="autoCommitOnClose" value="false"/>
<property name="minPoolSize" value="5"/>
<property name="maxPoolSize" value="10"/>
</bean>
<!-- 导入db.properties属性文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSourceDB" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${user}"/>
<property name="password" value="${password}"/>
<property name="jdbcUrl" value="${jdbcUrl}"/>
<property name="driverClass" value="${driverClass}"/>
</bean>
测试代码:
ComboPooledDataSource dataSource = applicationContext.getBean("dataSource", ComboPooledDataSource.class);
try {
Connection connection = dataSource.getConnection();
connection.setAutoCommit(false);
String sql="select packet_loss from icmp_data where id<?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,2);
ResultSet resultSet = preparedStatement.executeQuery();
connection.commit();
while (resultSet.next()){
System.out.println(resultSet.getMetaData().getColumnName(1)+":"+resultSet.getString("packet_loss"));
}
connection.close();
dataSource.close();
} catch (SQLException e) {
e.printStackTrace();
}
//输出如下
//packet_loss:0