Spring学习

  • 简介:
    SpringBoot其实不是什么新的框架,它默认配置了许多框架的使用方式,就像maven整合了所有的jar包。SpringBoot整合了所有的框架,并通过一行简单的main方法启动应用。
    springMVC是解决web控制层的一些问题

  • SpringIOC

IOC:控制反转,程序本身不负责对象的创建和维护,对象的创建和维护都是由外部容器负责创建和维护。也就是说每次新需要一个对象的时候不需要在程序中去new一个对象出来,而是直接到外部容器中调用。

DI:依赖注入,是控制反转的实现方式,用来创建对象和组装对之间的依赖关系。IOC在初始化的时候通过DI创建一系列的对象,并且将这些对象的依赖关系通过注入的方式组装起来。具体实例可以参考下图:
在这里插入图片描述
在这里插入图片描述
Spring注入的常见方式:构造方法注入、setter注入、基于注解的注入。具体实现方法请参考博客https://blog.csdn.net/a909301740/article/details/78379720

Bean
Bean:在springIOC中,把一切配置到IOC容器中的对象或者是实体都称为Bean
Bean的配置项:参考博客https://blog.csdn.net/qq_35680499/article/details/82499312
Bean的作用域:singleton(单例模式)、prototype(原型模式)、request(HTTP请求)、session(会话)、global-session(全局会话)
在这里插入图片描述
在配置bean的作用域时候,可以在XML中这样定义:

<bean id="bean的ID" class="cn.test.Dao.userDao" scope="singleton/prototype/request/session/global-session">

也可以基于@Scope(“singleton/prototype/request/session/global-session”)的方式来配置bean的作用域。 具体可以参考博客:https://blog.csdn.net/fuzhongmin05/article/details/73389779

Bean的自动装配常用注解:@Component、@Repository、@Service、@Controller、@Autowired、@Scope、@Resource

@Component:spring 管理组件的通用形式,可以放在任何类头上,在项目开发中一般不使用。
@Repository:注解在数据访问层的Bean。
@Service:注解在业务逻辑层Bean。
@Controller:注解在控制层Bean,也就是是spring-mvc的注解,具有将请求进行转发,重定向的功能。
@Autowired:字面意思为自动装配,用来给指定的字段或方法注入所需的外部资源。
@Scope :Spring默认产生的bean是单例(即"singleton")的,如果设置为"prototype"表示原型即每次都会new一个新的出来。
@Resource:用来给指定的字段或方法注入所需的外部资源(和@Autowired一样),默认按名称装配,当找不到与名称匹配的bean才会按类型装配;注意:@Resource非spring注解,而是J2EE的注解。
注解整合实例:

//==================================Controller
@Controller
public class SimpleController {
    @Autowired
    private SimpleService simpleService;
}
//==================================Service
@Service("simpleService")
public class SimpleServiceImpl implements SimpleService {
    @Autowired
    private SimpleDao simpleDao;
}
//===================================Repository
@Repository("simpleDao")
public class SimpleDaoImpl implements SimpleDao {
}
     整个装配流程是这样的:

1)在某一时刻Spring调用了 Bean工厂 的 getBean(beanName) 方法。beanName可能是simpleController,或者simpleService,simpleDao,顺序没关系(因为后面会有依赖关系的处理)。我们假设simpleController吧。

2)getBean方法首先会调用Bean工厂中定义的getSingleton(beanName)方法,来判断是否存在该名字的bean单例,若果存在则返回,方法调用结束。

3)否则,Spring会检查是否存在父工厂,如果有则返回,方法调用结束。

4)否则,Spring 会检查该bean 定义(BeanDefinition实例,用来描述Bean结构,component-scan 扫描后,就是将beanDefinition实例放入Bean工厂,此时Bean还没有被实例化。)是否有依赖关系,如果有,执行1)步,获取依赖的bean实例。

5)否则,Spring会尝试创建这个bean实例,创建实例前,Spring会检查确定调用的构造器,并实例化该Bean。

6)实例化完成后,Spring会调用Bean工厂的populateBean方法来填充bean实例的属性,也就是我们前面提到的自动转配了。populateBean方法便是调用了BeanPostProcessor实例来完成属性元素的自动装配工作。

