IOC-基于注解管理bean

注解

和XML配置文件一样,注解本身并不能执行,注解本身只是做一个标记,具体功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能执行具体操作

本质上:所有的操作都是Java代码来完成的,XML和注解只是告诉框架中的Java代码如何执行

标记

在使用注解标记时,我们要在 需要被IOC容器管理的类上 加上注解

常用注解:

@Component:将类标识为普通组件

@Controller:将类标识为控制层组件

@Service:将类标识为业务层组件

@Repository:将类标识为持久层组件

注:

1.这四个注解的作用是完全一样的,下面三个注解都是在第一个注解的基础上起了三个新的名字

但是为了代码的可读性,我们仍然要根据对应的关系来进行注解

2.这四个注解应该标记在要被管理的类上,不能被标记在接口上

扫描组件

在使用主键标记了需要被管理的类后,我们还需要扫描这些类,判断是否使用了注解

基础的扫描方式

在IOC容器中使用context:component-scan来设置我们需要扫描的包(需要context约束)

<context:component-scan base-package="com.controller"></context:component-scan>

若我们有多个要扫描的包,可以直接使用逗号分隔

<context:component-scan 
base-package="com.controller,com.dao.impl,com.service">
</context:component-scan>

也可以直接扫描一个大包,将需要扫描的包都包括进去

<context:component-scan base-package="com"></context:component-scan>

注:我们选择的包的范围越大,扫描到没有注解的类或接口就越多,导致效率降低,因此包的范围越小,越精确,效率就越高

指定要排除的组件

我们在进行扫描时,可能会出现某些类不想要让这个IOC容器管理的情况,那么此时就需要排除这些类

context:component-scan有子标签

context:exclude-filter:指定排除规则,其有属性

type和expression

type="annotation",根据注解排除,expression中设置要排除的注解的全类名

type="assignable",根据类型排除,expression中设置要排除的类型的全类名

<context:component-scan base-package="com.atguigu">
  <context:exclude-filter type="annotation"
    expression="org.springframework.stereotype.Controller"/>
  <!--<context:exclude-filter type="assignable"
  expression="com.atguigu.controller.UserController"/>-->
</context:component-scan>

仅扫描指定组件

为实现进扫描指定组件的功能,需要进行两步操作:

1.设置context:component-scan的属性 use-default-filters="false"

2.使用context:component-scan的子标签 context:include-filter ,然后设定type和expression来指定要扫描那些类

use-default-filters="true"(默认),所设置的包下所有的类都需要扫描,此时可以使用排除扫描

use-default-filters="false",所设置的包下所有的类都不需要扫描,此时可以使用包含扫描

<context:component-scan base-package="com.atguigu" use-default-filters="false">
  <context:include-filter type="annotation"
    expression="org.springframework.stereotype.Controller"/>
  <!--<context:include-filter type="assignable"
  expression="com.atguigu.controller.UserController"/>-->
</context:component-scan>

仅扫描使用的较少

注:一个扫描中可以设置多个排除或多个包含,但不能同时使用排除和包含

组件所对应的bean的id

默认id

在我们使用XML方式管理bean时,每个bean都有一个唯一标识,便于在其他地方引用。现在使用注解后,每个组件仍然应该有一个唯一标识

默认情况下,类名首字母小写就是bean的id

例:UserController类对应的bean的id就时userController

自定义id

除默认id外,我们也可以通过表示组件的注解的value属性设置自定义id

如图,此时UserController对应的bean的id就是controller

自动装配

在使用XML管理bean时,如果bean中的某个属性是一个类类型的属性,我们可以自动装配为其赋值

在注解管理bean中,要实现自动装配功能,我们可以使用@Autowired注解,该注解的标记位置有三种

1.在成员变量上使用@Autowired注解,此时不需要提供set方法

如图,为UserController类的userService成员变量实现自动装配,只需要在成员变量上使用注解即可

2.在成员变量的set方法上使用@Autowired注解

3.在为当前成员变量赋值的有参构造上使用@Autowired注解

注:一般使用第二种

@Autowire注解的原理

默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值

若有多个类型匹配的bean,此时会使用byName的方式实现自动装配的效果,即将要赋值的属性的属性名作为bean的id去匹配bean并为其赋值

若IOC容器中有多个类型匹配的bean,且这些bean的id和要赋值的属性的属性名都不同,则会抛异常,此时可以在要赋值的属性上添加一个@Qualifier注解,通过该注解的value属性值,指定某个bean的id,用这个bean为属性赋值

注:若IOC容器中没有任何一个类型匹配的bean,会抛出异常

在@Autowired注解中有个属性required,默认值为true,表示必须完成自动装配

可以将其设置为false,此时若无法装配则会使用默认值

上一篇:微信小程序之自定义组件及使用


下一篇:华为配置路由式Proxy ARP示例