Spring的核心知识点

1.什么叫做Spring?

就是一个容器,管理bean的。

2.我们为什么要将bean交给spring管理呢?IOC(控制反转)

一般我们需要什么类,直接就去new了,但是使用spring之后,我们将所需要的类交给spring容器管理,当我们需要这个类的时候直接在容器里面取出来就可以了。

这样的好处在什么地方?

生命周期不需要我们管,不用频繁的去new对象,这样就节省了jvm的堆内存,spring的bean默认是单例的,将类的一些信息放在了方法区,大大的节省了堆内存。

而且起到了一个解耦的作用。a需要b,不用new b,需要的时候spring直接将b给你。举个例子:公司老板依赖的是实现了程序员的人,并不是你,所以他想换你就换你。这个也可以叫做DI(依赖注入,解决对象之间的依赖关系。)

IOC源码执行过程分为三步

1.定位:寻找配置文件的位置

2.加载:找到配置文件,读取配置文件里面的内容

3.注册:把加载以后的配置文件解释成BeanDefinition

DI:依赖注入又分为两步

1.读取BeanDefinition中的信息,获取其依赖信息

2.实例化(代理对象)

总共有两个方法:

createBeanInstance 生成bean所包含的java对象实例,放到ioc容器

populateBean :对bean属性的依赖注入进行处理

如果使用了延时,依赖注入将会发生在getBean方法上。

3.spring管理的bean是线程安全的吗?

不一定,主要看配置,当我们配置bean的时候,scope默认是单例singleton(采用的是饿汉式),他默认走的是无参构造函数,这时候如果对全局变量进行一个写的操作时,就容易发生线程安全问题。如果配置的是scope="prototype"那么每次获取的bean都是一个新的实例。

4.Spring AOP的应用场景:权限控制,事务管理,日志打印,性能统计。

主要解决代码重复的问题。开发的时候将代码拆分,运行时在组合在一起。拆分,合并,解耦。

关注点:重复代码。

切入点:拦截那些方法。就是表达式的管理

切面:抽取重复的代码。关注的重复代码,一个切面就代表着n个bean的一个集合,这n个bean他们都有共同点,所以组成一个切面,比如事物管理的时候就用到了切面的定义(com.xxxxx.service.impl.*)

AOP有哪些通知类型呢?前置通知,后置通知,环绕通知,异常通知。

AOP的底层实现就是动态代理中的cglib+jdk动态代理综合运用:java的三种代理模式

AOP流程

1.加载配置信息,解析成AOPConfig

2.交给AopProxyFactory,调用一个createAopProxy的方法

3.JDkDynamicAopProxy调用AdvisedSupport的getInterceptorsAnd。。方法得到方法拦拦截链,并保存一个容器。

4.递归执行拦截器方法proceed()方法

5.Spring事物分类

事物的特性:原子性(要么一起失败,要么一起成功),一致性(前后保持数据一致,比如转账),隔离性(不受其它事物的影响),持久性(数据一旦改变,就是永久性的)

事物的分类:

编程事物(手动事物):自己写 开启事物,提交事物,回滚事物

声明式事物:xml或者注解

事物的原理:AOP+环绕通知(方法开始:开启事物,方法结束:关闭事物)+异常通知(出现异常:回滚事务)

记住一点:我们在写事物的时候,如果中间逻辑发生错误需要回滚事物的,一定不能try-catch,需要把异常抛出去,这样事物才能回滚。

6.Spring事物的传播行为

比如我一个service方法里面,加入了事物注解,调用了两个dao层的方法,那么。。。。

PROPAGATION_REQUIRED--如果当前没有事务,就新建一个事务。

PROPAGATION_SUPPORTS--(如果当前有事物,我就用当前事物,如果当前没有事物,就以非事物进行执行)
PROPAGATION_MANDATORY--支持当前事务,如果当前没有事务,就抛出异常。 
PROPAGATION_REQUIRES_NEW--新建事务,如果当前存在事务,把当前事务挂起。 
PROPAGATION_NOT_SUPPORTED--以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。 
PROPAGATION_NEVER--以非事务方式执行,如果当前存在事务,则抛出异常。

7.Spring的核心jar包

spring-core      spring的核心jar包(最核心的,所有项目都要依赖)

