DI 带来最大的益处是松耦合

控制反转IoC是一个很大的概念,可以用不同的方式来实现。其主要实现方式有两种:依赖注入和依赖查找

依赖注入:相对于IoC而言,依赖注入(DI)更加准确地描述了IoC的设计理念。所谓依赖注入(Dependency Injection),即组件之间的依赖关系由容器在应用系统运行期来决定,也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。组件不做定位查询,只提供普通的Java方法让容器去决定依赖关系。

1.依赖注入的基本原则

依赖注入的基本原则是:应用组件不应该负责查找资源或者其他依赖的协作对象。配置对象的工作应该由IoC容器负责,“查找资源”的逻辑应该从应用组件的代码中抽取出来,交给IoC容器负责。容器全权负责组件的装配,它会把符合依赖关系的对象通过属性(JavaBean中的setter)或者是构造器传递给需要的对象。

2.依赖注入有什么优势

依赖注入之所以更流行是因为它是一种更可取的方式:让容器全权负责依赖查询,受管组件只需要暴露JavaBean的setter方法或者带参数的构造器或者接口,使容器可以在初始化时组装对象的依赖关系。其与依赖查找方式相比,主要优势为:

· 查找定位操作与应用代码完全无关。
· 不依赖于容器的API,可以很容易地在任何容器以外使用应用对象。
· 不需要特殊的接口,绝大多数对象可以做到完全不必依赖容器。

3.有哪些不同类型的依赖注入实现方式?

依赖注入是时下最流行的IoC实现方式,依赖注入分为接口注入(Interface Injection),Setter方法注入(Setter Injection)和构造器注入(Constructor Injection)三种方式。其中接口注入由于在灵活性和易用性比较差,现在从Spring4开始已被废弃。

构造器依赖注入:构造器依赖注入通过容器触发一个类的构造器来实现的,该类有一系列参数,每个参数代表一个对其他类的依赖。

Setter方法注入:Setter方法注入是容器通过调用无参构造器或无参static工厂 方法实例化bean之后,调用该bean的setter方法,即实现了基于setter的依赖注入。

4.构造器依赖注入和 Setter方法注入的区别

构造函数注入 setter 注入
没有部分注入 有部分注入
不会覆盖 setter 属性 会覆盖 setter 属性
任意修改都会创建一个新实例 任意修改不会创建一个新实例
适用于设置很多属性 适用于设置少量属性

两种依赖方式都可以使用,构造器注入和Setter方法注入。最好的解决方案是用构造器参数实现强制依赖,setter方法实现可选依赖。

1.ioc和di区别是什么


ioc负责创建对象,di依赖注入.

2.set方式注入(常用,比构造方法用的多)

基本注入


