Java安全--Spring框架基础学习
Spring–IOC
简介
spring的核心思想是IOC和AOP,IoC - Inversion of Control, 控制反转,通俗点说就是把创建和管理bean的过程转移给了第三方。而这个第三方就是我们说的IOC容器。
Spring容器将创建对象,把它们连接在一起,配置它们,并管理他们的整个生命周期从创建到销毁。控制着bean的依赖注入。
那么这里为什么要叫做控制反转呢?
我们先来对比下两种不同的获取外部对象的资源的方法。
- 主动去创建相关对象然后再组合。
- IOC/DI容器中
在 Spring 中,类的实例化、依赖的实例化、依赖的传入都交由 Spring Bean 容器控制,而不是用new
方式实例化对象、通过非构造函数方法传入依赖等常规方式。实质的控制权已经交由程序管理,而不是程序员管理,所以叫做控制反转。
例子
有一个Book
类:
1 | public class Book { |
Person
类依赖于Book
类,
1 | public class Person { |
因为IoC容器要负责实例化所有的组件,因此,有必要告诉容器如何创建组件,以及各组件的依赖关系。一种最简单的配置是通过XML文件来实现,例如:
1 | <beans> |
上述XML配置文件指示IoC容器创建3个JavaBean组件,并把id为dataSource
的组件通过属性dataSource
(即调用setDataSource()
方法)注入到另外两个组件中。
总结
在Spring的IoC容器中,我们把所有组件统称为JavaBean,即配置一个组件就是配置一个Bean,控制反转通过依赖注入(DI)方式实现对象之间的松耦合关系。
Spring–Bean
简介
spring官方文档对bean的解释是:在spring中,构成应用程序主干并由Spring IoC容器管理的对象称为bean。bea是一个由Spring IoC容器实例化、组装和管理的对象。
bean主要包含以下几个概念:
- Bean容器,或称spring ioc容器,主要用来管理对象和依赖,以及依赖的注入。
- bean是一个java对象,根据bean规范编写出来的类,并由bean容器生成的对象就是一个bean。
- bean规范
Bean实例化
1.普通构造方法创建
使用比较多的一种创建方式,可以直接配置bean节点,例如:
1 | public class Demo { |
在xml中简单配置一个bean节点,如下:
1 | <bean class="org.test.Demo" id="test"/> |
通过以下代码进行简单的测试:
1 | ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); |
2.静态工厂创建
通过静态构造方法来创建一个bean的实例,如下:
1 | public class Demo2 { |
创建一个静态工厂,如下:
1 | public class Demo2Factory { |
该工厂中有一个静态方法,该静态方法返回一个的实例,通过Spring的配置文件生成Demo2的实例:
1 | <bean id="demo2" class="org.test.demo2Factory" factory-method="getInstance"/> |
factory-method属性,该属性指明该类中的静态工厂方法名为getInstance,spring框架根据属性来调用方法来获取Demo2的实例了,测试代码如下:
1 |
|
实例工厂创建
通过实例工厂来创建bean实例,例如:
1 | public class Demo3 { |
同时有一个工厂方法,如下:
1 | public class Demo3Factory { |
在Demo3Factory类中有一个getDemo3的方法,该方法返回一个Demo3类的实例,Spring的配置文件如下:
1 | <bean class="org.test.Demo3Factory" id="demo3Factory"/> |
第一个bean用来获取demo3Factory的实例,第二个bean则根据demo3Factory的实例,然后指定factory-method,通过getDemo3方法来获取Demo3的实例。
测试代码如下:
1 |
|
Bean作用域
spring bean 一共有五种作用域。
1.Singleton (缺省作用域、单例类型)
容器中只存在一个共享的Bean,只要id与Bean定义相匹配,那就会是同一个Bean。在容器启动(实例化)时Bean就实例化和初始化(可以通过lazy-init=”true”来设置使得Bean被调用时才初始化)。
2.Prototype (原型类型)
对有状态的Bean建议使用Prototype,对无状态建议使用Singleton。
容器启动时并没有实例化Bean,只有获取Bean时才会被创建,并且每一次都是新建一个对象。
3.request(web的Spring ApplicationContext)
每个HTTP 都会有自己的Bean,当处理结束时,Bean销毁。
4.session(web的Spring ApplicationContext)
每一个Http session有自己的Bean
5.global session(web的Spring ApplicationContext)
global session作用域类似于标准的HTTP Session作用域,不过仅仅在基于portlet的web应用中才有意义。Portlet规范定义了全局Session的概念,它被所有构成某个portlet web应用的各种不同的portlet所共享。在global session作用域中定义的bean被限定于全局portlet Session的生命周期范围内。
Bean生命周期
Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。
单例管理的对象
Bean在容器启动时就会实例化和初始化,但是可以通过Bean的设置来设置对象的初始化时机
第一种:通过设置
1 | <bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" lazy-init="true"/> |
第二种:通过设置
1 | <beans default-lazy-init="true"> |
非单例管理的对象
Spring读取xml文件的时候,并不会立刻创建对象,而是在第一次请求该bean时才初始化(如调用getBean方法时)。容器只会实例化和初始化Bean,不会销毁Bean。清除prototype作用域的对象并释放任何prototype bean所持有的昂贵资源,都是客户端代码的职责。在初始化后交由调用者管理
Spring–依赖注入(DI)
简介
依赖注入(Dependency Injection,DI),和控制反转含义相同,它们是从两个角度描述的同一个概念。
当某个java实例(调用者)需要另一个java实例(被调用者),我们通常采用的方法是由调用者来创建被调用者的实例。(使用new关键字获得被调用者的实例)。
在spring中,spring在创建被调用者的实例时,会自动将调用者需要的对象实例注入给调用者,调用者通过spring容器获得被调用者实例,被称为依赖注入。
注入方式(bean装配)
依赖注入的本质就是装配,装配是依赖注入的具体行为。在Spring中,注入依赖对象可以采用手工装配或自动装配。
手工装配一般分为两种方式:
一种是在XML文件中,通过在bean节点下配置;比如使用属性的setter方法注入依赖对象或者使用构造方法注入。
一种就是在java代码中使用注解的方式进行装配,在代码中加入@Resource或者@Autowired。
setter方法注入
由于setter注入方式具有可选择性和灵活性高的特点,因此它也是实际开发中最常用的注入方式。setter方法更加直观,我们来看一下spring的配置文件:
1 | <!-- 使用spring管理对象的创建,还有对象的依赖关系 --> |
接着我们来看一下,setter表示依赖关系的写法
1 | import com.tgb.spring.dao.UserDao; |
构造函数注入
构造函数注入是除setter注入之外的另一种常用的注入方式,它可以保证一些必要的属性在bean实例化时就得到了设置,并在实例化后就可以使用。
使用构造函数注入的前提是: bean必须提供带参的构造函数。
对于构造函数的注入,配置文件可以有以下几种方式:
- 按类型匹配入参
- 按索引匹配入参
- 联合使用类型和索引匹配入参
- 通过自身类型反射匹配入参
我们看一下spring的配置文件:
1 |
|
我们再来看一下,构造器表示依赖关系的写法,代码如下所示:
1 | import com.tgb.spring.dao.UserDao; |
基于注解
使用注解注入依赖对象不用再在代码中写依赖对象的setter方法或者该类的构造方法,并且不用再配置文件中配置大量的依赖对象,使代码更加简洁,清晰,易于维护。
在Spring IOC编程的实际开发中推荐使用注解的方式进行依赖注入。
- Autowired是自动注入,自动从spring的上下文找到合适的bean来注入
- Resource用来指定名称注入
- Qualifier和Autowired配合使用,指定bean的名称,如
1 | @Autowired |
Spring容器的配置文件applicationContext.Xml文件中配置以下信息,是一个Spring配置文件的模板:
1 |
|
Spring配置隐式的注册了多个对注释进行解析的处理器,例如:
- AutowiredAnnotationBeanPostProcessor
- CommonAnnotationBeanPostProcessor
- PersistenceAnnotationBeanPostProcessor
在配置文件中打开context:annotation-config节点,告诉Spring容器可以用注解的方式注入依赖对象;其在配置文件中的代码如下:
1 | <beans><context:annotation-config></context:annotation-config></beans> |
在配置文件中配置bean对象,如下:
1 | <bean id="userDao" class="com.springtest.dao.impl.UserDAOImpl"></bean> |
最后,在需要依赖注入的类中,声明一个依赖对象,不用生成该依赖对象的setter方法,并且为该对象添加注解:
1 | public class UserBizImpl implements UserBiz { |
@Autowired默认按类型装配,@Resource默认按名称装配,当找不到与名称匹配的bean时,才会按类型装配。
控制反转与依赖注入的区别
依赖注入和控制反转是对同一件事情的不同描述,
依赖注入是从应用程序的角度在描述:应用程序依赖容器创建并注入它所需要的外部资源;
控制反转是从容器的角度在描述:容器控制应用程序,由容器反向的向应用程序注入应用程序所需要的外部资源。
参考文章
详解Spring中bean的几种注入方式 - 编程语言 - 亿速云 (yisu.com)
https://www.w3cschool.cn/wkspring
(15条消息) Spring Bean自动装配和注解注入_似水流年-CSDN博客
Author: Shu1L
Link: https://shu1l.github.io/2021/02/12/java-an-quan-spring-ji-chu-xue-xi/
License: 知识共享署名-非商业性使用 4.0 国际许可协议