Spring基础知识总结

1. Spring基本介绍

1、Spring 是轻量级的开源的 JavaEE 框架

2、Spring 可以解决企业应用开发的复杂性

3、Spring 有两个核心部分:IOC 和 Aop

1)IOC:控制反转,把创建对象过程交给 Spring 进行管理

2)Aop:面向切面,不修改源代码进行功能增强

4、Spring 特点

  • 方便解耦,简化开发

    Spring 提供了 Ioc 控制反转,由容器管理对象,对象的依赖关系。原来在程序代码中的 对象创建方式,现在由容器完成。对象之间的依赖解耦合。

  • Aop 编程支持

  • 方便程序测试

  • 方便和其他框架进行整合

  • 方便进行事务操作

  • 降低 API 开发难度

1、Spring 框架有哪些主要模块?

Spring有七大功能模块:

  1. Core:Core模块是Spring的核心类库,Core实现了IOC功能。

  2. AOP:Apring AOP模块是Spring的AOP库,提供了AOP(拦截器)机制,并提供常见的拦截器,供用户自定义和配置。

  3. orm:提供对常用ORM框架的管理和支持,hibernate、mybatis等。

  4. Dao:Spring提供对JDBC的支持,对JDBC进行封装。

  5. Web:对Struts2的支持。

  6. Context:Context模块提供框架式的Bean的访问方式,其它程序可以通过Context访问Spring的Bean资源,相当于资源注入。

  7. MVC:MVC模块为spring提供了一套轻量级的MVC实现,即Spring MVC。

2、使用 Spring 框架能带来哪些好处?

1、轻量级框架、容器

Spring是一个容器,管理对象的生命周期和配置。基于一个可配置原型prototype,你的bean可以使单利的,也可以每次需要时都生成一个新的实例。

2、控制反转IOC

Spring通过控制反转实现松耦合。

3、支持AOP

Spring提供对AOP的支持,它允许将一些通用任务,如安全、事务、日志等进行集中式处理,从而提高了程序的复用性。

4、方便测试

Spring提供Junit4的支持,可以通过注解方便测试spring程序。

5、对Java中很多API进行了封装

6、方便集成各种优秀框架

如Struts、hibernate、mybstis。

7、支持声明式事务处理

只需通过配置就可以完成对事务的管理,而无须手动编程。

2. IOC

1、什么是 IOC

IOC,Inversion of Control,控制反转,指将对象的控制权转移给Spring框架,由 Spring 来负责控制对象的生命周期(比如创建、销毁)和对象间的依赖关系。

最直观的表达就是,以前创建对象的时机和主动权都是由自己把控的,如果在一个对象中使用另外的对象,就必须主动通过new指令去创建依赖对象,使用完后还需要销毁(比如Connection等),对象始终会和其他接口或类耦合起来。而 IOC 则是由专门的容器来帮忙创建对象,将所有的类都在 Spring 容器中登记,当需要某个对象时,不再需要自己主动去 new 了,只需告诉 Spring 容器,然后 Spring 就会在系统运行到适当的时机,把你想要的对象主动给你。也就是说,对于某个具体的对象而言,以前是由自己控制它所引用对象的生命周期,而在IOC中,所有的对象都被 Spring 控制,控制对象生命周期的不再是引用它的对象,而是Spring容器,由 Spring 容器帮我们创建、查找及注入依赖对象,而引用对象只是被动的接受依赖对象,所以这叫控制反转。

2、什么是DI

IOC 的一个重点就是在程序运行时,动态的向某个对象提供它所需要的其他对象,这一点是通过DI(Dependency Injection,依赖注入)来实现的,即应用程序在运行时依赖 IoC 容器来动态注入对象所需要的外部依赖。而 Spring 的 DI 具体就是通过反射实现注入的,反射允许程序在运行的时候动态的生成对象、执行对象的方法、改变对象的属性。

3、IOC 底层原理

xml 解析、工厂模式、反射

4、IOC(BeanFactory 接口)

1、IOC 思想基于 IOC 容器完成,IOC 容器底层就是对象工厂

2、Spring 提供 IOC 容器实现两种方式:(两个接口)

1)BeanFactory:IOC 容器基本实现,是 Spring 内部的使用接口,不提供开发人员进行使用

  • 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象

    BeanFactory fb = new ClassPathXmlApplicationContext(config);
    SomeService proxy = (SomeService) fb.getBean("someService");//获取对象时创建对象 

