SpringSecurity启动源码WebSecurityConfigurerAdapter分析

SpringSecurity启动源码WebSecurityConfigurerAdapter分析,第1张

SpringSecurity启动源码WebSecurityConfigurerAdapter分析

csrf()将CsrfConfigurer实例放到add进AbstractConfiguredSecurityBuilder的configurers(链表)成员变量中,disable()则是将CsrfConfigurer实例从configurers remove出去,在add之前会判断CsrfConfigurer实例是否已经在configurers中,如果有直接返回,没有则创建这里为啥要disable呢 ,因为我们自定义的规则类的父类WebSecurityConfigurerAdapter的get>

创建对象的第一种方式:利用无参构造器

id:唯一标识符

class:类的全类名

-->

/

Spring 容器利用构造函数创建对象

/

@Test

public void testCreateObjectByConstrutor(){

//1、启动 spring 容器

ApplicationContext context =

new ClassPathXmlApplicationContext("applicationContextxml");

//2、从 spring 容器中取出数据

HelloIoc IOC = (HelloIoc) contextgetBean("helloIoc");

//3、通过对象调用方法

IOCsayHello();

//利用配置文件 alias 别名属性创建对象

HelloIoc IOC2 = (HelloIoc) contextgetBean("helloIoc2");

IOC2sayHello();

}

HelloIocjava 中手动添加无参的构造方法,然后执行上面的测试代码,会发现构造方法会在 sayHello()方法执行之前调用

<xml version="10" encoding="UTF-8">

<beans p=""

xmlns:xsi=">

创建对象的第二种方式:利用静态工厂方法

factory-method:静态工厂类的获取对象的静态方法

class:静态工厂类的全类名

-->

/

Spring 容器利用静态工厂方法创建对象

/

@Test

public void createObjectStaticFactory(){

ApplicationContext context =

new ClassPathXmlApplicationContext("applicationContextxml");

HelloIoc staticFactory =

(HelloIoc) contextgetBean("helloStaticFactory");

staticFactorysayHello();

}

spring容器只负责调用静态工厂方法,而这个静态工厂方法内部实现由程序员完成

利用实例工厂方法

首先创建实例工厂类 HelloInstanceFactory java

public class HelloInstanceFactory {

public HelloInstanceFactory(){

Systemoutprintln("实例工厂方法构造函数");

}

//利用实例工厂方法创建对象

public HelloIoc getInstance(){

HelloIoc instanceIoc = new HelloIoc();

return instanceIoc;

}

}

接着在 applicationContextxml 中进行如下配置:

<!--

创建对象的第三种方式:利用实例工厂方法

factory-bean:指定当前Spring中包含工厂方法的beanID

factory-method:工厂方法名称

-->

/

Spring 容器利用实例工厂方法创建对象

/

@Test

public void createObjectInstanceFactory(){

ApplicationContext context =

new ClassPathXmlApplicationContext("applicationContextxml");

HelloIoc staticFactory =

(HelloIoc) contextgetBean("instance");

staticFactorysayHello();

}

Spring 容器创建对象的时机

默认情况下,启动 spring 容器便创建对象

在spring的配置文件bean中有一个属性 lazy-init="default/true/false"

①、如果lazy-init为"default/false"在启动spring容器时创建对象(默认情况)

②、如果lazy-init为"true",在contextgetBean时才要创建对象

在第一种情况下可以在启动spring容器的时候,检查spring容器配置文件的正确性,如果再结合tomcat,如果spring容器不能正常启动,整个tomcat就不能正常启动。但是这样的缺点是把一些bean过早的放在了内存中,如果有数据,则对内存来是一个消耗。

反过来,在第二种情况下,可以减少内存的消耗,但是不容易发现错误

spring的bean中的scope:"singleton/prototype/request/session/global session"

一、默认scope的值是singleton,即产生的对象是单例的

applicationContextxml 文件中配置:

//spring 容器默认产生对象是单例的 scope="singleton"

