4 自动装配

本文介绍了自动装配在Spring框架中的应用,包括基于XML的配置、byType和byName自动装配策略,以及基于注解(@Autowired)的自动装配。重点讲解了如何通过XML标签和注解来管理bean和自动装配,以及可能出现的问题和解决方案。
摘要由CSDN通过智能技术生成
  • 什么是自动装配?
    • 自动装配就是为我们的类类型属性自动赋值,就是我们之前需要用ref引入外部的那些属性,自动装配则帮助我们自动完成了这个操作
场景模拟
  • 在三层结构中,常常会有view层的controller调用service层的业务方法,service层的业务方法调用数据访问层dao的sql语句
  • 假设我的有一个userController,userService,userDao
    • userController接收到了我的请求,调用userService中的方法,userService的方法需要调用userDao中的语句
    • 那么我在userController这个类中需要有一个成员变量userService,这样使用userService.方法()调用,userService中调用userDao也需要userDao成员变量来调用相关的方法
    • 我不使用new一个对象的方式去为它们赋值,而是为它们设定好set方法进行注入
    • 配置文件写法
      • <bean id="usercontroller" class="com.cn.zt.mvc.controller.impl.UserControllerImpl">
        • <property name="userService" ref="userservice"/>
      • </bean>
      • <bean id="userservice" class="com.cn.zt.mvc.service.impl.UserServiceImpl">
        • <property name="userDao" ref="userdao"/>
      • </bean>
      • <bean id="userdao" class="com.cn.zt.mvc.dao.impl.UserDaoImpl"/>
基于xml使用自动装配
  • 根据指定的策略,在IOC容器中匹配某个bean,自动为bean中的类类型的属性或者接口类型的属性赋值
  • 使用自动装配之后,就不需要再bean标签中使用property标签来为类类型属性赋值了
  • 我们可以通过bean标签中autowire来实现自动装配
    • <bean id="usercontroller" class="com.cn.zt.mvc.controller.impl.UserControllerImpl" autowire="">
    • autowire属性中有5个可选项
      • no和default:都表示不装配,即bean中的属性不会自动匹配某个bean为属性赋值,此时属性为默认值
        • 这个默认值就是你手动用property标签注入,如果没写,那就是空
      • byType:根据要赋值的属性的类型,在IOC容器中匹配某个bean,为属性赋值
        • 比如,我userController的bean,我有个接口类型属性userService,在bean标签中我配置了这个接口类型属性的实现类userServiceImpl,那么自动装配就会将我这个实现类的bean注入到userController的userService属性中。
        • <bean id="usercontroller" class="com.cn.zt.mvc.controller.impl.UserControllerImpl" autowire="byType">
        • 注意
          • 在类型匹配自动装配中,没有找到一个bean,就会使用默认值
          • 如果找多个bean匹配,报错,报NoUniquebean的错,所以要求只能有一个bean匹配
      • byName:它会将我们属性的属性名当做要匹配的bean的id来自动匹配
        • 我还是提醒一下,属性名的概念和成员变量有区别,切记,属性名时set方法后面跟的名字并且第一个字母小写
        • 用byName,就算id能匹配上,也要求你属性的类型能够匹配,不然使用默认值
  • 用xml自动装配是比较少用的,因为xml中的自动装配是在bean标签中,这样会使得你的这个类的所有属性都会自动装配,而我们有些属性是想自己赋值的
