Spring框架依赖注入(Dependency Injection)详解
简单来说,依赖注入就是给属性赋值,而这里的属性可以是具体类里面简单数据类型的属性以及引用类型的属性。
- 基于XML配置文件的依赖注入
(1)简单类型
简单类型指的是int、String等这些数据类型。
<!--基于XML配置文件的简单类型DI-->
<bean id="需要创建对象名称" class="类的全限定名称">
<!--spring自动调用set方法,不需要开发人员自己设置,具体类必须有set方法-->
<!--注意:属性名称需要和具体类中属性的名称一致,若不一致,则无法赋值-->
<property name="属性名称" value="属性值"/>
<property name="属性名称" value="属性值"/>
</bean>
(2)引用类型
引用类型依赖注入的是给对象赋值
<bean id="对象名称" class="类的全限定名称">
<property name="属性名称" value="属性值"/>
<property name="属性名称" value="属性值"/>
</bean>
<bean id="对象名称" class="类的全限定名称">
<property name="属性名称" value="属性值"/>
<property name="属性名称" value="属性值"/>
<!--这里是给引用类型赋值,ref中的值必须是bean标签的id值,因为这个id值唯一-->
<property name="属性名称" ref="对象名称"/>
</bean>
而spring框架为了方便引用类型赋值,提供了自动注入(仅限于引用类型,简单类型不能使用),使用规则是在bean标签后面设置属性autowire,而autowire的属性值有两个,一个是byName(根据对象名称),一个是byType(根据对象类型)。
第一种byName
<!-- 第一种byName-->
<bean id="对象名称" class="类的全限定名称" autowire="byName">
<property name="属性名称" value="属性值"/>
<property name="属性名称" value="属性值"/>
</bean>
<!-- 关键是java类的属性名称要和bean标签里面的id名称一致,要不然赋值不了-->
<bean id="对象名称" class="全限定名称">
<property name="属性名称" value="属性值"/>
<property name="属性名称" value="属性值"/>
</bean>
第二种byType
<!-- 第二种byType-->
<bean id="对象名称" class="类的全限定名称" autowire="byType">
<property name="属性名称" value="属性值"/>
<property name="属性名称" value="属性值"/>
</bean>
<!-- 关键是java类的属性的类型要和bean标签创建对象的类型一致或者存在继承关系,要不然赋值不了-->
<bean id="对象名称" class="全限定名称">
<property name="属性名称" value="属性值"/>
<property name="属性名称" value="属性值"/>
</bean>
- 基于注解的依赖注入
除了基于XML配置文件的依赖注入,spring框架还提供了基于注解的依赖注入,而重要的注解有如下七个:
(1)@Component
语法格式:@Component(“对象名称”)
位置:在类的上面
(2)@Repository
作用:使用在DAO层(持久层),用来创建dao对象访问数据库(后面还会更新Mybatis和spring整合,这个会在后面讲到)。
(3)@Service
作用:使用在Service层(业务层),用来创建service创建对象,调用dao对象,主要是处理业务(后面更新SSM框架整合会讲到)。
(4)@Controller
作用:放在控制器类上面,创建控制器对象,接收用户提交的数据,显示请求处理结果。
(5)@Value
作用:简单类型赋值
位置:放在具体属性上面,无需set方法
(6)@Autowired
作用:引用类型赋值
位置:引用类型属性上面
(7)@Resource
作用:和@Autowired一样,给引用类型赋值,但是不一样的是@Resource可以同时使用byType和byName两个属性,默认属性为byName,若不符合byName,则根据byType来给引用类型赋值。
使用注解的依赖注入还有一个重要的东西,就是要声明组件扫描器,这个需要在spring配置文件当中声明,具体语法如下:
<context:component-scan base-package="包名"/>
简单举个使用@Component的例子
在具体类的上面加入@Component注解
@Component("myStudent")
public class Student {
private String name;
private int age;
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
声明组件扫描器
<context:component-scan base-package="org.example.ch03"/>
测试方法
@Test
public void test01(){
//封装路径
String config = "ba01/applicationContext.xml";
//创建容器对象
ApplicationContext ac = new ClassPathXmlApplicationContext(config);
//获取对象
Student myStudent = (Student) ac.getBean("myStudent");
//属性赋值
myStudent.setName("小廖");
myStudent.setAge(20);
//输出属性
System.out.println("学生姓名为:"+myStudent.getName());
System.out.println("学生年龄为:"+myStudent.getAge());
}
- 总结
总结一下基于XML配置文件的依赖注入和基于注解的依赖注入,如果需要经常改动代码的话,推荐使用基于XML配置文件的依赖注入,如果不需要经常改动代码的话,推荐使用基于注解的依赖注入。作者第一次发表,若有错误欢迎指出。