Spring基础解读

Spring IOC

Spring最核心的两大部分IOC和AOP

一、基础解读

介绍:

Spring IOC,控制反转,就是把对象创建和对象之间的调用过程,交给 Spring 进行管理,不使用new进行创建;

目的:

使用IOC主要目的就是通过将对象交给Spring管理,不需要在别的类中再使用new创建对象,从而降低耦合度。

使用方式:

对IOC的使用就是通过在XML文件中配置需要创建的对象。

二、底层原理简单说明

对IOC来说,其容器底层就是一个对象工厂(BeanFactory),通过xml解析+工厂模式+反射来实现IOC的功能。其解耦过程主要包括:

  • 第一步:在XML文件中配置待创建的对象
    <!--配置User对象的创建-->
    <bean id="user" class="com.SpringT.Spring5.User"></bean>
  • 第二步:编写service类和dao类,创建工厂类
    • 工厂类中,需要进行的步骤:
      • 1)xml解析;
      • 2)使用Class.forName(xml解析数据),通过反射创建对象;
      • 3)通过clazz.newInstance()创建dao类的对象,return出去
    • 优势:通过工厂,在每次dao层修改时,不需要继续修改Service类,只需要通过修改xml配置,让工厂类直接读取xml配置的对象
  • 代码实例
public class UserFactory {
    public static User getDao() {
        // 进行xml解析,获取class属性值——classValue——根据上面配置为"com.SpringT.Spring5.User"
        // ...
        // 通过反射创建对象
        Class classC = Class.forName(classValue);
        
        // 创建dao对象,并return
        return (User)classC.newInstance();
    }
}

三、Spring提供IOC容器的实现方式

方式一:BeanFactory

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

  • 根据上图中,BeanFactory的子接口中,AutowireCapableBeanFactory是用来自动装配Bean的,不过ApplicationContext没有继承该接口,但是可以进行组合使用,如下;
// ApplicationContext的方法,最后返回的就是AutowireCapableBeanFactory
AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
  • ApplicationContext的子接口ConfigurableApplicationContext也提供了getBeanFactory()方法用来获取BeanFactory;
	ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;
  • 上面的方法返回的是ConfigurableListableBeanFactory,这是一个特殊的接口。该接口继承了BeanFactory的所有二级接口

注意:使用BeanFactory时,在加载配置文件时候不会创建对象,在获取对象(使用)才去创建对象,ApplicationContext相反

public class TestSpring5 {
    @Test
    public void testBook1(){
        // 1、加载 spring 配置文件——ApplicationContext在这步就创建对象
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-config.xml");
        // 2、获取配置创建的对象——BeanFactory在此处创建对象
        Orders orders = context.getBean("orders", Orders.class);
        orders.orderTest();
    }
}

方式二:ApplicationContext

  • 从方式一的截图中可以看出,ApplicationContext就是BeanFactory接口的子接口,提供更多更强大的功能,一般由开发人员进行使用
public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory,
		MessageSource, ApplicationEventPublisher, ResourcePatternResolver
  • 根据源码可以看出:
  • 父接口
    • ApplicationContext继承了接口ListableBeanFactory,该接口可以改变顶层BeanFactory只获取单个Bean的情况,可以获取多个Bean
    • 继承了接口HierarchicalBeanFactory,以此可以在应用中起多个BeanFactory,且为他们设置父子关系
  • 子接口
    • ApplicationContext的子接口ConfigurableApplicationContext
  • 在Spring源码中,ApplicationContext的实现类主要包括:
    • FileSystemXmlApplicationContext:参数需要写配置文件在系统盘上的路径
    • ClassPathXmlApplicationContext:参数写项目的src下的类路径

启动过程分析

以下过程都以ApplicationContext的最终实现类ClassPathXmlApplicationContext为例

ClassPathXmlApplicationContext启动过程分析_I_m_j的博客-CSDN博客

四、IOC操作——Bean管理

(一)操作组成

  • Spring创建对象;
  • Spring注入属性。

(二)Bean管理操作的两种方式:

1、基于xml配置文件方式实现

(1)基于xml方式创建对象

a)在spring配置文件中,使用bean标签,标签里面添加对应属性,就可以实现对象创建;

b)bean标签常用的属性:id 属性:唯一标识;class 属性:类全路径(包类路径) ;

