1、概念
IoC:指将对象的创建权,交给到Spring容器;
DI :指Spring创建对象的过程中,将对象依赖的属性通过配置的方式自动的设值给当前的对象 。
IoC/DI注解详解
完成IoC/DI,有两种方式,一种是使用xml配置文件,另一种是使用注解,我们先来介绍xml方式。
2、xml配置
2.1 使用setter注入(推荐)
Setter注入:最常用的注入方法,需要在xml配置文件中进行手动的配置.
要求:对象中的每个属性必须要有setter 方法
如何配置:
需要为对象中的每个属性配置一个"property"标签:
其中name属性的值为对象中属性的名字.如何给属性注入值时,需要先确定该属性的类型
对象中的属性分为以下三种类型,不同的类型使用不同的注入方式
1):简单数据类型(八大基本类型,String,BigDecimal,Date等). 使用value.
2):引用数据类型. 使用ref.
3):集合数据类型. 使用集合的元素.
(1)新建User类
@Setter@ToString
public class User {
// 简单数据类型
private String name;
private Integer age;
private BigDecimal salary;
// 引用数据类型
private Dog dog;
// 集合数据类型
private List list;
private Map map;
private Properties pro;
(2)创建引用类Dog
(3)新建配置文件
<!--Setter方式DI注入(类必须要实现了setter方法!!!)-->
<bean id="user" class="com.project.DI.setter.User">
<!--简单数据类型,自动类型转换-->
<property name="name" value="张三"/>
<property name="age" value="20"/>
<property name="salary" value="200.000"/>
<!--引用数据类型,使用ref标签,引入容器中已经存在的一个对象-->
<property name="dog" ref="d_dog"/>
<!--集合数据类型-->
<property name="list">
<list>
<value>list1</value>
<value>list2</value>
<!--list集合存放引用数据类型-->
<ref bean="d_dog"></ref>
</list>
</property>
<property name="map">
<map>
<entry key="k1" value="v1"></entry>
<entry key-ref="d_dog" value="汪汪"></entry>
</map>
</property>
<property name="pro">
<props>
<prop key="pro1">ppp</prop>
<prop key="pro2">qqq</prop>
</props>
</property>
</bean>
<bean id="d_dog" class="com.project.DI.setter.Dog"></bean>
(4)新建测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestRun {
@Autowired
private User user;
@Test
public void run(){
System.out.println(user);
}
}
2.2 使用构造器注入
构造器注入:利用构造函数为对象中的属性注入值,需要在xml配置文件中进行手动的配置.
要求:
对象中必须存在有参数的构造函数.xml中手动配置了哪些属性需要注入值,对象中必须存在对应的属性为参数的构造函数.
如何配置:
需要为对象中的每个属性配置一个"constructor-arg"标签:
其中name属性的值构造函数中形参的名字.如何给属性注入值时,需要先确定该属性的类型(与setter注入方式类似)
对象中的属性分为以下三种类型,不同的类型使用不同的注入方式
1):简单数据类型(八大基本类型,String,BigDecimal,Date等). 使用value.
2):复合数据类型. 使用ref.
3):集合数据类型. 使用集合的元素.
3、注解配置
注解分为Ioc注解及Di注解
3.1 DI注解
目的:使用DI注解替换xml文件中的property标签
1 、在Spring中使用注解来完成DI操作,我们称之为注解自动装配,存在两种用法.
(1):使用Spring框架自身提供的注解:@Autowired
(2):使用JavaEE规范提供的注解:@Resource
2、Autowired标签:
(1).通过@Autowired标签可以让Spring自动的把对象需要的属性从Spring容器中找出来,并注入(设置)给该属性。
(2).第三方程序:Spring3.0之前,需要手动配置@Autowired注解解析程序; 在Spring3.0开始,Spring就会自动的加入针对@Autowired标签的解析程序。
(3)@Autowired标签贴在字段或者setter方法上。
(4)@Autowired可以同时为一个属性注入多个对象。
public void setXxx(OtherBean1 other1,OtherBean2 other2) {}
3、Autowired标签注意事项
@Autowired找bean的方式:
(1)首先按照依赖对象的类型找,如果没有找到。默认会报错;如果找到一个匹配的对象,直接注入。(不过,可使用required=false来避免该问题:Autowired(required=false)
)
(2)如果在Spring上下文中找到多个匹配(2个或者2个以上)的类型,再按照名字(id)去找,如果没有匹配则报错;
(3)可以通过使用@Qualifier(“otherBean”)标签来规定依赖对象按照bean的id+类型去找;
4 、@Autowired注解的使用
(1)创建User类及引用Dog类
使用注解可以替代setter方法
@ToString
public class User {
/*基本数据类型使用DI注解赋值,注解不需要setter方法*/
@Value(value = "天天")
private String name;
/*引用数据类型使用DI注解赋值*/
@Autowired(required=false)
private Dog d;
}
(2)创建配置文件
<?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:util="http://www.springframework.org/schema/util"
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/util http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<!--使用DI autowired注解 替代 property标签-->
<bean id="user" class="com.project.DI.autowired4DI.User">
<!--<property name="name" value="天天"/>
<property name="d" ref="dog"/>-->
</bean>
<bean id="dog" class="com.project.DI.autowired4DI.Dog"></bean>
</beans>
(3)测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestRun {
@Autowired
private User user;
@Test
public void run()
{
System.out.println(user);
}
}
3.2 IoC注解
目的:使用注解来替换bean标签(只能是自己定义的类,替代不了第三方类)
- IoC注解分为四类:
- (1)@Repository:用于标记dao层的类
- (2)@Service:用于标记service层的类
- (3)@Controller:用于标记controller(servlet)层
- (4)@Component:不分层情况下,用这个
步骤:
(1)使用标签来完成IoC,就必须有IoC注解的解析器 , 使用context:component-scan来扫描spring需要管理的bean; base-package就告诉spring,去哪些包及其子包里去扫描bean,如果有多个包需要被扫描;只需要用逗号隔开多个包即可。
在xml文件中声明IoC注解的解析器:
<context:component-scan base-package="com.ujiuye.spring.xxx" />
(2)创建类,在类上使用IoC注解@Component
@Component
public class User {
/*基本数据类型使用DI注解赋值,注解不需要setter方法*/
@Value(value = "天天")
private String name;
/*引用数据类型使用DI注解赋值*/
@Autowired
private Dog d;
@PostConstruct
public void init(){
System.out.println("初始化");
}
@PreDestroy
public void destroy(){
System.out.println("销毁");
}
}
(3)测试
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class TestRun {
@Autowired
private User user;
@Test
public void run()
{
System.out.println(user);
}
}
4、总结
选用xml还是注解:
1),Annotation:使用方便,XML文件很小,但是,依赖关系又重新回到了代码当中;
2),XML:使用稍微复杂,但是,代码很干净,代码不会很任何框架产生关系;XML安全;
两种方式都必须掌握;