需要注意的是,必须先加载bean.xml才能使用在配置文件的配置,否则无法使用

  1. <**bean id="IUserService" class="com.lmxi.service.UserServiceImpl"**><br /> <!--也可以用set方式注入dao层--><br /><**property name="iuserDao" ref="customerDaoImpl"**></**property**><br /> <!--用set方式注入--><br /> <**property name="username" value="ceuiset"**></**property**><br /> <**property name="age" value="666"**></**property**><br /> <**property name="birthday" ref="time"**></**property**><br /> </**bean**>
  2. <!--然后就是开始注入 customerDaoImpl 这个和上面的标识一样--><br /> <**bean id="customerDaoImpl" class="com.lmxi.dao.UserDaoImpl"**/><br /> <**bean id="time" class="java.util.Date"**/><br /></**beans**><br />![](https://cdn.nlark.com/yuque/0/2020/png/350923/1592465708134-5a4df0ec-7c98-4b93-80f1-7205a5aa9d52.png#crop=0&crop=0&crop=1&crop=1&height=239&id=RzBjT&originHeight=319&originWidth=553&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=&width=415)

注入集合map数组之类

<!—用set方法注入
思路就是 id 是注入的接口
然后class是它实现类的权限定类名
由于实现类还需要注入这个接口iuserDao 通过ref 属性找它的标识
private String[] myArrays;
private List myList;
private Set mySet;
private Map myMap;
private Properties myProps;

—>
<bean id=”iUserService” class=”com.lmxi.service.UserServiceImpl”>

<property name=”myArrays”>
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>

<property name=”myList”>
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>

<property name=”mySet”>
<array>
<value>aaa</value>
<value>bbb</value>
<value>ccc</value>
</array>
</property>

<property name=”myMap”>
<props>
<prop key=”AAA”>aaa</prop>
<prop key=”BBB”>bbb</prop>
<prop key=”CCC”>ccc</prop>
</props>
</property>

<property name=”myProps”>

<map>
<entry key=”AAA” value=”aaa”></entry>
<entry key=”BBB”>
<value>bbb</value>
</entry>
</map>
</property>
</bean>

3.构造方式注入(了解)

需要注意的是,必须先加载bean.xml才能使用在配置文件的配置,否则无法使用


注意需要有构造方法, 被注入的属性在UserServiceImpl里面就需要在那里有构造方法,
<bean id=”IUserService” class=”com.lmxi.service.UserServiceImpl”>
<property name=”iuserDao” ref=”customerDaoImpl”></property>

<constructor-arg name=”username” value=”泰斯特”></constructor-arg>
<constructor-arg name=”age” value=”111”></constructor-arg>
<constructor-arg name=”birthday” ref=”time”></constructor-arg>
</bean>


<bean id=”customerDaoImpl” class=”com.lmxi.dao.UserDaoImpl”/>
<bean id=”time” class=”java.util.Date”/>

4.注解注入

基本

需要注意一下,普通方法(字段)进入容器里面(交给Spring容器管理,注册成为bean,就是存入Spring容器里面)才能被Spring注入(取出来),不进入就不能被Spring容器注入
4.注意:如果读取不到类就反射不到方法,如果Spring没有拿到类,就无法拿到类中的方法(不能把方法交给Spring容器管理)
要想用到方法.就得先让类被Spring容器管理才能让里面的方法被Spring容器管理

/

Description: spring的配置类,它就相当于bean.xml


@ComponentScan
作用:用于指定要扫描的包
属性:
value:指定包的名称。它等同于basePackages属性
相当于xml的扫描包
——————————————
*
@Bean(方法级别注解)
作用:把当前方法的返回值作为对象,存入spring的容器(添加的bean的id是被注解修饰的方法名)
属性:
value:也可以使用name属性。作用就是指定bean的id。默认值是当前方法名称
@Bean(“runner”) //注入容器里面 容器里面就有这个id为runner的bean对象了
——————————————
@Configuration
作用:把当前类看成是一个spring的配置类
细节:
当创建容器时作为参数传入字节码之后,该注解就可以不写。
————————————————-
@Import*
作用:用于引入其他的配置类
属性:
value:用于指定配置类的字节码
*/

Spring 注解配置(没试过)



使用该标签需要引入名字空间:
1
DI依赖注入 - 图1
第 1 页
DI依赖注入 - 图2
@Component(“名字”) : 组件注解,没有业务含义的注解使用,在类级别 名字可省略,如果省略,则为类名首字母小写后的类名作为名字相当于 在spring 配置文件中 使用标签注册一个对象到IOC容器
@Value(“值”):为属性赋值(基本类型及其包装类型和String)
@Service(“名字”):服务层组件注解,通常业务逻辑层使用,如UserServiceIml
@Repository(“名字”):持久层注解,通常用于数据访问层,如UserDaoImpl
@Controller(“名字”):控制器层注解,通常用于SpringMVC中的控制器类
DI依赖注入 - 图3
@Autowired(required=true|false):自动注入,根据默认类型byType注入
required:表示是否为必须,如果为true, 又找不到注入的bean 则报错 默认为 true,该注解可以再字段,set方法,构造器上使用
@Resource(name=”bean名字”): JSR250提供的注解,根据名字注入
DI依赖注入 - 图4
@Configuration:配置类,该注解表示这个类是一个配置类,其作用等价于Spring XML配置文件
@Bean(“名字”):等价于 xml 中书写 注册bean
DI依赖注入 - 图5

5.依赖注入基本介绍总结


什么是依赖注入:
指的是在程序运行期间,让spring为我们提供类中所缺的对象。
通过配置文件的方式告知spring要把哪个对象传入。
简单的说:缺什么传什么

什么时候用构造函数注入
如果希望程序一运行的时候被注入的属性有值就用构造方法注入

如果不太强求程序一运行就得有值,只需要用的时候就有值就行用set方式注入(比构造方式好用)

注意:1.有些东西没有set方法就必须需要用构造方式注入: 比如说DataSource就没有set方法
只能用构造方式注入.
2.需要注意的是,必须先加载bean.xml才能使用在配置文件的配置,否则无法使用
3.静态方法被Spring容器注入会报错,因为静态是随着类加载而加载.


依赖注入(DI),spring使用javaBean对象的set方法或者带参数的构造方法为我们在创建所需对象时将其属性自动设置所需要的值的过程,就是依赖注入的思想。
简单说就是缺什么传什么,比如缺dao的实现类就传进来.


























AAA
BBB
CCC





AAA
BBB
CCC





AAA
BBB
CCC






CCC
DDD







BBB



6.获取所有的bean的工具类

DI依赖注入 - 图6


如果实在看不懂就看这个案例


DI依赖注入 - 图7