@Test

public void test_scope_single_CreateObject(){

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContextxml");

HelloIoc hello1 = (HelloIoc) contextgetBean("helloIoc");

HelloIoc hello2 = (HelloIoc) contextgetBean("helloIoc");

Systemoutprintln(hello1equals(hello2)); //true

}

scope=“prototype”

多例模式,并且spring容器启动的时候并不会创建对象,而是在得到 bean 的时候才会创建对象

applicationContextxml 文件中配置:

总结:在单例模式下,启动 spring 容器,便会创建对象;在多例模式下,启动容器并不会创建对象,获得 bean 的时候才会创建对象

scope=“request” 每次>

$pngname = $openid'png';

if(imagepng($QR, $pngname)){

imagedestroy($QR);

$qrurl = W_DOMAIN''$pngname;

$this->assign('qrcode',$qrurl);

$this->display();

}

概述 :Spring ioc容器加载过程相对复杂,在阅读源码时候可以将其划分为几个小流程 和一个总体流程,这样对源码的阅读以及理解会简单很多,大体如下:

ioc容器创建主主流程

beanfactory获取子流程

beanDefinition加载过程

bean创建过程

懒加载机制

循环依赖的处理

这里讲述ioc容器的基础知识以及总体流程

IoC Inversion of Control (控制反转/反转控制),注意它是⼀个技术思想,不是⼀个技术实现

描述的事情 :Java开发领域对象的创建,管理的问题

传统开发⽅式 :⽐如类A依赖于类B,往往会在类A中new⼀个B的对象

IoC思想下开发⽅式 :我们不⽤⾃⼰去new对象了,⽽是由IoC容器(Spring框架)去帮助我们实例化对

象并且管理它,我们需要使⽤哪个对象,去问IoC容器要即可

我们丧失了⼀个权利(创建、管理对象的权利),得到了⼀个福利(不⽤考虑对象的创建、管理等⼀系列

事情)

为什么叫做控制反转?

控制 :指的是对象创建(实例化、管理)的权利

反转 :控制权交给外部环境了(spring框架、IoC容器)

 IoC和DI的区别

DI:Dependancy Injection(依赖注⼊)IOC和DI描述的是同⼀件事情,只不过⻆度不⼀样罢了

lazy-Init 延迟加载

ApplicationContext 容器的默认⾏为是在启动服务器时将所有 singleton bean 提前进⾏实例化。提前

实例化意味着作为初始化过程的⼀部分,ApplicationContext 实例会创建并配置所有的singleton

bean。lazy-init="false",⽴即加载,表示在spring启动时,⽴刻进⾏实例化。

 FactoryBean 和 BeanFactory

BeanFactory接⼝是容器的顶级接⼝,定义了容器的⼀些基础⾏为,负责⽣产和管理Bean的⼀个⼯⼚,

具体使⽤它下⾯的⼦接⼝类型,⽐如ApplicationContext;此处我们重点分析FactoryBean

Spring中Bean有两种,⼀种是普通Bean,⼀种是⼯⼚Bean(FactoryBean),FactoryBean可以⽣成

某⼀个类型的Bean实例(返回给我们),也就是说我们可以借助于它⾃定义Bean的创建过程。

Bean创建的三种⽅式中的静态⽅法和实例化⽅法和FactoryBean作⽤类似,FactoryBean使⽤较多,尤

其在Spring框架⼀些组件中会使⽤,还有其他框架和Spring框架整合时使⽤

后置处理器

Spring提供了两种后处理bean的扩展接⼝,分别为 BeanPostProcessor 和

BeanFactoryPostProcessor,两者在使⽤上是有所区别的。

⼯⼚初始化(BeanFactory)—> Bean对象

在BeanFactory初始化之后可以使⽤BeanFactoryPostProcessor进⾏后置处理做⼀些事情

在Bean对象实例化(并不是Bean的整个⽣命周期完成)之后可以使⽤BeanPostProcessor进⾏后置处

