Spring依赖注入
为什么需要DI
可能DI(依赖注入)这个词本身就不太好理解,首先我们先来看看官方的定义:
依赖注入会将所依赖的关系自动交给目标对象,而不是让对象自己去获取依赖。
- A自己去获取B依赖:在A类属性中申明B,然后再A的构造函数中new一个B对象。
1 | Class A{ |
- B注入到A:在A类属性中申明B,通过带有B参数的构造函数获取B。
1 | Class A{ |
我们可以看到,第二种方式(注入方式)灭有自己创建B对象,而是在构造的时候吧B对象作为构造器参数传入。这也是依赖注入方式之一,即构造器注入(construction injection)。
很多小伙伴看到这里就要问了,有差吗?有差。
一方法的B对象是绑定死的;二方法的对象是灵活的,因为B类型可以是接口类型,只要实现了B接口的类都能通过二方法注入到A。我用个图表示一下两者的差别:
从图中局很好理解,主动获取是紧耦合的,而依赖注入是松散耦合的。这就是我们需要DI的原因,不知道各位客官想通了咩有。
装配Bean
到目前为止,因为B没有实例化,所以A还是无法使用B的,而我们同样也还是是用不了A,原因也是一样。如果写一个主类,在主类里头使用A和B,我们应该会很熟悉,代码如下:
1 | public class Main{ |
但是如果有很多个类都需要实例化,都写在main中不免会有些臃肿,如果把这些配置
写在另一个统一的类,岂不是更加?我们就把这些配置
剥离到一个名为Config
类中。
1 | class Config{ |
现在的问题是,main函数怎么拿到b对象和a对象呢?我们需要Configure conf = new Configure();
,然后从conf中获取。1
2
3
4
5
6
7public class Main {
public static void main(String[] args) {
Configure configure = new Configure();
// 别忘了实现a的getter方法
configure.a.useB();
}
}
其实我认为上述就是我们可以用Spring框架解决这个问题。我们修改一下Config
类,改成如下所示:
1 |
|
我们使用@Configuration
注解了Config
类,生成了两个bean,Spring就会根据@Bean
注解把bean放到它的容器之中,即取即用。
具体怎么拿出来,我们看下面的代码:
/**
* @author wangxiaobin
*/
public class Main {
public static void main(String[] args) {
// 申明上下文
AnnotationConfigApplicationContext context
= new AnnotationConfigApplicationContext();
// 注册Configure类
context.register(Configure.class);
context.refresh();
// 获取A类
A a = context.getBean(A.class);
a.useB();
}
}
我们使用AnnotationConfigApplicationContext
申明一个Spring上下文,并且告诉它配置类是Configure.class
,这样它就能知道有多少bean是需要被加载到容器中的,然后用getBean()方法取出即可。