1>依赖注入
- DI 是ioc的技术实现
- DI(Dependency Injection):依赖注入, 只需要在程序中提供要使用的对象名称就可以,至于对象如何在容器中创建,赋值,查找都由容器内部实现。
- spring是使用的di实现了ioc的功能, spring底层创建对象,使用的是反射机制。
- spring是一个容器,管理对象,给属性赋值, 底层是反射创建对象。
2>依赖注入的分类
- 基于XML的DI
- 基于注解的DI
- 无论是基于XML的DI还是注解的DI都会要求输入id名称
- 这个ID相当于对象的名称
- Spring会通过Map一样的方式将对象名称与对象一一对应
- (String,Object)
3>基于XML的DI
- 分为两种
- Set注入(掌握)
- 构造注入(了解)
3.1、Set注入
- Set注入,顾名思义,是我们在构造类的时候,写入了无参构造以及Setxxx()方法
- Spring容器在我们在xml写入时,通过使用无参构造和Setxxx()方法为对象赋值
3.1.2、简单类型注入
- 简单类型指的是String和基本数据类型
3.1.2、引用类型注入
- 当指定 bean 的某属性值为另一 bean 的实例时,通过 ref 指定它们间的引用关系。ref的值必须为某 bean 的 id 值。
3.2、构造注入
- 构造注入:spring调用类的带参构造方法,在创建对象的同时,在构造方法中给属性赋值,构造注入使用<constructor-arg>标签
- <constructor-arg>标签属性:
- name:表示构造方法的形参名
- index:表示构造方法的参数位置,参数从左往右是0,1,2的顺序
- value:构造方法的形参类型是简单类型的,使用value
- ref:构造方法的形参类型是引用类型的,使用ref
- 例子:使用构造注入创建一个系统类File对象
4>引用类型的自动注入
- 对于引用类型属性的注入,也可不在配置文件中显示的注入。可以通过为标签 设置 autowire属性值,为引用类型属性进行隐式自动注入(默认是不自动注入引用类型属性)。
- 根据自动注入判断标准的不同,可以分为两种:
- byName:根据名称自动注入
- byType: 根据类型自动注入
4.1、byName
- spring很智能无论前后顺序都可以正常运行
- 使用byName 要求引用类型的声明的id必须与类中变量名相同
4.2、byType
- java类中引用类型的数据类型和spring容器中(配置文件)<bean>的class属性是同源关系的,这样的bean能够赋值给引用类型
- 但这样的同源的被调用 bean 只能有一个。多于一个,容器就不知该匹配
哪一个了。 - 同源就是一类的意思:
- 1、java类中引用类型的数据类型和bean的class的值是一样的
- 2、java类中引用类型的数据类型和bean的class值父子类关系的
- 3、java类中引用数据类型的数据类型和beandd额class值接口和实现类关系的
- 语法:
<bean id="xx" class="yyy" autowird="byType">
</bean>
5>基于注解的DI
5.1、定义Bean的注解@Component( 掌握)
- 需要在类上使用注解@Component,该注解的 value 属性用于指定该 bean 的 id 值。
- @Component 不指定 value 属性,bean 的 id 是类名的首字母小写。
- 另外,Spring 还提供了 3 个创建对象的注解:
➢ @Repository 用于对 DAO 实现类进行注解
➢ @Service 用于对 Service 实现类进行注解
➢ @Controller 用于对 Controller 实现类进行注解 - 这三个注解与@Component 都可以创建对象,但这三个注解还有其他的含义,@Service创建业务层对象,业务层对象可以加入事务功能,@Controller 注解创建的对象可以作为处理器接收用户的请求。
- @Repository,@Service,@Controller 是对@Component 注解的细化,标注不同层的对象。即持久层对象,业务层对象,控制层对象。
5.2、简单属性注入@Value(掌握)
- 需要在属性上使用注解@Value,该注解的 value 属性用于指定要注入的值。
- 使用该注解完成属性注入时,类中无需setter。当然,若属性有 setter,则也可将其加到setter上。
5.3、byType自动注入@Autowired( 掌握)
- 需要在引用属性上使用注解@Autowired,该注解默认使用按类型自动装配Bean的方式。
- 使用该注解完成属性注入时,类中无需 setter。当然,若属性有 setter,则也可将其加到 setter 上。
- 需要在引用属性上联合使用注解@Autowired 与@Qualifier。@Qualifier 的 value 属性用于指定要匹配的 Bean 的 id 值。类中无需 set 方法,也可加到 set 方法上。
- @Autowired 还有一个属性 required,默认值为 true,表示当匹配失败后,会终止程序运行。
- 若将其值设置为 false,则匹配失败,将被忽略,未匹配的属性值为 null。
5.4、JDK注解@Resource自动注入(掌握)
5.4.1、byType注入引用类型属性
- @Resource 注解若不带任何参数,采用默认按名称的方式注入,按名称不能注入bean,则会按照类型进行Bean的匹配注入。
5.4.2、byName 注入引用类型属性
- @Resource 注解指定其 name 属性,则name的值即为按照名称进行匹配的 Bean的id。
5.5.3、注解中使用属性配置文件(了解)
5.6、使用注解注入配置Spring文件
- 对于 DI 使用注解,将不再需要在 Spring 配置文件中声明 bean 实例。Spring 中使用注解,需要在原有 Spring 运行环境基础上再做一些改变。
- 需要在 Spring 配置文件中配置组件扫描器,用于在指定的基本包中扫描注解。
5.6.1、指定多个包的三种方式
- 1、使用多个 context:component-scan 指定不同的包路径
- 2、指定 base-package 的值使用分隔符
- 逗号分隔:
- 分号分隔:
- 逗号分隔:
- 3、base-package 是指定到父包名
- base-package 的值表是基本包,容器启动会扫描包及其子包中的注解,当然也会扫描到子包下级的子包。所以 base-package 可以指定一个父包就可以,或者最顶级的父包
- 但不建议使用顶级的父包,扫描的路径比较多,导致容器启动时间变慢。指定到目标包和合适的。也就是注解所在包全路径。例如注解的类在
com.bjpowernode.beans 包中
- base-package 的值表是基本包,容器启动会扫描包及其子包中的注解,当然也会扫描到子包下级的子包。所以 base-package 可以指定一个父包就可以,或者最顶级的父包
6>注解与XML对比
- 注解优点是:
- 方便
- 直观
- 高效(代码少,没有配置文件的书写那么复杂)。
- 其弊端也显而易见:以硬编码的方式写入到 Java 代码中,修改是需要重新编译代码的。
- XML 方式优点是:
- 配置和代码是分离的
- 在 xml 中做修改,无需编译代码,只需重启服务器即可将新的配置加载。
- xml 的缺点是:编写麻烦,效率低,大型项目过于复杂。