c)创建对象时候,默认也是执行无参数构造方法完成对象创建。此时如果定义了有参构造函数,没有定义无参构造函数时,无参失效,代码执行会报错。

(2)基于xml方式注入属性

通过DI—依赖注入的方式,其本质就是注入属性

(A)第一种注入方式:使用set方法进行注入

a)创建类,定义属性和对应的 set 方法;

b)在 spring 配置文件中,使用bean标签配置对象创建,配置property属性注入

(B)第二种注入方式:使用有参数构造进行注入

a)创建类,定义属性,创建属性对应有参数构造方法;

b)在 spring 配置文件中,使用bean标签,通过constructor-arg标签进行有参构造函数属性注入

(C)第三种注入方式:p 名称空间注入(了解)

a)在约束中添加 p 名称空间在配置文件中;

b)进行属性注入,在 bean 标签里面进行操作

(3)xml注入其他属性

(A)注入字面量

a)null值:<property name="address"><null/></property>

b)属性值包含特殊符号:<property name="address"> <value><![CDATA[<<南京>>]]></value> </property>

(B)注入属性-外部bean

a)创建一个dao接口,两个类service类和daoImpl类(继承接口);

b)在service中创建dao接口类型属性,并生成set方法;

c)在service的自定义函数中,可以调用dao里面的方法;

d)在spring配置文件中进行配置;<property name="userDao" ref="userDaoImpl"></property>,将类注入到service中的userDao属性中

(C)注入属性-内部bean

a)创建多种类,其中有一对多关系;

b)在 spring 配置文件中进行配置

具体配置见文档

(D)注入属性-级联赋值

具体配置见文档,如果要修改内容,需要在类中生成get方法,再在xml中使用配置修改属性值

(4)注入集合属性

a)注入数组、List集合、Map集合类型属性

  • 创建类,定义数组、list、map、set 类型属性,生成对应 set 方法;
  • 在spring配置文件,分别在property标签中使用<array>、<list>、<map>、<set>进行配置

注意:可以将集合注入的内容提取出来,使用util标签完成集合提取注入

(5)xml自动装配

解释:根据指定装配规则(属性名称或者属性类型),Spring自动将匹配的属性值进行注入

参数:autowire:byName(根据属性名称注入)、byType(根据属性类型注入)

  • byName 根据属性名称注入 ,注入值 bean 的 id 值和类属性名称一样 
  • byType 根据属性类型注入,相同类型的bean不能定义多个,否则报错

2、基于注解方式实现

(1)注解的概念

  • 注解是代码特殊标记
  • 格式:@注解名称(属性名称=属性值, 属性名称=属性值..) 
  • 使用注解,注解作用在类上面,方法上面,属性上面
  • 使用注解目的:简化 xml 配置

(2)Bean管理中创建对象的注解

  • @Component
  • @Service
  • @Controller
  • @Repository

(3)开启步骤:

  • 第一步:引入依赖;
  • 第二步:开启组件扫描;<context:component-scan base-package="com.spring"></context:component-scan>
  • 第三步:创建类,在类上面添加创建对象注解。

(4)属性注入注解:

  • @Autowired:根据属性类型进行自动装配
    • 第一步:把 service 和 dao 对象创建,在 service 和 dao 类添加创建对象注解
    • 第二步:在 service 注入 dao 对象,在service类添加dao类型属性,在属性上面使用注解
  • @Qualifier:根据名称进行注入
    • 和@Autowired 一起使用,用于当接口有多个实现类导致无法判断使用哪个实现类的情况
  • @Resource:可以根据类型注入,可以根据名称注入
  • @Value:注入普通类型属性

(三)Bean作用域:

(1)介绍

  • 在Spring中,默认情况下,bean是单实例对象
    • 单实例:所有的请求都用一个对象来处理;
    • 多实例:每个请求用一个新的对象来处理。
  • 多实例配置:
    • 在 spring 配置文件 bean 标签里面有属性(scope)用于设置单实例还是多实例
      • singleton:单实例,加载 spring 配置文件时候就会创建单实例对象;
      • prototype:不是在加载 spring 配置文件时候创建对象,在调用getBean方法时候创建多实例对象

(四)Bean生命周期:

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

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

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

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

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

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

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

Spring AOP

(一)介绍