spring-context spring上下文jar包,包括ioc的具体实现

spring-jdbc       spring和数据库连接的jar包

spring-aop       spring面向切面编程的jar包

spring-beans    spring实例的jar包(定义的是规范)

8.我们使用spring框架,启动web项目很慢的原因?

首先需要加载web.xml,然后初始化servlert,同时我们配置了一个spring的配置文件,这个文件就相当于一个spring容器,管理着所有的bean(当然也可以使用注解和在配置文件里面是一个道理),这时候会去读取这个application.xml文件,dom4j+反射去实例化这些bean,只有这样我们在需要某个类的时候才不会使用new而是直接在容器里面获取,但是我们使用反射的时候就会大量的消耗资源,所以会慢。

9.Spring的上下文作用,拦截器和过滤器?

之前我一直有一个疑惑就是,我们的过滤器与拦截器的区别

1、拦截器是基于java的反射机制的,而过滤器是基于函数回调 
2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 
3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用 
4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能 

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次 

我们依次来解释一下这五句话。。。

1.拦截器基于java的反射,是根据class的路径去加载类,肯定就是java的反射了

<mvc:interceptors>
    <mvc:interceptor>
        <!-- 匹配的是url路径, 如果不配置或/**,将拦截所有的Controller -->
        <mvc:mapping path="/**"/>
        <bean class="com.cckj.util.auth.AuthInterceptor"></bean>
    </mvc:interceptor>
    <!-- 当设置多个拦截器时,先按顺序调用preHandle方法,然后逆序调用每个拦截器的postHandle和afterCompletion方法 -->
</mvc:interceptors>

过滤器是基于函数回调,这个理解起来就比较困难了,其实我们当我们一个路径过来首先进入我们的过滤器,最后又将请求交给了我们的过滤器,执行相应的dofilter方法,实现的filter接口中doFilter方法就是回调函数

<filter>
    <filter-name>WCLoginFilter</filter-name>
    <filter-class>com.bilein.filter.WCLoginFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>WCLoginFilter</filter-name>
    <url-pattern>/app.ZMTManage/wclogin.do</url-pattern>
</filter-mapping>

2、过滤器依赖与servlet容器,而拦截器不依赖与servlet容器 

想一想我们的过滤器是在web.xml中配置,在这个里面我们配置所有的servlert,在application.xml中我们配置所有的bean,所以说过滤器依赖servlet容器,而拦截器并不是在web.xml中配置,所以不依赖与servlet容器。

3、拦截器只能对action请求起作用,而过滤器则可以对几乎所有的请求起作用 

Filter的过滤范围比Interceptor大,Filter除了过滤请求外通过通配符可以保护页面,图片,文件等等。而拦截器只能拦截具体的方法路径。

4、拦截器可以访问action上下文、值栈里的对象,而过滤器不能

什么叫做上下文:就是Spring容器帮我们初始化好的所有的bean就叫做上下文。很显然是和spring容器相关。

过滤器没有放在spring容器中,我们怎么能获取到上下文的对象和值呢?

5、在action的生命周期中,拦截器可以多次被调用,而过滤器只能在容器初始化时被调用一次 

到这里我们能感觉到servlert和spring容器bean有关系了,servlert是线程安全的吗?如果能反思这个问题。我们顺着这个问题往上推,它是不安全的,因为它是单例,所以在初始化的时候只能被调用一次,也就是说整个应用系统只有这一个实例。拦截器action的生命周期是在每次请求时创建一个新的action,所以说它被调用了多次。

10.SpringMVC的执行流程?

11.BeanFactory和FactoryBean之间的区别?

12.AOP

spring aop包是Aspects的上层建筑,主要作用就是在IOC中拿到代理对象,对每一个方法进行重写,我们使用的时候使用的其实就是代理对象。(这个是在了解了代理模式之后,突然间领悟的)

在spring中,do开头方法的都是实际工作的。

13.@AutoWried注解(自动识别类型,自动转型)

它是自动注入,声明的是接口,自动找到接口的实现类,前提接口只有一个实现类。

另外可以根据BeanId来自动装配。

发布了93 篇原创文章 · 获赞 26 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/lizhen1114/article/details/79788271
今日推荐