基于注解来管理bean以及自动装配
基于注解的管理bean
  • 基于注解管理bean也有缺点,比如你不能管理依赖包中的类,只能通过xml文件来
  • 注解与扫描基本使用
    • 注解:是一种标记,具体的功能是框架检测到注解标记的位置,然后针对这个位置按照注解标记的功能来执行具体操作
      • 常用注解
        • @Component:将类标识为普通组件
        • @Controller:将类标识为控制层组件
        • @Service:将类标识为业务层组件
        • @Repository:将类标识为持久层组件
        • 这里的组件就是指一个个bean
        • 其他三个组件都是由Component扩展而来,方便开发人员分辨各个层面,它们拥有不同的处理机制。但对于ioc容器来说,实质上没有太大区别。
    • 扫描:spring为了知道程序员在哪里标记了什么注解,就需要通过扫描的方式,来进行检测,然后根据注解进行后续操作
      • 在spring配置文件中配置相关的扫描标签,配置扫描才能检测注解
      • <context:component-scan base-package="com.cn.zt.mvc"></context:component-scan>
      • 这个context:component-scan标签就是一个扫描标签,它的属性base-package的值表示扫描的包的范围
  • 扫描组件的详细配置
    • 由于我们以后的spring和spring mvc 有各自扫描的范围,如果spring和spring mvc都扫描了同一个范围,一个组件会被扫描多次,那么这个组件会同时被这两个框架所影响
    • 在context:component-scan标签有两个子标签
      • <context:exclude-filter type="" expression=""/>,这个表示排除扫描什么
        • type属性有两个常用的值,表示排除扫描的方式
          • annotation:表示根据注解来排除
          • 它对应的expression属性的值填一个注解的全类名,比如Controller注解的全类名org.springframework.stereotype.Controller 我写了这个,那么Controller注解将不会被扫描
          • 这种排除方式就是注解排除,排除所有该注解的组件
          • assignable:表示根据类型来排除
          • 它对应的expression属性值往往填一个具体的全类名,表示个这个类不被扫描
          • 这种方式是类型排除,排除这个类的组件
      • <context:include-filter type="" expression=""/>,这个表示只扫描什么
        • 如果想使用这个子标签,它的父标签一定要改变父标签use-default-fiters的属性值为false,不然它默认是true把包扫描一遍,这个标签不起作用
        • 它的type属性有两种 包含扫描 方式,注解包含,类型包含。
        • 跟上面一样的用法,只不过,它是包含而已,就是只扫描它指定的
      • 常用的还是排除扫描,不用设置use-default-fiters属性,而且用的多
  • 通过注解加扫描添加到ioc中的bean的id
    • 默认的bean的id就是类的小驼峰,比如我UserController的注解是Controller,它的bean的id是userController,它的首字母会小写,你原先的类名如果是usercontroller,它的bean的id就是usercontroller
    • 自定义bean的id在注解中设置
      • @Controller("usercontroller") 这样它的bean的id就会被设置为括号里名字,也就是修改注解的value,但是我们常用的还是类型获取bean,id用的少
  • 基于注解的自动装配
    • 自动装配注解的使用@Autowired
      • 它的标识位置
        • 成员变量上,Spring 会自动将匹配的依赖注入到该变量中(常用)
        • set方法上,被标记的方法会在对象创建后注入相应依赖
        • 有参构造上,Spring 会在创建对象时,通过构造方法注入所需的依赖
    • 注解@Autowired自动装配的原理
      • 它是默认通过byType的方式,在IOC容器中通过类型匹配某个bean为属性赋值
      • 如果我的注解已经被扫描,在ioc中有对应类型的bean,我又在配置文件中配置了一个bean标签对应类型也是它,就会有多个类型匹配的bean了,自动装配默认的是byType,那么它会自动变成byName匹配
      • 如果byType和byName的方式都无法实现自动装配,如果ioc容器中有多个类型匹配的bean,且这些bean的id和要赋值的属性的属性名都不一致,就会报NoUnique的错
        • 这种的话可以使用注解@Qualifier(value),通过这个注解的value值来指定一个bean的id来将这个bean为这个属性赋值
      • 如果我byType方式没有找到类型匹配的bean,xml配置文件的byType的这种情况和注解的这种情况还是有区别的,注解的byType方式没找到类型匹配的bean,它会报一个spring的错,因为注解@Autowired要求一定自动装配,你要设置它的一个属性@Autowired(required = false),这样它就会能装配装配,不能就为空
        • 报错了反正三个方面,注解加扫描加自动装配,看这几个有没有问题
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值