IOC(Inversion of Control,控制反转)、 DI(Dependency Injection,依赖注入)装配
IOC、DI 概述
控制反转IoC(Inversion of Control)是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由业务代码自己把控的, 而现在这种权力转移到第三方,比如转移交给了IoC容器,
它就是一个专门用来创建对象的工厂,你要什么对象,它就给你什么对象,有了 IoC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IoC容器了,通过IoC容器来建立它们之间的关系。
这是我对Spring的IoC(控制反转)的理解。
DI(依赖注入)其实就是IOC的另外一种说法,DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。他总结:控制的什么被反转了?就是:获得依赖对象的方式反转了。
1、xml文件实现bean的手动装配
<?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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="catDTO" class="com.lzq.entity.CatDTO"/>
<bean name="dogDTO" class="com.lzq.entity.DogDTO"/>
<bean id="peopleDTO" class="com.lzq.entity.PeopleDTO">
<property name="name" value="lzq"/>
<property name="age" value="24"/>
<!-- 手动依赖注入-->
<property name="catDTO" ref="catDTO"/>
<property name="dogDTO" ref="dogDTO"/>
</bean>
</beans>
2、xml文件实现bean的autowired自动装配
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="catDTO1" class="com.lzq.entity.CatDTO"/>
<bean name="dogDTO" class="com.lzq.entity.DogDTO"/>
<!-- 自动装配 byName byType
在容器中使用名称或者类型与直接bean中对应的要set的属性-->
<!-- <bean id="peopleDTO" class="com.lzq.entity.PeopleDTO" autowire="byName">-->
<bean id="peopleDTO" class="com.lzq.entity.PeopleDTO" autowire="byType">
<property name="name" value="lzq"/>
<property name="age" value="24"/>
</bean>
</beans>
public class PeopleDTO {
private String name;
private Integer age;
private DogDTO dogDTO;
private CatDTO catDTO;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public DogDTO getDogDTO() {
return dogDTO;
}
public void setDogDTO(DogDTO dogDTO) {
this.dogDTO = dogDTO;
}
public CatDTO getCatDTO() {
return catDTO;
}
public void setCatDTO(CatDTO catDTO) {
this.catDTO = catDTO;
}
@Override
public String toString() {
return "PeopleDTO{" +
"name='" + name + '\'' +
", age=" + age +
", dogDTO=" + dogDTO +
", catDTO=" + catDTO +
'}';
}
}
3、xml配置后注解实现bean的autowired自动装配
<?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"
xsi:schemaLocation="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.xsd">
<bean id="catDTO1" class="com.lzq.entity.CatDTO"/>
<bean name="dogDTO" class="com.lzq.entity.DogDTO"/>
<!-- 自动装配 byName byType
在容器中使用名称或者类型与直接bean中对应的要set的属性-->
<bean id="peopleDTO" class="com.lzq.entity.PeopleDTO">
<property name="name" value="lzq"/>
<property name="age" value="24"/>
</bean>
<!--指定spring容器要扫描的包件 包下的注解生效-->
<context:component-scan base-package="com.lzq"/>
<!-- 启用注解-->
<context:annotation-config/>
</beans>
public class PeopleDTO {
private String name;
private Integer age;
// @Autowired 先根据类型(byType)查找,如果存在多个(Bean)再根据名称(byName)进行查找;
// @Resource 先根据名称(byName)查找,如果(根据名称)查找不到,再根据类型(byType)进行查找。
//spring 注解 @Autowired 装配注入
@Autowired
private DogDTO dogDTO;
//java 注解装配注入
@Resource
private CatDTO catDTO;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public DogDTO getDogDTO() {
return dogDTO;
}
public void setDogDTO(DogDTO dogDTO) {
this.dogDTO = dogDTO;
}
public CatDTO getCatDTO() {
return catDTO;
}
public void setCatDTO(CatDTO catDTO) {
this.catDTO = catDTO;
}
@Override
public String toString() {
return "PeopleDTO{" +
"name='" + name + '\'' +
", age=" + age +
", dogDTO=" + dogDTO +
", catDTO=" + catDTO +
'}';
}
}
4、基于Java代码使用注解代替bean.xml依赖注入进行装配
注解
@Component
@Configuration 指定该类为配置类 代表这是一个配置类,就和我们之前看的beans.xml
@ComponentScan("com.lzq") 设置要spring容器要扫描那些包件下的组件
@Import(BeanConfig1.class) 等价于xml文件spring配置的 import resource="bean.xml"/> 用于合并其他xml中的配置合并在一个xml文件中用于引用
1、@Component
代表将某个类注册到Spring中,装配Bean
@Component有几个衍生注解,我们在web开发中,会按照mvc三层架构分层
1 dao/mapper [@Repository]
2 service [@Service]
3 controller (@Controller]
这四个注解功能都是一样的,都是代表将某个类注册到Spring中,装配Bean
2、@ComponentScan(“com.lzq”)
设置要spring容器要扫描那些包件下的组件 等价于xml文件
<!--指定spring容器要扫描的包件 包下的注解生效-->
<context:component-scan base-package="com.lzq"/>
<!-- 启用注解-->
<context:annotation-config/>
3、@Import(BeanConfig1.class)
等价于xml文件spring配置的 import resource=“bean.xml”/> 用于合并其他xml中的配置合并在一个xml文件中用于引用
<!-- <import/> 用于合并其他xml中的配置合并在一个xml文件中用于引用-->
<import resource="bean.xml"/>
4、@Configuration
指定该类为配置类 代表这是一个配置类,就和我们之前看的beans.xml
@Configuration //指定该类为配置类
@ComponentScan("com.lzq")
@Import(BeanConfig1.class)
public class BeanConfig {
@Bean
public UserDTO user() {
return new UserDTO();
}
}