2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人 员进行使用

  • 加载配置文件时候就会把在配置文件对象进行创建

    //加载配置文件时对象进行创建
    ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
    SomeService proxy = (SomeService) ctx.getBean("someService");

3、ApplicationContext 接口有实现类

 

3. AOP

1、AOP理解

AOP,一般称为面向切面,作为面向对象的一种补充,用于将那些与业务无关,但却对多个对象产生影响的公共行为和逻辑,抽取并封装为一个可重用的模块,这个模块被命名为“切面”(Aspect),减少系统中的重复代码,降低了模块间的耦合度,提高系统的可维护性。可用于权限认证、日志、事务处理。

AOP 底层使用动态代理

1)有两种情况动态代理

第一种 有接口情况,使用 JDK 动态代理

JDK动态代理只提供接口的代理,不支持类的代理,要求被代理类实现接口。JDK动态代理的核心是InvocationHandler接口和Proxy类,在获取代理对象时,使用Proxy类来动态创建目标类的代理类(即最终真正的代理类,这个类继承自Proxy并实现了我们定义的接口),当代理对象调用真实对象的方法时, InvocationHandler 通过invoke()方法反射来调用目标类中的代码,动态地将横切逻辑和业务编织在一起。

第二种 没有接口情况,使用 CGLIB 动态代理

如果被代理类没有实现接口,那么Spring AOP会选择使用CGLIB来动态代理目标类。CGLIB(Code Generation Library),是一个代码生成的类库,可以在运行时动态的生成指定类的一个子类对象,并覆盖其中特定方法并添加增强代码,从而实现AOP。CGLIB是通过继承的方式做的动态代理,因此如果某个类被标记为final,那么它是无法使用CGLIB做动态代理的。

2、AOP 编程术语

1)连接点

类里面哪些方法可以被增强,这些方法称为连接点

2)切入点

实际被真正增强的方法,称为切入点

被标记为 final 的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不能被增强的。

3)切面

被抽取出来的公共模块,可以用来会横切多个对象。如事务处理、日志处理就可以理解为切面。实际就是对主业务逻辑的一种增强。

4)目标对象

目 标 对 象 指 将 要 被 增 强 的 对 象 。 即 包 含 主 业 务 逻 辑 的 类 的 对 象 。

5)通知

通知表示切面的执行时间,Advice 也叫增强。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是之后执行等。通知类型不同,切入时间不同。

3、Spring通知(Advice)有哪些类型?

1)前置通知(Before Advice):在目标方法执行之前执行的通知。

2)后置通知(AfterReturning Advice):在目标方法执行之后执行。由于是目标方法之后执行,所以可以获取到目标方法的返回值。

3)环绕通知(Around Advice):在目标方法执行之前之后执行。被注解为环绕增强的方法要有返回值,Object 类型。并且方法包含一个 ProceedingJoinPoint 类型的参数。接口 ProceedingJoinPoint 其有一个 proceed()方法,用于执行目标方法。若目标方法有返回值,则该方法的返回值就是目标方法的返回值。最后,环绕增强方法将其返回值返回。该增强方法实际是拦截了目标方法的执行。

4)抛出异常后通知(AfterThrowing advice):在目标方法抛出异常后执行。

5)最终通知(After Advice):无论目标方法是否抛出异常,该增强均会被执行。

4. BeanFactory和ApplicationContext有什么区别?

Spring 提供 IOC 容器实现两种方式:(两个接口)

1)BeanFactory:IOC 容器基本实现,是Spring里面最底层的接口,包含了各种Bean的定义,读取bean配置文档,管理bean的加载、实例化,控制bean的生命周期,维护bean之间的依赖关系。是 Spring 内部的使用接口,不提供开发人员进行使用。

  • 加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象

    BeanFactory fb = new ClassPathXmlApplicationContext(config);
    SomeService proxy = (SomeService) fb.getBean("someService");//获取对象时创建对象 

2)ApplicationContext:BeanFactory 接口的子接口,提供更多更强大的功能,一般由开发人员进行使用

  • 加载配置文件时候就会把在配置文件对象进行创建

    //加载配置文件时对象进行创建
    ApplicationContext ctx = new ClassPathXmlApplicationContext(config);
    SomeService proxy = (SomeService) ctx.getBean("someService");

