1、自动注入的前提: Spring对象中的属性名(该属性指是对象属性)与ref="“值相同的情况可以使用自动注入。
2、自动注入的五种使用方式介绍:
自动注入是在或者标签中使用属性autowire=”“属性,
autowire=""属性有五个值:default、no、byName、byType、constructor
2.1、default值:如果在标签中使用,表示默认使用全局配置标签中的autowire=”"属性配置,
若全局配置中没有进行自动注入配置,则默认值为no,不使用自动注入
2.2、no:表示不使用自动注入。
2.3、byName:使用对象名进行自动注入;例如:在Spring容器中创建并管理对象,
在该类对象中有名称为fruiter的属性,在tree的标签中设置属性autowire=“byName”
则Spring会在Spring容器中查找名称为fruiter的对象自动注入到tree中。
2.4、byType:使用类型注入,依然使用byName中的例子,如果在tree的标签中配置自动注入属性,autowire="byType"值为byType,则会按照tree对象中的
属性的类型进行自动注入,spring会在Spring容器中查找类型为Fruiter的对象。
注:需要注意的是使用byType自动注入时,在Spring容器中一个类型的对象只能存在一个,及Fruiter类型的对象有且只能有一个被Spring容器
管理,即只能这一个,不能再重复创建该对象。
2.5、constructor:构造方法注入,例如tree使用构造方法自动注入,需要在tree类对象中存在一个有参构造方法,参数的名称需要与注入的对象名称一致,如tree要
实现fruiter注入,构造方法的参数就应该是Tree(Fruiter fruiter)。
3、自动注入与属性文件一起使用的注意事项:
3.1、属性文件加载介绍:
<context:property-placeholder location="classpath:db.properties,classpath:data.properties"></context:property-placeholder>
加载属性文件(使用属性文件实现软编码):属性文件可以同时加载多个,
格式如下:location=“classpath:db.properties,classpath:data.properties”;
属性文件读取成功,属性文件中的信息会保存在Spring容器中,在Spring容器管理的任意位置都可以使用${key}的方式取出属性文件中的数据。
例如下边的数据库连接信息。
3.2、自动注入与属性文件使用的注意事项:
注意事项(很重要): 使用自动注入需要注意的是,自动注入在Spring容器中的优先级较高,要谨慎使用,特别要注意的是在使用属性文件配置数据库连接信息,
创建sqlSessionFactory时不要使用自动注入,如果使用自动注入,因为自动注入的优先级较高,在Spring配置文件加载时会先进行注入,
然后进行属性文件加载,当自动注入实例化数据库连接对象dataSource时,属性文件还没有加载,无法使用${key}获取数据库连接信息,因此实例化
dataSource时会报异常。
4、自动注入、属性文件的实际使用情况:
4.1、Spring配置文件–ApplicationContext.xml:
<?xml version="1.0" encoding="UTF-8"?>
<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"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd
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-4.0.xsd">
<context:property-placeholder location="classpath:db.properties,classpath:data.properties"></context:property-placeholder>
<!--注解开发扫描-->
<context:component-scan base-package="Tree"></context:component-scan>
<bean id="fruiter" class="Tree.Fruiter"></bean>
<bean id="tree" class="Tree.Tree" autowire="byName"></bean>
<!--数据库连接信息-->
<!-- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${dataBase.driverClassName}"></property>
<property name="url" value="${dataBase.url}"></property>
<property name="username" value="${dataBase.userName}"></property>
<property name="password" value="${dataBase.passWord}"></property>
</bean>-->
<!--此处工厂类对象的id不要使用SqlSessionFactory-->
<!--<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean" autowire="byName">-->
<!--此处SqlSessionFactoryBean对象中有和以上数据库对象相同名称(dataSource)的属性,因此可以使用byName自动注入-->
<!--<property name="dataSource" ref="dataSource"></property>-->
<!--</bean>-->
<!--映射文件扫描-->
<!-- <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value=""></property>-->
<!--如果使用的是属性文件创建的数据库连接,此处不能使用自动注入,如果使用自动注入,
自动注入会根据sqlSessionFactory名在Spring容器中查找同名对象,然后一直查找到dataSource对象,
此时属性文件还没加载,实例化该对象会报异常。
为防止出现此种错误,因此在使用自动加载时,使用MapperScannerConfigurer类的属性sqlSessionFactoryBeanName配置工厂类,
避开自动注入,避开可能产生的问题(<property name="sqlSessionFactoryBeanName" value="factory"></property>)。
-->
<!--<property name="sqlSessionFactory" ref="factory"></property>-->
<!-- <property name="sqlSessionFactoryBeanName" value="factory"></property>
</bean>-->
</beans>
**注意事项:**为防止自动注入与属性文件冲突,产生错误,因此在映射文件扫描对象使用了sqlSessionFactoryBeanName属性引入工厂类方法。
4.2、属性文件db.properties、data.properties:
db.properties:
dataBase.driverClassName =com.mysql.jdbc.Driver
dataBase.url=jdbc:mysql://localhost:3306/mybatis
dataBase.userName=root
dataBase.passWord=root
data.properties:
tree.name=橘子树
tree.age=12
tree.height=4.5
4.3、Frutier.java:
package Tree;
import org.springframework.beans.factory.annotation.Value;
public class Fruiter {
/**
* 使用@Value(""):根据属性文件中的key获取使用属性文件中的数据,此处也要使用${key}的格式,格式不能省略;
* 变量名称与属性文件的key可以不同名;
* 类型可以进行自动转换;例如 int 类型的treeAge 获取的数据-- @Value("${tree.age}")
int treeAge;
*/
@Value("${tree.name}")
private String name;
@Value("${tree.age}")
private int treeAge;
@Value("${tree.height}")
private Double treeHeight;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getTreeAge() {
return treeAge;
}
public void setTreeAge(int treeAge) {
this.treeAge = treeAge;
}
public Double getTreeHeight() {
return treeHeight;
}
public void setTreeHeight(Double treeHeight) {
this.treeHeight = treeHeight;
}
@Override
public String toString() {
return "Fruiter{" +
"name='" + name + '\'' +
", treeAge=" + treeAge +
", treeHeight=" + treeHeight +
'}';
}
}
4.4、Tree.java:
package Tree;
public class Tree {
private Fruiter fruiter;
public Fruiter getFruiter() {
return fruiter;
}
public void setFruiter(Fruiter fruiter) {
this.fruiter = fruiter;
}
public Tree() {}
public Tree(Fruiter fruiter) {
this.fruiter = fruiter;
}
public void treeInfo(){
System.out.println("这是一棵"+fruiter.getName()+",树龄是"+fruiter.getTreeAge()+",高度是:"+fruiter.getTreeHeight()+"米(m)");
}
}
注:根据Tree.java、Frutier.java类使用byName实现自动注入。
4.5、测试类:
import Tree.Tree;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestDemo01 {
@Test
public void Test01(){
ApplicationContext ac = new ClassPathXmlApplicationContext("ApplicationContext.xml");
Tree tree= ac.getBean("tree", Tree.class);
tree.treeInfo();
/**
* 运行结果:
* 这是一棵橘子树,树龄是12,高度是:4.5米(m)
*/
}
}