理解SpringIOC

IOC(Inversion Of Control):控制反转
控制:即对资源(如一个Java类)的获取方式
获取方式可以分为两种

  1. 主动获取
    在Spring之前我们想要获取一个类都是自己创建,即new出这个类对象
    如在LoginServlet中需要使用LoginService
      LoginServlet{
      LoginService ls = new LoginService();//此时调用LoginService的无参构造创建对象
      //下边需要对ls这个对象赋值然后开始使用,如果是一个较简单的对象,那么赋值也比较容易,如果对象复杂,那么赋值也是复杂的,所以赋值这个过程也不怎么友好
    }
    
  2. 被动获取
    即资源不需要我们自己创建,而是交给一个容器来完成创建和设置的工作,我们只需要从容器中取出想要的资源就可以
      LoginServlet{
        LoginService ls;//取出想要的资源
        public void login(){
          ls.check;//直接开始使用
        }
    }
    

容器:可以管理所有的组件(有功能的类);假设LoginServlet和LoginService都受容器的管理,容器可以自动探查(通过配置文件或注解)出哪些组件中需要用到其他组件 ,容器可以直接帮我们创建LoginService对象,并给LoginService对象赋值。

DI(Dependency Injection):依赖注入
容器能知道哪些组件在运行时需要其他组件 ,容器通过反射的形式,将容器中准备好的LoginService对象注入(利用反射给属性赋值)到LoginServlet中

使用@Autowired进行自动注入

@Autowired原理
  @Autowired
  private BookService bookSerivce
  先按照类型去容器中找对应组件bookService = ioc.getBean(BookService.class)
    1) 没找到,抛异常:
    2)找到一个,直接赋值
    3)找到多个,以变量名为Bean的id进行匹配
      (1)找到,进行赋值
      (2)没找到,抛异常
          在此处,我们可以使用@Qualifier("新id")注解来指定新id,这样就可以不按变量名作为id去匹配,而是用我们指定的新id进行匹配
            a. 找到,赋值
            b. 没找到,抛异常
  最终,我们发现,@Autowired注解是一定会将组件注入的,如果不成功的话就报错了,程序就不能正常运行了
  如果确定会发生注入不成功的情况,我们可以指定@Autowired(required = false)来告诉Spring这个注入不是必须的,找不到就不注入

也可以使用@Resource(id)进行注入

@Autowired与@Resource的区别
Autowired是spring自己的注解,Reource是javax包下的注解,即Resource是Java的标准,所有框架都支持
所以在Spring框架中@Autowired和@Resource都是可以使用的,如果换成别的框架@Autowired就不能使用,而@Resource仍然可以使用,所以@Resource扩展性更强

IOC容器的接口:ApplicationContext,即是一个IOC容器

在容器中注册了组件后,组件的创建时机:
单例对象(scope='singleton'或不指定scope)在容器创建完成后也就被创建好了,也就是在我们getBean()时是拿已经创建好的Bean,而不是在getBean()时创建对象,多实例对象(scope='prototype')是每次获取的时候创建一个新的对象

当我们要获取的Bean不存在时会抛出NoSuchBeanDefinitionException异常
Bean的属性名不是由我们写的属性名称决定,而是由getter/setter方法后面的名称决定

向容器中注册组件的方式

一、通过xml进行配置

通过标签声明组件, 声明时为其赋值的方式如下:

  1. 通过标签,它是利用对象的setter方法为Bean的属性赋值。
    (1) 基本属性可以直接在标签属性中设置
    (2) 当bean属性需要引用类型(如其他bean类型)时,可以使用标签属性ref来引用其它定义好的bean
    也可以在标签体内部再定义bean,不过这个内部bean是不可以被其他外部bean引用的
    (3) 定义复杂属性类型,如List,Map,Properties
    直接在标签体中定义对应的标签即可,





    value
  2. 通过构造器标签
  3. 通过p名称空间使用标签属性为bean属性赋值
  4. 可以通过继承其他bean来实现配置信息的重用,在bean标签中指定属性parent="beanID"。但这两个类不是继承关系,只是重用了它的配置
  5. 如果一个bean只是为了用来被其它bean继承,那么可以通过bean标签的abstract属性将其指定为抽象的,这样它就不可以通过getBean()方法获取,可能用来继承配置信息。
  6. 通过工厂来创建Bean
    首先创建工厂类,编写工厂方法
    (1) 静态工厂(即方法是静态的,可以直接通过类名调用)
    声明一个工厂对象,然后使用factory-method来指定使用哪个工厂方法,getBean之后返回的就是工厂方法返回的对象,而不是这个工厂对象
    (2) 动态工厂(方法不是静态的,需要通过类对象来调用)
    需要声明一个工厂对象,然后再声明想要创建的bean对象,然后通过factory-bean指定使用哪个工厂对象和factory-method指定使用哪个方法
    (3) 也可以通过实现FeactoryBean接口来实现工厂
    实现BeactoryBean接口之后要实现三个方法:getObject、getObjectType、isSingleton

二、通过注解进行配置

共有四个注解可以将一个类添加到Spring容器中:Component、Controller、Service、Respority
这四个注解的作用是一样的,只是为了我们程序员好区分类的功能
注意:用注解进行配置时,要在配置文件中配置组件扫描,让spring可以扫描到注解来进行相应配置
<context:component-scan>标签进行组件扫描

  1. 扫描指定目标
    <context:component-scan>标签中写<context:include-filter>来扫描指定的目标,但是注意要把component-scan的默认行为禁用掉,因为它是默认扫描指定目标下的所有,用useDefaultFilter=false将默认行为禁用掉,这样就可以只扫描我们指定的内容
  2. 排除掉指定的目标
    <context:component-scan>标签中写<context:exclude-filter>来排除一些不需要的内容
posted @   程长新  阅读(24)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤
点击右上角即可分享
微信分享提示