Spring5

1、Spring

  • 什么是Spring?

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

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

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

  • 为什么需要Spring?

    Spring可以解决企业应用开发的复杂性,有以下特点:

    1. 方便解耦,简化开发
    2. AOP编程支持
    3. 方便程序测试
    4. 方便和其他框架进行整合(粘合剂)
    5. 方便进行事务操作
    6. 降低API开发难度
  • 怎么使用Spring?

    1. 创建普通类(User)
    2. 创建Spring配置文件(applicationContext.xml),在配置文件配置创建的对象
<bean id="user" class="com.atguigu.spring5.User"></bean>
1. 测试代码编写
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
applicationContext.getBean("user");

2、IOC

  • 什么是IOC?

    控制反转,把对象的创建和对象之间的调用过程,交给Spring进行管理

  • 为什么需要IOC?

    为了降低耦合度

  • 怎么使用IOC?

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

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

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

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

      加载配置文件时候就会创建好对象放入IOC容器(预加载)

3、FactoryBean

  • 什么是FactoryBean?

    Spring有两种类型bean,一种普通bean,另外一种工厂bean(FactoryBean)

    普通bean:在配置文件中定义bean类型就是返回类型

    工厂bean:在配置文件定义bean类型可以和返回类型不一样

  • 为什么需要FactoryBean?(主要和beanFactory对比)

    我们使用beanFactory获取bean(getBean())之前,我们需要事先定义这个bean长什么样子,或者说它由哪些组件组成,这种方式的弊端是所有的bean都需要实现定义好,但是有时候,有的一些bean我们只知道它大概是什么样子,但是无法事先定义出其具体的功能,只有在代码执行的时候,我才知道是什么类型,需要实现什么功能,例如mybatis中的mapper,这样FactoryBean就有了其意义,它可以定义出一种类型的Bean,并且在创建的时候再去实现其具体的功能。

  • 怎么使用FactoryBean?

    1. 第一步:创建类,让这个类作为工厂bean,实现接口FactoryBean
    2. 第二步:实现接口里面的方法(主要是getObject来返回获取到的对象类型),在实现的方法中定义返回的bean类型
public class MyBean implements FactoryBean<Course>{
    **@Override
    public Course getObject() throws Exception(){
        Course course = new Course();
        course.setCname("abc");
        return course;
    }**
    ...//其他重写的方法
}
1. 这样定义后通过ioc容器getBean()获取MyBean对象时获取的是Course对象(准确来说是容器创建的代理对象)。
2. 如果想获取到MyBean对象,可以在getBean()方法调用时在这样写getBean("&myBean")。

4、IOC容器中singleton和prototype的区别

  1. singleton单实例,prototype多实例

  2. 设置scope值是singleton的时候,加载spring配置文件的时候就会创建单实例对象(加载即创建);

    设置scope值是prototype的时候,不是在加载spring配置文件的时候创建对象,而是在调用getBean方法的时候创建多实例对象

5、IOC操作Bean管理(bean生命周期)

  • bean生命周期(主观来看)

    1. 通过构造器创建bean实例(无参构造器)
    2. 为bean的属性设置值和对其他bean引用(调用set方法)
    3. 调用bean的初始化方法(需要进行配置初始化的方法)
    4. bean可以使用了(对象获取到了)
    5. 当容器关闭的时候,调用bean 的销毁方法(需要进行配置销毁的方法)

  • bean的后置处理器,bean生命周期有七步(内部大致调用过程)

    1. 通过构造器创建bean实例(无参构造器)
    2. 为bean的属性设置值和对其他bean引用(调用set方法)
    3. 把bean实例传递给bean后置处理器的方法postProcessBeforeInitialization
    4. 调用bean的初始化的方法(需要进行配置初始化方法)
    5. 把bean实例传递给bean后置从处理器的方法postProcessAfterInitialization
    6. bean可以使用了(对象获取到了)
    7. 当容器关闭的时候,调用bean的销毁方法(需要进行配置销毁的方法)

6、IOC操作Bean管理(基于注解方式)

  • 什么是注解?

    注解是代码特殊标记,格式:@注解名称(属性名称1=属性值1,属性名称2=属性值2...)

  • 为什么要使用注解?

    简化xml配置

  • 在哪里使用注解?

    注解作用在类上面,方法上面,属性上面

  • 怎么使用注解?

    1. 在对应类上标上对应的注解

      @Component

      @Controller

      @Service

      @Repository

    2. 在spring配置文件中开启组件扫描

<!-- 扫描com.atguigu中的所有组件放入容器 -->
<context:component-scan base-package="com.atguigu">
</cotext:component-scan>

7、AOP(面向切面)

  • 什么是AOP?

    1. 面向切面编程(方面),利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
    2. 通俗描述:不通过修改开发人员写的源代码的方式,在主干功能里面添加新功能。
  • 为什么要使用AOP?

    使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。

  • 底层原理(两种情况)

    1. 有接口的情况,使用JDK动态代理

      创建接口实现类代理对象,增强类方法

    2. 没有接口情况,使用CGLIB动态代理

      创建子类的代理对象,增强类方法

    注:想了解详情看《Spring5框架笔记》

  • 怎么使用AOP?

    1. AOP术语:

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

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

      • 通知(增强):

        (1)实际增强的逻辑部分称为通知(增强)

        (2)通知类型有5种

        前置通知
        
        后置通知
        
        环绕通知
        
        异常通知
        
        最终通知
        
      • 切面:是动作。把通知应用到切入点的过程

    2. AOP操作准备工作:

      (1)Spring框架一般都是基于AspectJ实现AOP操作

      AspectJ不是Spring组成部分,独立AOP框架,一般把AspectJ和Spring框架一起使用,进行AOP操作

      (2)基于AspectJ实现AOP操作

      基于xml配置文件实现

      基于注解方式实现(使用)

      (3)在项目工程里面引入AOP相关依赖

      (4)写切入点表达式

      切入点表达式作用:知道对哪个类里面的哪个方法进行增强

      语法结构:execution([权限修饰符] [返回类型] [类全路径] 方法名称) 如:execution(* com.atguigu.dao.BookDao.*(..))

    3. AspectJ注解

      ① 创建类,在类里面定义方法

      ② 创建增强类(编写增强逻辑)