相当BeanFactory额外的功能

  • 继承MessageSource,因此支持国际化。

  • 统一的资源文件访问方式。

  • 提供在监听器中注册bean的事件。

  • 同时加载多个配置文件。

  • 载入多个(有继承关系)上下文 ,使得每一个上下文都专注于一个特定的层次,比如应用的web层。

3)ApplicationContext启动后预载入所有的单实例Bean,所以在运行的时候速度比较快,因为它们已经创建好了。相对于BeanFactory,ApplicationContext 唯一的不足是占用内存空间,当应用程序配置Bean较多时,程序启动较慢。

4)BeanFactory通常以编程的方式被创建,ApplicationContext还能以声明的方式创建,如使用ContextLoader。

5)BeanFactory和ApplicationContext都支持BeanPostProcessor、BeanFactoryPostProcessor的使用,但两者之间的区别是:BeanFactory需要手动注册,而ApplicationContext则是自动注册。

5. Spring Bean的生命周期

  1. 通过构造器创建 bean 实例(无参数构造)

  2. 为 bean 的属性设置值和对其他 bean 引用(调用 set 方法)

  3. 把 bean 实例传递 bean 后置处理器的方法 postProcessBeforeInitialization

  4. 调用 bean 的初始化的方法(需要进行配置初始化的方法)

  5. 把 bean 实例传递 bean 后置处理器的方法 postProcessAfterInitialization

  6. bean 可以使用了(对象获取到了)

  7. 当容器关闭时候,调用 bean 的销毁的方法(需要进行配置销毁的方法)

6. Spring中bean的作用域

1)singleton:默认作用域,单例bean,每个容器中只有一个bean的实例。

2)prototype:为每一个bean请求创建一个实例,多实例。

3)request:为每一个request请求创建一个实例,在请求完成以后,bean会失效并被垃圾回收器回收。

4)session:与request范围类似,同一个session会话共享一个实例,不同会话使用不同的实例。

5)global-session:全局作用域,所有会话共享一个实例。如果想要声明让所有会话共享的存储变量的话,那么这全局变量需要存储在global-session中。

7. Spring框架中的Bean是线程安全的么?如果线程不安全,那么如何处理?

Spring容器本身并没有提供Bean的线程安全策略,因此可以说Spring容器中的Bean本身不具备线程安全的特性,但是具体情况还是要结合Bean的作用域来讨论。

1)对于prototype作用域的Bean,每次都创建一个新对象,也就是线程之间不存在Bean共享,因此不会有线程安全问题。

2)对于singleton作用域的Bean,所有的线程都共享一个单例实例的Bean,因此是存在线程安全问题的。但是如果单例Bean是一个无状态Bean,也就是线程中的操作不会对Bean的成员执行查询以外的操作,那么这个单例Bean是线程安全的。比如Controller类、Service类和Dao等,这些Bean大多是无状态的,只关注于方法本身。

  • 有状态Bean(Stateful Bean) :就是有实例变量的对象,可以保存数据,是非线程安全的。

  • 无状态Bean(Stateless Bean):就是没有实例变量的对象,不能保存数据,是不变类,是线程安全的。

对于有状态的bean(比如Model和View),就需要自行保证线程安全,最浅显的解决办法就是将有状态的bean的作用域由“singleton”改为“prototype”。也可以采用ThreadLocal解决线程安全问题,为每个线程提供一个独立的变量副本,不同线程只操作自己线程的副本变量。

ThreadLocal和线程同步机制都是为了解决多线程中相同变量的访问冲突问题。同步机制采用了“时间换空间”的方式,仅提供一份变量,不同的线程在访问前需要获取锁,没获得锁的线程则需要排队。而ThreadLocal采用了“空间换时间”的方式。ThreadLocal会为每一个线程提供一个独立的变量副本,从而隔离了多个线程对数据的访问冲突。因为每一个线程都拥有自己的变量副本,从而也就没有必要对该变量进行同步了。

8. Spring基于xml注入bean的几种方式

  • set()方法注入

  • 构造器注入:①通过index设置参数的位置;②通过type设置参数类型

  • 静态工厂注入

  • 实例工厂

9. Spring的自动装配

