理解SpringIOC
IOC(Inversion Of Control):控制反转
控制:即对资源(如一个Java类)的获取方式
获取方式可以分为两种
- 主动获取
在Spring之前我们想要获取一个类都是自己创建,即new出这个类对象
如在LoginServlet中需要使用LoginServiceLoginServlet{ LoginService ls = new LoginService();//此时调用LoginService的无参构造创建对象 //下边需要对ls这个对象赋值然后开始使用,如果是一个较简单的对象,那么赋值也比较容易,如果对象复杂,那么赋值也是复杂的,所以赋值这个过程也不怎么友好 }
- 被动获取
即资源不需要我们自己创建,而是交给一个容器来完成创建和设置的工作,我们只需要从容器中取出想要的资源就可以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进行配置
通过
- 通过
标签,它是利用对象的setter方法为Bean的属性赋值。
(1) 基本属性可以直接在标签属性中设置
(2) 当bean属性需要引用类型(如其他bean类型)时,可以使用标签属性ref来引用其它定义好的bean
也可以在标签体内部再定义bean,不过这个内部bean是不可以被其他外部bean引用的
(3) 定义复杂属性类型,如List,Map,Properties
直接在标签体中定义对应的标签即可,
如
value
- 通过构造器标签
- 通过p名称空间使用标签属性为bean属性赋值
- 可以通过继承其他bean来实现配置信息的重用,在bean标签中指定属性parent="beanID"。但这两个类不是继承关系,只是重用了它的配置
- 如果一个bean只是为了用来被其它bean继承,那么可以通过bean标签的abstract属性将其指定为抽象的,这样它就不可以通过getBean()方法获取,可能用来继承配置信息。
- 通过工厂来创建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>
标签进行组件扫描
- 扫描指定目标
在<context:component-scan>
标签中写<context:include-filter>
来扫描指定的目标,但是注意要把component-scan的默认行为禁用掉,因为它是默认扫描指定目标下的所有,用useDefaultFilter=false
将默认行为禁用掉,这样就可以只扫描我们指定的内容 - 排除掉指定的目标
在<context:component-scan>
标签中写<context:exclude-filter>
来排除一些不需要的内容
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek “源神”启动!「GitHub 热点速览」
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· DeepSeek R1 简明指南:架构、训练、本地部署及硬件要求
· 2 本地部署DeepSeek模型构建本地知识库+联网搜索详细步骤