理做⼀些事情

注意:对象不⼀定是springbean,⽽springbean⼀定是个对象

SpringBean的⽣命周期

BeanPostProcessor:

BeanPostProcessor是针对Bean级别的处理,可以针对某个具体的Bean

该接⼝提供了两个⽅法,分别在Bean的初始化⽅法前和初始化⽅法后执⾏,具体这个初始化⽅法指的是什么⽅法,类似我们在定义bean时,定义了init-method所指定的⽅法,定义⼀个类实现了BeanPostProcessor,默认是会对整个Spring容器中所有的bean进⾏处理。如果要对具体的某个bean处理,可以通过⽅法参数判断,两个类型参数分别为Object和String,第⼀个参数是每个bean的实例,第⼆个参数是每个bean的name或者id属性的值。所以我们可以通过第⼆个参数,来判断我们将要处理的具体的bean。

注意:处理是发⽣在Spring容器的实例化和依赖注⼊之后。

BeanFactoryPostProcessor

beanFactory级别的处理,是针对整个Bean的⼯⼚进⾏处理,

BeanDefinition对象 :我们在 XML 中定义的 bean标签,Spring 解析 bean 标签成为⼀个 JavaBean,

这个JavaBean 就是 BeanDefinition

注意 :调⽤ BeanFactoryPostProcessor ⽅法时,这时候bean还没有实例化,此时 bean 刚被解析成

BeanDefinition对象

  IoC容器是Spring的核⼼模块,是抽象了对象管理、依赖关系管理的框架解决⽅案。Spring 提供了很多的容器,其中 BeanFactory 是顶层容器(根容器),不能被实例化,它定义了所有 IoC 容器 必须遵从的⼀套原则,具体的容器实现可以增加额外的功能,⽐如我们常⽤到的ApplicationContext,其下更具体的实现ClassPathXmlApplicationContext 包含了解析 xml 等⼀系列的内容其中beanfactory提供了主体方法,其他接口分别实现他的同时又有自己相对应的一些扩展方法  将相类似的功能分别放在不同接口 避免了大量重写方法的困扰

Spring IoC 容器初始化的关键环节就在 AbstractApplicationContext#refresh() ⽅法中查看 refresh ⽅法来俯瞰容器创建的主体流程

大致流程如下

在本文中,我们将详细介绍从BeanFactory中获取bean的多种方式。

简单地说,正如方法的名称所表达的, getBean() 负责从Spring IOC容器中获取bean实例。

首先,让我们定义一些用于测试的Spring bean。创建spring IOC容器有多种方式,但是在本文中,我们将使用基于注释的Java配置:

我们创建了两个bean。 Lion 具有默认的单例作用域。Tiger被显式地设置为 prototype 。另外,我们为每个bean定义了名称,这些名称将在后边的实例中使用。

BeanFactory提供了getBean()方法的5个方法,我们将在下面的小节中研究。

让我们看看如何使用名称获取 Lion Bean实例:

在此方法中,我们根据bean名称获取bean,如果在spring ico容器中存在和bean,则返回 Object 类的实例。否则,抛出如下异常NoSuchBeanDefinitionException。

主要的缺点是,在获取bean之后,我们必须将它转换为所需的类型。如果返回的bean的类型与我们期望的不同,则可能会产生异常。

假设我们试图用“tiger”这个名字来得到“lion”。当我们将结果转换为lion时,它会抛出一个ClassCastException:

在这里,我们需要指定所请求bean的名称和类型:

与31的方法相比,此方法更安全,因为我们可以编译阶段就发现错误而不是在运行阶段。

使用 getBean() 的第三种方式, 仅指定bean类型就足够了

在这种情况下,我们需要 特别注意可能存在的歧义

在上面的示例中,由于 Lion 和 Tiger都 实现了 Animal 接口,因此仅指定类型不足以明确确定结果。因此,我们得到一个 NoUniqueBeanDefinitionException 。即在同一个IOC 容器中,如果有相同类型的多个bean,则不能通过类型获取bean。