7)在元素装配过程中,Spring会检查被装配的属性是否存在自动装配的其他属性,然后递归调用getBean方法,直到所有@Autowired的元素都被装配完成。如在装配simpleController中的simpleService属性时,发现SimpleServiceImpl实例中存在@Autowired属性simpleDao,然后调用getBean(simpleDao)方法,同样会执行1)-7)整个过程。所以可以看成一个递归过程。

8)装配完成后,Bean工厂会将所有的bean实例都添加到工厂中来。

注:Spring MVC是多线程单实例的MVC框架,就是说,对于同一个Controller,只会生成一个实例来处理所有的请求,因此bean实例只会实例化一次,并被存放在工厂中,以供其他请求使用。

Bean的生命周期流程:
在说明前可以思考一下Servlet的生命周期:实例化,初始init,接收请求service,销毁destroy;

Spring上下文中的Bean也类似,如下

1)实例化一个Bean--也就是我们常说的new;

2)按照Spring上下文对实例化的Bean进行配置--也就是IOC注入;

3)如果这个Bean已经实现了BeanNameAware接口,会调用它实现的setBeanName(String)方法,此处传递的就是Spring配置文件中Bean的id值

4)如果这个Bean已经实现了BeanFactoryAware接口,会调用它实现的setBeanFactory(setBeanFactory(BeanFactory)传递的是Spring工厂自身(可以用这个方式来获取其它Bean,只需在Spring配置文件中配置一个普通的Bean就可以);

5)如果这个Bean已经实现了ApplicationContextAware接口,会调用setApplicationContext(ApplicationContext)方法,传入Spring上下文(同样这个方式也可以实现步骤4的内容,但比4更好,因为ApplicationContext是BeanFactory的子接口,有更多的实现方法);

6)如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessBeforeInitialization(Object obj, String s)方法,BeanPostProcessor经常被用作是Bean内容的更改,并且由于这个是在Bean初始化结束时调用那个的方法,也可以被应用于内存或缓存技术;

7)如果Bean在Spring配置文件中配置了init-method属性会自动调用其配置的初始化方法。

8)如果这个Bean关联了BeanPostProcessor接口,将会调用postProcessAfterInitialization(Object obj, String s)方法、;

注:以上工作完成以后就可以应用这个Bean了,那这个Bean是一个Singleton的,所以一般情况下我们调用同一个id的Bean会是在内容地址相同的实例,当然在Spring配置文件中也可以配置非Singleton,这里我们不做赘述。

9)当Bean不再需要时,会经过清理阶段,如果Bean实现了DisposableBean这个接口,会调用那个其实现的destroy()方法;

10)最后,如果这个Bean的Spring配置中配置了destroy-method属性,会自动调用其配置的销毁方法。

这里描述的是应用Spring上下文Bean的生命周期,如果应用Spring的工厂也就是BeanFactory的话去掉第5步就Ok了

Spring AOP
面向切面编程AOP,是为了将不同的问题交给不同的部分去解决。将通用化功能用代码实现,对应的就是所谓的切面(Aspect)。业务功能代码和切面代码分开后,架构便变得高内聚低耦合。

AOP的三种织入方式
编译时织入:需要特殊的Java编译器,如AspectJ
类加载时织入:需要特殊的Java编译器,如AspectJ和AspectWerkz
运行时织入:Spring采用的方式,通过动态代理的方式,实现简单
AOP的主要名词概念
Aspect:通用功能的代码实现
Target:被织入Aspect的对象
Join Point:可以作为切入点的机会,所有方法都可作为切入点
PointCut:Aspect实际被引用在的Join Point
Advice:类里的方法 以及这个方法如何织入到目标方法的方法
Weaving:AOP的实现过程
Advice的种类
前置通知(Before)
后置通知(AfterReturning)
异常通知(AfterThrowing)
最终通知(After)
环绕通知(Around)
Spring事务
事务的四大特性(ACID)
原子性(Atomicity):事务是一个原子操作,由一系列动作组成。事务的原子性确保动作要么全部完成,要么完全不起作用。
一致性(Consistency):一旦事务完成(不管成功还是失败),系统必须确保它所建模的业务处于一致的状态,而不会是部分完成部分失败。在现实中的数据不应该被破坏。
隔离性(Isolation):可能有许多事务会同时处理相同的数据,因此每个事务都应该与其他事务隔离开来,防止数据损坏。
持久性(Durability):一旦事务完成,无论发生什么系统错误,它的结果都不应该受到影响,这样就能从任何系统崩溃中恢复过来。通常情况下,事务的结果被写到持久化存储器中。
事务的传播行为
当事务方法被另一个事务方法调用时,必须指定事务应该如何传播。Spring 定义了如下七中传播行为,这里以A业务和B业务之间如何传播事务为例说明:

PROPAGATION_REQUIRED :required , 必须。默认值,A如果有事务,B将使用该事务;如果A没有事务,B将创建一个新的事务。
PROPAGATION_SUPPORTS:supports ,支持。A如果有事务,B将使用该事务;如果A没有事务,B将以非事务执行。
PROPAGATION_MANDATORY:mandatory ,强制。A如果有事务,B将使用该事务;如果A没有事务,B将抛异常。
PROPAGATION_REQUIRES_NEW :requires_new,必须新的。如果A有事务,将A的事务挂起,B创建一个新的事务;如果A没有事务,B创建一个新的事务。
PROPAGATION_NOT_SUPPORTED :not_supported ,不支持。如果A有事务,将A的事务挂起,B将以非事务执行;如果A没有事务,B将以非事务执行。
PROPAGATION_NEVER :never,从不。如果A有事务,B将抛异常;如果A没有事务,B将以非事务执行。
PROPAGATION_NESTED :nested ,嵌套。A和B底层采用保存点机制,形成嵌套事务。
事务的隔离级别
并发事务引起的问题:在典型的应用程序中,多个事务并发运行,经常会操作相同的数据来完成各自的任务。并发虽然是必须的,但可能会导致以下的问题:

脏读(Dirty reads)——脏读发生在一个事务读取了另一个事务改写但尚未提交的数据时。如果改写在稍后被回滚了,那么第一个事务获取的数据就是无效的。
不可重复读(Nonrepeatable read)——不可重复读发生在一个事务执行相同的查询两次或两次以上,但是每次都得到不同的数据时。这通常是因为另一个并发事务在两次查询期间进行了更新。
幻读(Phantom read)——幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录。
在 Spring 事务管理中,为我们定义了如下的隔离级别:

ISOLATION_DEFAULT:使用后端数据库默认的隔离级别
ISOLATION_READ_UNCOMMITTED:最低的隔离级别,允许读取尚未提交的数据变更,可能会导致脏读、幻读或不可重复读
ISOLATION_READ_COMMITTED:允许读取并发事务已经提交的数据,可以阻止脏读,但是幻读或不可重复读仍有可能发生
ISOLATION_REPEATABLE_READ:对同一字段的多次读取结果都是一致的,除非数据是被本身事务自己所修改,可以阻止脏读和不可重复读,但幻读仍有可能发生
ISOLATION_SERIALIZABLE:最高的隔离级别,完全服从ACID的隔离级别,确保阻止脏读、不可重复读以及幻读,也是最慢的事务隔离级别,因为它通常是通过完全锁定事务相关的数据库表来实现的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring是一个开源的Java框架,用于构建企业级应用程序。它提供了一种轻量级的、非侵入式的开发方式,通过依赖注入和面向切面编程等特性,简化了Java应用程序的开发过程。 以下是关于Spring学习的一些笔记: 1. IoC(控制反转):Spring通过IoC容器管理对象的创建和依赖关系的注入。通过配置文件或注解,将对象的创建和依赖关系的维护交给Spring容器来管理,降低了组件之间的耦合度。 2. DI(依赖注入):Spring通过依赖注入将对象之间的依赖关系解耦。通过构造函数、Setter方法或注解,将依赖的对象注入到目标对象中,使得对象之间的关系更加灵活和可维护。 3. AOP(面向切面编程):Spring提供了AOP的支持,可以将与业务逻辑无关的横切关注点(如日志、事务管理等)从业务逻辑中分离出来,提高了代码的可重用性和可维护性。 4. MVC(模型-视图-控制器):Spring提供了一个MVC框架,用于构建Web应用程序。通过DispatcherServlet、Controller、ViewResolver等组件,实现了请求的分发和处理,将业务逻辑和视图展示进行了分离。 5. JDBC和ORM支持:Spring提供了对JDBC和ORM框架(如Hibernate、MyBatis)的集成支持,简化了数据库访问的操作,提高了开发效率。 6. 事务管理:Spring提供了对事务的支持,通过声明式事务管理和编程式事务管理,实现了对数据库事务的控制和管理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值