1)在Spring框架xml配置中共有5种自动装配:

  • no:默认的方式是不进行自动装配的,通过手工设置ref属性来进行装配bean。

  • byName:通过bean的名称进行自动装配,如果一个bean的 property 与另一bean 的name 相同,就进行自动装配。

  • byType:通过参数的数据类型进行自动装配。

  • constructor:利用构造函数进行装配,并且构造函数的参数通过byType进行装配。

  • autodetect:自动探测,如果有构造方法,通过 construct的方式自动装配,否则使用 byType的方式自动装配。

2)基于注解的自动装配方式:

使用@Autowired、@Resource注解来自动装配指定的bean。在使用这些注解之前需要在Spring配置文件进行配置组件扫描器<context:component-scan base-package="项目中的包名" />。在启动spring IoC时,容器自动装载了一个AutowiredAnnotationBeanPostProcessor后置处理器,当容器扫描到@Autowied、@Resource或@Inject时,就会在IoC容器自动查找需要的bean,并装配给该对象的属性。

1、在使用@Autowired时,首先在容器中查询对应类型的bean:

  • 如果查询结果刚好为一个,就将该bean装配给@Autowired指定的数据

  • 如果查询的结果不止一个,那么@Autowired会根据名称来查找

  • 如果上述查找的结果为空,那么会抛出异常。解决方法时,使用required=false

2、@Autowired和@Resource之间的区别:

  • @Autowired默认是按照类型装配注入的,默认情况下它要求依赖对象必须存在(可以设置它required属性为false)

  • @Resource默认是按照名称来装配注入的,只有当找不到与名称匹配的bean才会按照类型来装配注入

10. Spring事务的实现方式和实现原理

Spring事务的本质其实就是数据库对事务的支持,没有数据库的事务支持,spring是无法提供事务功能的。Spring只提供统一事务管理接口,具体实现都是由各数据库自己实现,数据库事务的提交和回滚是通过 redo log 和 undo log实现的。Spring会在事务开始时,根据当前环境中设置的隔离级别,调整数据库隔离级别,由此保持一致。

1)Spring事务的种类

  • 编程式事务管理使用TransactionTemplate。

  • 声明式事务管理建立在AOP之上的。其本质是通过AOP功能,对方法前后进行拦截,将事务处理的功能编织到拦截的方法中,也就是在目标方法开始之前启动一个事务,在执行完目标方法之后根据执行情况提交或者回滚事务。

    声明式事务最大的优点就是不需要在业务逻辑代码中掺杂事务管理的代码,只需在配置文件中做相关的事务规则声明或通过@Transactional注解的方式,便可以将事务规则应用到业务逻辑中,减少业务代码的污染。唯一不足地方是,最细粒度只能作用到方法级别,无法做到像编程式事务那样可以作用到代码块级别。

2)spring的事务传播机制

所谓事务传播行为是指,处于不同事务中的方法在相互调用时,执行期间事务的维护情况。如 A 事务中的方法 doSome()调用 B 事务中的方法 doOther(),在调用执行期间事务的维护情况,就称为事务传播行为。

spring七种传播行为

  • PROPAGATION_REQUIRED:(默认传播行为)如果当前没有事务,就创建一个新事务;如果当前存在事务,就加入该事务。

  • PROPAGATION_REQUIRES_NEW:无论当前存不存在事务,都创建新事务进行执行。

  • ROPAGATION_SUPPORTS:如果当前存在事务,就加入该事务;如果当前不存在事务,就以非事务执行。

  • PROPAGATION_NOT_SUPPORTED:以非事务方式执行操作,如果当前存在事务,就把当前事务挂起。

  • PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内执行;如果当前没有事务,则启动一个新的事务,并在它自己的事务内运行。

  • PROPAGATION_MANDATORY:当前方法必须运行在事物内部,如果没有正在运行的事务,就抛出异常。

  • PROPAGATION_NEVER:当前方法不应该运行在事物中,如果有运行的事务,就抛出异常。

3)Spring中的隔离级别

  • READ-UNCOMMITTED(读取未提交): 最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读。

  • READ-COMMITTED(读取已提交): 允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生。

  • REPEATABLE-READ(可重复读): 对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生。

  • SERIALIZABLE(可串行化): 最高的隔离级别,完全服从ACID的隔离级别。所有的事务依次逐个执行,这样事务之间就完全不可能产生干扰,也就是说,该级别可以防止脏读、不可重复读以及幻读。