除了bean名称,我们还可以传递构造函数参数:

这个方法有点不同,因为它只适用于具有原型作用域的bean。

在单例的情况下,我们将得到BeanDefinitionStoreException异常。

因为原型bean,每次从spring ioc容器中获取bean都会返回一个新创建的实例,所以我们可以在调用getBean()时动态地提供构造函数参数:

正如我们所看到的,根据我们在请求bean时指定的第二个参数,每个Tiger都有不同的名称。

此方法类似于上一个方法,但是我们需要将类型而不是名称作为第一个参数传递:

与34相似, 此方法仅适用于具有原型作用域的bean

getBean()尽管是在BeanFactory接口中定义的,但是getBean()方法大部分是通过ApplicationContext访问。通常,我们在应用程序中不希望直接使用getBean()方法。

Bean应该由容器管理。如果我们想使用它们中的一个,我们应该依赖依赖注入,而不是直接调用ApplicationContextgetBean()。这样,我们就可以避免将应用程序逻辑与与框架相关的细节混合在一起。

在本快速教程中,我们从 BeanFactory 接口浏览了 getBean() 方法的所有实现,并描述了每种方法的优缺点。

     IoC(Inverse of Control:控制反转)是⼀种设计思想,就是 将原本在程序中⼿动创建对象的控制权,交由Spring框架来管理。

      IoC 在其他语⾔中也有应⽤,并⾮ Spring 特有。 IoC 容器是 Spring⽤来实现 IoC 的载体, IoC 容器实际上就是个Map(key,value),Map 中存放的是各种对象。将对象之间的相互依赖关系交给 IoC 容器来管理,并由 IoC 容器完成对象的注⼊。这样可以很⼤程度上简化应⽤的开发,把应⽤从复杂的依赖关系中解放出来。 

    IoC 容器就像是⼀个⼯⼚⼀样,当我需要创建⼀个对象的时候,只需要配置好配置⽂件/注解即可,完全不⽤考虑对象是如何被创建出来的。在实际项⽬中⼀个 Service 类可能有⼏百甚⾄上千个类作为它的底层,假如我们需要实例化这个Service,你可能要每次都要搞清这个 Service 所有底层类的构造函数,这可能会把⼈逼疯。如果利⽤IoC 的话,你只需要配置好,然后在需要的地⽅引⽤就⾏了,这⼤⼤增加了项⽬的可维护性且降低了开发难度。

  我们来看看执行过程:

   1  读取Bean配置信息放入Bean定义注册表

    2 根据Bean注册表实例化Bean

    3 将实例化之后的bean实例放入Bean缓存池(HashMap实现)

    4 应用程序通过类名从Bean缓存池中取出Bean实例

     工厂模式(Factory Pattern)。工厂模式可将Java对象的调用者从被调用者的实现逻辑中分离出来。工厂模式是Java中最常用的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。在工厂模式中,我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

     这么讲可能有点抽象,简单的说就是以后我们不用自己new对象了,对象的实例化都交给工厂来完成,我们需要对象的时候直接问工厂拿一个就行,一会我们会来看一个例子。在这里有一点要说明,spring IOC与工厂模式并不是完全相同的,最大的不同在于普通的工厂模式内部还是使用new来创建对象,但是spring IOC是用反射来创建对象,这么做有什么好处呢?

     反射就在这一句上,我们通过类的全类名来创建了对象,全类名来自于我们的Properties对象,也就是读取我们的配置文件产生的对象,对标spring IOC容器中的Bean定义注册表。

以上就是关于SpringSecurity启动源码WebSecurityConfigurerAdapter分析全部的内容,包括:SpringSecurity启动源码WebSecurityConfigurerAdapter分析、Spring详解(二)、spring怎么加载配置文件并启动ioc容器等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/9564290.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-04-29
下一篇2023-04-29

发表评论

登录后才能评论

评论列表(0条)

    保存