IOC控制反转
Java基础的调用对象方式
我们会常用很多类来描述它们特有的功能,当其他类需要使用这些功能时,我们会创建一个该类的对象来调用相应的方法,最为常见的办法就是使用new关键字来创建一个对象.这个时候,每个类都需要负责管理与自己有交互的类的引用和依赖,当实现功能的类改变时我们可能需要修改所有的引用了该类对象的类,这无疑是个很麻烦的过程.这种做法让代码变的异常难以维护和极度的高耦合,这无疑时违背了我们开发中需要遵循的高内聚低耦合的理念.而IOC的出现正是用于解决这个问题.
IOC的思想
通过IOC可以将这些互相依赖对象的创建协调工作交给spring容器去处理,每个对象只需要关注其自身的业务逻辑关系就可以了.可以看到获得依赖对象的方式进行了反转.在过去我们每次需要使用一个类的对象时都是new一个对象出来,现在则是直接从一个容器中将相应的对象取出来,相应的实例化工作都交给了spring来做.
容器
容器,顾名思义就是一个可以装许多东西的大盒子.我们可以将spring容器看作是一个大柜子,里面有许多抽屉,我们在创建了一个类的时候,就把这个类注册到一个抽屉去,这个抽屉里面就存放了一个该类的对象,我们通常把这个被实例的,组装的及被Spring 容器管理的Java对象称为bean,而创建应用对象之间的协作关系的行为称为:装配(wiring),这就是依赖注入的本质。
Spring的三种配置方式
我们新建一个module,在其中新建几个类,同时在resources文件夹中添加一个spring配置文件(名字随意):
在XML文件中显式配置
在beans.xml文件中,添加以下代码:
<bean id="cat" class="com.autowire.spring.Cat"/>
<bean id="dog" class="com.autowire.spring.Dog"/>
<bean id="people" class="com.autowire.spring.People">
<property name="name" value="aaa"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
</bean>
这样子就成功装配了这三个类.
其中id即为容器中这个对象的名字,我们也是通过这个名字去取这个对象,.class属性即为这个类的全限定名
在每个bean标签中,有一个property属性,它是用于装配类中的实例变量。name即为变量的名称,value用于注入变量值,ref用于注入对象类型
自动装配
这个是通过注解来实现的,首先需要在xml文件中添加context支持
<context:component-scan base-package="com.autowire.spring"/>
base-package属性就是会自动扫描的包
然后在需要装配的类上面添加@Component注解,这个类就会被自动装配到bean容器中
这时我们是通过这个类的首字母小写后的名称来获取这个对象
纯使用Java代码和注解配置
前面两种方法都是通过配置xml文件来实现的,而这一中方法是完全通过Java代码来实现.
首先新建一个配置类,使用@Configuration注解表明这是一个配置bean的配置类,然后编写用@Bean声明的方法,来return一个相应类的对象
@Configuration
public class MyConfig {
@Bean
public Cat getCat(){
return new Cat();
}
}
测试类中使用相应对象
以往我们调用某个类实现功能都是new一个对象,现在我们则是通过下面的这种方式:
ApplicationContext context=new ClassPathXmlApplicationContext("beans.xml");
//ApplicationContext context=new AnnotationConfigApplicationContext(MyConfig.class);
People people=context.getBean("people",People.class);
people.getCat().shout();
people.getDog().shout();
这里是通过一个ApplicationContext类型的对象调用getBean方法来获取相应类的实例,对于该接口的介绍可参照:https://blog.csdn.net/stupid56862/article/details/89299609以及https://www.jianshu.com/p/17b66e6390fd这两篇文章.
注入的方式
在XML文件中显示地配置
1、使用setter方法注入
在类中给每个实例变量设置一个setter方法,然后在xml文件中使用标签注入,如:
<property name="name" value="aaa"/>
<property name="cat" ref="cat"/>
<property name="dog" ref="dog"/>
2、使用构造器注入
利用类中的有参构造方法进行注入
使用自动装配
@Autowire注解可以实现自动装配,是按照声明地变量类型/名称自动在已装配的bean中查找,可以通过@Qualifier(value=***)来选择注入的元素名称