11. Spring 框架中都用到了哪些设计模式?

1)工厂模式:Spring使用工厂模式,通过BeanFactory和ApplicationContext来创建对象。

2)单例模式:Bean默认为单例模式。

3)策略模式:例如Resource的实现类,针对不同的资源文件,实现了不同方式的资源获取策略。

4)代理模式:Spring的AOP功能用到了JDK的动态代理和CGLIB字节码生成技术。

5)模板方法:可以将相同部分的代码放在父类中,而将不同的代码放入不同的子类中,用来解决代码重复的问题。比如RestTemplate, JmsTemplate, JpaTemplate。

6)适配器模式:Spring AOP的增强或通知(Advice)使用到了适配器模式,Spring MVC中也是用到了适配器模式适配Controller。

7)观察者模式:Spring事件驱动模型就是观察者模式的一个经典应用。

8)桥接模式:可以根据客户的需求能够动态切换不同的数据源。比如我们的项目需要连接多个数据库,客户在每次访问中根据需要会去访问不同的数据库。

12. Spring框架中有哪些不同类型的事件?

Spring 提供了以下5种标准的事件:

1)上下文更新事件(ContextRefreshedEvent):在调用ConfigurableApplicationContext 接口中的refresh()方法时被触发。

2)上下文开始事件(ContextStartedEvent):当容器调用ConfigurableApplicationContext的Start()方法开始/重新开始容器时触发该事件。

3)上下文停止事件(ContextStoppedEvent):当容器调用ConfigurableApplicationContext的Stop()方法停止容器时触发该事件。

4)上下文关闭事件(ContextClosedEvent):当ApplicationContext被关闭时触发该事件。容器被关闭时,其管理的所有单例Bean都被销毁。

5)请求处理事件(RequestHandledEvent):在Web应用中,当一个http请求(request)结束触发该事件。

13. 什么是 JavaConfig?

JavaConfig是Spring3.0新增的概念,就是以注解的形式取代Spring中繁琐的xml文件。

JavaConfig结合了xml的解耦和java编译时检查的优点。

  • @Configuration,表示这个类是配置类

  • @ComponentScan,相当于xml的<context:componentScan basepackage=“”>

  • @Bean,相当于xml的<bean id="student" class="com.guor.entity">

  • @EnableWebMvc,相当于xml的mvc:annotation-driven

  • @ImportResource,相当于xml的<import resource="application-context-cache.xml">

  • @PropertySource,用于读取properties配置文件

  • @Profile,一般用于多环境配置,激活时可用@ActiveProfile("dev")注解

14. 什么是 ORM 框架?

ORM(Object-relational mapping),对象关系映射。

是为了解决面向对象与关系型数据库存在的不匹配问题。

ORM框架的优点:

  1. 开发效率更高

  2. 数据访问更抽象、轻便

  3. 支持面向对象封装

15. 什么是 Spring inner beans?

<!--内部 bean-->
<bean id="emp" class="com.atguigu.spring5.bean.Emp">
     <!--设置两个普通属性-->
     <property name="ename" value="lucy"></property>
     <property name="gender" value="女"></property>
     <!--设置对象类型属性-->
     <property name="dept">
         <bean id="dept" class="com.atguigu.spring5.bean.Dept">
            <property name="dname" value="安保部"></property>
         </bean>
     </property>
</bean>

16. 静态方法使用注入bean对象

1、方法一

直接将bean对象,在静态方法传入

public static String getValueBykey(String key,RedisTemplate redisTemplate){
        String value = (String) redisTemplate.opsForValue().get(key);
        return value;
}

2、方法二

    private static RedisTemplate redisTemplate;
    
    @Autowired
    public HandleSign(RedisTemplate redisTemplate){//构造方法
        this.redisTemplate = redisTemplate;
    }
​
    public static String  getValueBykey(String key){
        String value = (String) redisTemplate.opsForValue().get(key);
        return value;
    }

3、方法三

    @Autowired
    private  RedisTemplate redisTemplate;
​
    private static HandleSign handleSign;
    
    @PostConstruct
    public void init(){
        handleSign=this;
        handleSign.redisTemplate=this.redisTemplate;
    }
    
    public static String  getValueBykey(String key){
        String value = (String) redisTemplate.opsForValue().get(key);
        return value;
    }
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值