什么是IOC
- 控制反转,把对象创建和对象之间的调用过程,交给spring进行管理
- 使用spring的目的:为了耦合度降低
DI:依赖注入,注入属性,是IOC中的一种具体实现。
对ioc的简单理解
在平时的java应用开发中,我们要实现某一个功能或者说是完成某个业务逻辑时至少需要两个或以上的对象来协作完成,在没有使用Spring的时候,每个对象在需要使用他的合作对象时,自己均要使用像new object() 这样的语法来将合作对象创建出来,这个合作对象是由自己主动创建出来的,创建合作对象的主动权在自己手上,自己需要哪个合作对象,就主动去创建,创建合作对象的主动权和创建时机是由自己把控的,而这样就会使得对象间的耦合度高了,A对象需要使用合作对象B来共同完成一件事,A要使用B,那么A就对B产生了依赖,也就是A和B之间存在一种耦合关系,并且是紧密耦合在一起,而使用了Spring之后就不一样了,创建合作对象B的工作是由Spring来做的, Spring创建好B对象,然后存储到一个容器里面,当A对象需要使用B对象时,Spring就从存放对象的那个容器里面取出A要使用的那个B对象,然后交给A对象使用,至于Spring是如何创建那个对象,以及什么时候创建好对象的,A对象不需要关心这些细节问题(你是什么时候生的,怎么生出来的我可不关心,能帮我干活就行),A得到Spring给我们的对象之后,两个人一起协作完成要完成的工作即可。
所以控制反转IoC(Inversion of Control)是说创建对象的控制权进行转移,以前创建对象的主动权和创建时机是由自己把控的,而现在这种权力转移到第三方,比如转移交给了IoC容器,它就是一个专门用来创建对象的工厂,你要什么对象,它就给你什么对象,有了 IoC容器,依赖关系就变了,原先的依赖关系就没了,它们都依赖IoC容器了,通过IoC容器来建立它们之间的关系。
这是我对Spring的IoC(控制反转)的理解。DI(依赖注入)其实就是IOC的另外一种说法,DI是由Martin Fowler 在2004年初的一篇论文中首次提出的。他总结:控制的什么被反转了?就是:获得依赖对象的方式反转了。
原始方法---------->工厂模式-------------->IOC
Spring 提供 IOC实现的两种方式(两个接口)
1.BeanFactory
BeanFactory context=new ClassPathXmlApplicationContext("TestBean1.xml");
User user = context.getBean("userHhy", User.class);
特点:
- 加载配置文件的时候不会创建对象,在获取(使用)的时候才会创建对象
2.ApplicationContext
ApplicationContext context=new ClassPathXmlApplicationContext("TestBean1.xml");
User user = context.getBean("userHhy", User.class);
特点:
- 加载配置文件的时候就会把配置文件中的对象进行创建
ApplicationContext 是BeanFactory 的子接口,功能更强大,建议使用
ApplicationContext 接口下的两个重要的实现类:
- ClassPathXmlApplicationContext(相对路径)
- FileSystemXmlApplicationContext(绝对路径)
IOC操作,bean管理
什么是bean管理?
bean管理指的是两个操作
- spring创建对象
- spring注入属性
bean管理操作的两种方式
- 基于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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="userHhy" class="com.hhy.entity.User"/>
</beans>
(1)在spring配置文件中,使用bean标签,标签里面添加对应属性, 就可以实现对象创建。
(2)在bean标签有很多属性,介绍常用的属性。
*id属性:唯一标识。
*class属性:类全路径(包类路径)
(3) 创建对象时候,默认也是执行无参数构造方法完成对象创建.写上有参构造必须写上无参构造。
- 注入属性
第一种实现方式:使用set方法注入
public class User {
private int age;
private String name;
private boolean gender;
public void setAge(int age) {
this.age = age;
}
public void setName(String name) {
this.name = name;
}
public void setGender(boolean gender) {
this.gender = gender;
}
@Override
public String toString() {
String res= gender ?"男":"女";
return "User{" +
"age=" + age +
", name='" + name + '\'' +
", gender=" + res +
'}';
}
}
<?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="userHhy" class="com.hhy.entity.User">
<!--使用property注入属性
name:类里面的属性名称
value:向属性注入的值
-->
<property name="name" value="hhy"/>
<property name="age" value="20"/>
<property name="gender" value="true"/>
</bean>
</beans>
第二种实现方式:有参构造方法注入
public class Orders {
private String name;
private String address;
public Orders(String name, String address) {
this.name = name;
this.address = address;
}
@Override
public String toString() {
return "Orders{" +
"name='" + name + '\'' +
", address='" + address + '\'' +
'}';
}
}
<?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="orders" class="com.hhy.entity.Orders">
<constructor-arg name="name" value="java入门到入土"/>
<constructor-arg name="address" value="河北省保定市莲池区五四东路180号"/>
</bean>
</beans>
测试类
public class TestIoc {
@Test
public void testIoc(){
//BeanFactory context=new ClassPathXmlApplicationContext("TestBean1.xml");
ApplicationContext context=new ClassPathXmlApplicationContext("TestBean1.xml");
User user = context.getBean("userHhy", User.class);
Orders orders = context.getBean("orders", Orders.class);
System.out.println(user.toString());
System.out.println(orders.toString());
}
}
- 基于注解方式实现
Spring针对Bean管理中创建对象提供注解
(1) @Component
(2) @Service+
(3) @Controller
(4) @Repository。
*.上面四个注解功能是一样的,都可以用来创建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
">
<!--
1.如果扫描多个包,可以用,隔开
<context:component-scan base-package="com.hhy.mapper,com.hhy.service,com.hhy.controller"/>
2,也可以扫描上级目录
<context:component-scan base-package="com.hhy"/>
-->
<context:component-scan base-package="com.hhy"/>
</beans>
之后就可以在相应的类上写相应的注解
Spring针对Bean管理中属性注入提供注解
(1) @AutoWired
- 根据属性类型进行自动装配
(2) @Qualifier
- 根据属性名称进行注入 (接口可以有多个实现类,注入时需要指定具体的类名 @Qualifier(名称),和@AutoWired一起使用 )
(3) @Resource
- 可以根据属性类型进行注入,也可以根据属性名称进行注入( @Resource根据类型注入,@Resource( name = 名称)会根据名称注入,@Resource 注解是javax包下的,不建议使用)
(4) @Value 注入普通类型属性,一般用于读取配置文件 参考 博客.