@Aspect
public class UserProxy{
    public void before(){  //前置通知
        System.out.println("before...");
    }
}
    ③ 进行通知的配置

      在增强类上加@Aspet注解生成代理对象

      **在spring配置文件中开启生成代理对象**
<!-- 开启Aspect生成代理对象 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
1. 配置不同类型的通知

    在增强类的里面,在作为通知方法上面添加通知类型注解,使用切入点表达式配置
//增强的类
@Component
@Aspect  //生成代理对象
public class UserProxy{
   //前置通知
   //@Before注解表示作为前置通知
   @Before(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
   public void before(){
       System.out.println("before...");
   }   
   //后置通知(返回通知)
   @AfterReturning(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
   public void afterReturning(){
       System.out.println("afterReturning...");
   }
   //最终通知
   @After(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
   public void after(){
       System.out.println("after...");
   }
   //异常通知
   @AfterThrowing(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
   public void afterThrowing(){
       System.out.println("afterThrowing");
   }
   //环绕通知
   @Around(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint){
        System.out.println("环绕之前...");
        //被增强的方法执行
        proceedingJoinPoint.proceed();
        System.out.println("环绕之后...");
    }   
}

1. 相同的切入点抽取
//相同的切入点抽取
@Pointcut(value="execution(* com.atguigu.spring5.aopanno.User.add(..))")
public void pointDemo(){}

//那么之前的前置通知可以写为
@Before(value="pointDemo()")
public void before(){
    System.out.println("before...");
}
1. 有多个增强类多同一个方法进行增强,设置增强类优先级

    在增强类上添加注解@Order(数字),数字值越小优先级越高
1. 完全使用注解开发

    创建配置类,不需要创建xml配置文件
@Configuration  //让ioc容器知道这是一个配置类
@ComponentScan(basePackages = {"com.atguigu"}  //可以写多个包名
@EnableAspectJAutoProxy(proxyTargetClass=true)  //开启注解配置AOP
public class ConfigAop{}

1. AspectJ配置文件(第二种方式配置AOP方式)
1、创建两个类,增强类和被增强类,创建方法
2、在spring配置文件中创建两个类对象
<!-- 创建对象 -->
<bean id="book" class="com.atguigu.spring5.aopxml.Book"></bean>
<bean id="bookProxy" class="com.atguigu.spring5.aopxml.BookProxy"></bean>
3、在spring配置文件中配置切入点
<!-- 配置aop增强 -->
<aop:config>
    <!-- 切入点 -->
    <aop:pointcut id="p" expression="execution(* com.atguigu.spring5.aopxml.Book.buy(..))" />
    <!-- 配置切面 -->
    <aop:aspect>
        <!-- 增强作用在具体的方法上 -->
        <aop:before method="before" pointcut-ref="p" />
    </aop:aspect>
</aop:config>

8、JdbcTemplate(后面可以使用MyBatis框架代替)

  • 什么是JdbcTemplate?

    Spring框架对JDBC进行封装,使用JdbcTemplate方便实现对数据库操作

  • 怎么使用JdbcTemplate?

    1、引入相关jar包

    2、在spring配置文件配置数据库连接池

<!-- 1、导入dbconfig.properties文件 -->
<context:property-placeholder location="classpath:dbconfig.properties" />

<!-- 2、数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
  destroy-method="close">
      <property name="url" value="${jdbc.jdbcUrl}" />
      <property name="driverClass" value="${jdbc.driverClass}" />
      <property name="user" value="${jdbc.user}" />
      <property name="password" value="${jdbc.password}" />
</bean>
<!-- 3、配置JdbcTemplate对象,注入DataSource -->
<!-- JdbcTemplate对象 -->
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
    <!-- 注入dataSource -->
    <property name="dataSource" ref="dateSource" ></property> 
</bean>

9、事务操作(搭建事务操作环境)

  • 什么是事务?

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

  • 事务四个特性

    • 原子性
    • 一致性
    • 隔离性
    • 持久性
  • 怎么使用(开启)事务?

    1、事务添加到JavaEE三层结构里面的Service层(业务逻辑层)

    2、在Spring进行事务管理有两种方式:

    编程式事务和声明式事务
    

    3、声明式事务管理

    基于注解方式(使用)和基于xml配置文件方式
    

    4、在Spring进行声明式事务管理,底层使用AOP原理

    5、开启事务

1、在spring配置文件配置事务管理器
<!-- 创建事务管理器 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <!-- 注入数据源 -->
    <property name="dataSource" ref="dataSource"></property>
</bean>

2、开启事务注解
<!-- 开启事务注解 -->
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>

3、在需要开启事务的类上(或者类里面的方法上)添加事务注解
(1)@Transactional,这个注解添加到类上面,也可也添加到方法上面
(2)如果把这个注解添加到类上面,这个类里面所有的方法都添加事务
(3)如果把这个注解添加到方法上面,就只为这个方法添加事务
@Service
@Transactional
public class UserService{}
posted @ 2022-01-21 14:46  ArosyCat  阅读(22)  评论(0编辑  收藏  举报