面向切面编程,利用 AOP 可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

  • 常用术语:
    • 连接点:类里面可以被增强的方法。
    • 切入点:类里面真正被增强的方法。
    • 通知:实际增强的逻辑部分,包括前置、后置、环绕、异常、最终通知
    • 切面:将通知应用到切入点的过程

(二)底层原理

1、有接口的情况:

  • JDK动态代理
    • 主要做法:
      • 创建接口实现类的代理对象,增强类的方法。其中,代理对象是使用 Proxy 类里面的方法创建的
    • 具体方法:Proxy.newProxyInstance(),该方法中有三个参数:
      • 第一参数,类加载器;
      • 第二参数,增强方法所在的类,这个类实现的接口,支持多个接口;
      • 第三参数,实现这个接口 InvocationHandler,创建代理对象,写增强的部分

2、没有接口的情况:

  • CGLIB动态代理
    • 创建子类的代理对象,增强类的方法

(三)基于 AspectJ 实现 AOP 操作

  • 切入点表达式:
    • 作用:
      • 让程序知道对哪个类里面的哪个方法进行增强
    • 语法结构: 
      • execution([权限修饰符] [返回类型] [类全路径] [方法名称]([参数列表]) )
    • 举例:
      • execution(* com.atguigu.dao.*.* (..))

(四)实现方式

1、基于注解方式实现(常用)

  • 过程:
    • 创建增强类和被增强类,并定义方法;
    • 在Spring配置文件或者定义配置类,开启注解扫描;
    • 使用@Component等注解创建增强类和被增强类对象,增强类上使用@Aspect注解;
    • 配置不同类型的通知;
  • 通知注解:
    • Before前置、AfterReturning后置、After最终、AfterThrowing异常、Around环绕
  • 注意:
    • 可以使用@Pointcut进行相同的切入点抽取;
    • 有多个增强类多同一个方法进行增强,可以使用@Order(n)设置增强类优先级,数字类型值越小优先级越高

2、基于 xml 配置文件实现(一般不用)

事务

(一)概念

事务是数据库操作最基本单元,逻辑上一组操作,要么都成功,如果有一个失败所有操作都失败

(二)事务管理

1、事务管理操作:

事务管理操作分为编程式事务管理和声明式事务管理,而最常用的就是声明式事务管理的基于注解的方式

  • 需要在Spring配置文件中配置事务管理器以及开启事务注解,或者重建配置类使用全注解开发;然后再Service类上使用@Transcantional添加事务注解;
    • 如果把这个注解添加类上面,这个类里面所有的方法都添加事务;
    • 如果把这个注解添加方法上面,为这个方法添加事务;

2、事务注解参数:

  • propagation()—事务传播行为
    • REQUIRED(常用)
      • 特点:使用当前事务,如果当前没有事务,则自己新建一个事务,子方法是必须运行在一个事务中的;如果当前存在事务,则加入这个现有事务中,成为一个整体
    • SUPPORTS(常用)
      • 特点:如果当前有事务,则使用事务;如果当前没有事务,则不使用事务。
      • 该方式没有回滚机制,主要用于查询
    • MANDATORY
      • 特点:该传播属性强制必须存在一个事务,如果父方法没有事务会抛出异常
    • REQUIRES_NEW
      • 特点:
        • 如果当前有事务,则挂起事务,并且自己创建一个新的事务给自己使用;如果当前没有事务,则同REQUIRED
      • 测试现象:
        • 如果父方法没有事务,则仅该子方法事务回滚;但是如果父方法有事务,那第二个事务回滚的同时,也会影响父方法中其余方法,都发生回滚(现象和REQUIRED相同);不过父方法如果有错误,那不会影响子方法;
    • NOT_SUPPORTED
      • 特点:如果当前有事务,则把事务挂起,自己不使用事务去运行数据库操作
    • NEVER
      • 特点:如果当前有事务存在,则抛出异常
    • NESTED
      • 特点:如果当前有事务,则开启子事务(嵌套事务),嵌套事务是独立提交或者回滚;如果当前没有事务,则同REQUIRED;如果主事务提交,则会携带子事务一起提交;如果主事务回滚,则子事务一起回滚。相反,子事务异常,则父事务可以回滚或不回滚(try catch)
  • ioslation:事务隔离级别
  • timeout:超时时间
  • readOnly:是否只读
  • rollbackFor:回滚
  • noRollbackFor:不回滚

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值