Spring框架3

回顾:
创建对象的注解: @Component,@Controller,@Service,@Repository
依赖注入的注解: @Autowired,@Value
生命周期的注解: @Scope
纯注解编程:@Bean
单元测试的注解:

  1. 动态代理
    动态代理: 在不改变类源代码的前提下对方法进行增强.
    1.1 静态代理
    1.2 基于接口的动态代理
    生成的动态代理对象是接口的实现类( 1. 增强,2调用被代理对象的方法)
/**
 * 基于接口的动态代理:
 *      创建接口的实现类
 * 使用JDK提供的Proxy工具类创建
 */
public class JdkProxyTest {

   public static void main(String[] args) {
      //1.创建了被代理对象
      AccountService as = new AccountServiceImpl();
      //2.创建动态代理对象
      /**
       *  参数:
       *      1.类加载器
       *      2.接口的字节码数组 : as.getClass().getInterfaces()
       *      3.增强的代码块(invocationHandler)
       */
      AccountService proxy = (AccountService)Proxy.newProxyInstance(JdkProxyTest.class.getClassLoader(), new Class[]{AccountService.class}, new InvocationHandler() {
         /**
          * 增强的业务逻辑
          *      proxy   : 代理对象的引用
          *      method  : 当前执行的方法对象
          *      args    : 当前执行方法的所有参数
          *  invoke方法中,代码的执行步骤:
          *      1.增强
          *      2.调用被代理对象的方法
          *      3.返回值: 一般而言和被代理对象方法的返回值一模一样
          */
         public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            System.out.println("1.进入被代理对象方法之前打印日志");
            Object rtValue = null;
            try{
               //执行被代理对象的方法
               rtValue = method.invoke(as,args);//1.方法是所属对象,2.方法的所有参数
               System.out.println("2.调用被代理对象方法得到返回值之后打印日志");
            }catch (Exception e) {
               e.printStackTrace();
               System.out.println("3.抛出异常打印日志");
            }finally {
               System.out.println("4.最终代码块打印日志");
            }
            return rtValue;
         }
      });


      //3.调用动态代理对象的save方法
      proxy.update("123");
   }
}

1.3 基于子类的动态代理
应用场景: 延迟加载
动态代理对象: 是被代理对象的子类
工具类 : cglib

/**
 * 基于子类的动态代理:
 *      创建被代理对象的子类
 * 使用cglib创建
 */
public class CglibProxyTest {

   public static void main(String[] args) {
      //1.创建了被代理对象
      AccountServiceImpl as = new AccountServiceImpl();
      //2.创建动态代理对象
      /**
       * 使用cglib创建动态代理对象 :Enhancer.create()
       *      参数:
       *          1.被代理对象(父类)的字节码对象
       *          2.增强的业务逻辑(jdk的动态代理的invocationHandler相似)
       */
      AccountServiceImpl proxy = (AccountServiceImpl)Enhancer.create(AccountServiceImpl.class, new MethodInterceptor() {
         /**
          * intercept : 增强的业务逻辑
          *      proxy      : 动态代理对象的引用(不用)
          *      method     : 当前执行的方法对象
          *      args       : 当前执行的方法对象的所有参数
          *      methodProxy: 当前执行的方法对象的动态代理对象(不用)
          *
          *  方法执行的顺序
          *      1.增强
          *      2.调用被代理对象(父类)的方法
          *      3.返回值
          */
         public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            System.out.println("1.进入被代理对象方法之前打印日志");
            Object rtValue = null;
            try{
               //执行被代理对象的方法
               rtValue = method.invoke(as,args);//1.方法是所属对象,2.方法的所有参数
               System.out.println("2.调用被代理对象方法得到返回值之后打印日志");
            }catch (Exception e) {
               e.printStackTrace();
               System.out.println("3.抛出异常打印日志");
            }finally {
               System.out.println("4.最终代码块打印日志");
            }
            return rtValue;
         }
      });

      //3.调用动态代理对象的save方法
      proxy.findById("123");
   }
}

  1. 转账案例
    在这里插入图片描述

    2.1 ThreadLocal
    ThreadLocal:将数据绑定到当前线程
    在这里插入图片描述
    在这里插入图片描述
    2.2 事务控制
    在这里插入图片描述

    1. AOP相关概念
      3.1 Aop的概念
      在这里插入图片描述
      3.2 专业术语

连接点(Join point):
被代理对象中的所有方法
切入点(Point cut):
被代理对象中所有被增强的方法
增强/通知(Advice):
增强的业务逻辑
织入(Weaving)
动作:动态代理
目标对象(Target)
被代理对象
切面(Aspect)
切入点和通知之间的关联关系

3.3 通知的类型
前置通知 : 调用被代理对象方法之前执行的增强内容
后置通知 : 调用被代理对象方法得到返回值之后执行的增强内容
异常通知 : 抛出异常的时候执行的增强内容
最终通知 : 在finally代码块中执行的增强内容
环绕通知 :

  1. 基于XML的AOP配置(重点)
案例 : 对账户service进行日志部分的增强
操作步骤:
1.	创建工程导入坐标
2.	搭建工程基本结构
3.	完成IOC的配置
4.	编写增强业务逻辑类(切面类),编写增强业务逻辑的方法
5.	配制AOP
<aop:config>
	//切入点
	<aop:ponitcut id=”唯一标志” expression=”execution(* cn.itcast.service..*.*(..))”></ aop:ponitcut >
//切面
<aop:aspect ref=”切面类的唯一标识”>
	//配置通知类型
	<aop:before method=”切面类的方法名” pointcut-ref=”切入点的id”></ aop:before >
<aop:after-returning method=”切面类的方法名” pointcut-ref=”切入点的id”></ aop: :after-returning >
<aop: after-throwing method=”切面类的方法名” pointcut-ref=”切入点的id”></ aop: after-throwing >
<aop:after method=”切面类的方法名” pointcut-ref=”切入点的id”></ aop:after>
<aop:around method=”切面类的方法名” pointcut-ref=”切入点的id”></ aop: around >
</ aop:aspect >
</aop:config>

4.1 创建工程导入坐标

<dependencies>
    <!--ioc-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>5.0.5.RELEASE</version>
    </dependency>
    <!--单元测试-->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-test</artifactId>
        <version>5.0.5.RELEASE</version>
    </dependency>
    
    <!--aop坐标-->
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-aop</artifactId>
        <version>5.0.5.RELEASE</version>
    </dependency>
    <!--aspectJ : 表达式语言的jar包-->
    <dependency>
        <groupId>org.aspectj</groupId>
        <artifactId>aspectjweaver</artifactId>
        <version>1.6.8</version>
    </dependency>
</dependencies>

4.2 搭建工程基本结构
在这里插入图片描述
4.3 完成IOC的配置
在这里插入图片描述
4.4 编写切面类
切面类:所有增强的业务逻辑方法
在这里插入图片描述
4.5 配制AOP
将切面类交给spring容器管理
声明AOP配置
配置切入点
配置切面在这里插入图片描述
4.6 切入点表达式
在这里插入图片描述
4.7 环绕通知
在这里插入图片描述
配置:
在这里插入图片描述
5. 基于注解结合xml的AOP配置(重点)
注解:
Ioc注解
Aop配置
5.1 开启对注解的支持
包扫描和开启对AOP注解的支持
在这里插入图片描述
5.2 注解配置AOP
注解需要配置到切面类上
5.3 声明切面类
@Aspect
在这里插入图片描述
5.4 配置通知类型
@Before:前置通知
@AfterReturni
@AfterThrowin
@After:最终通知
@Around:环绕通知
在这里插入图片描述
5.5 定义公共的切入点
@PonitCut
在这里插入图片描述
6. 基于纯注解的AOP配置(了解)
在这里插入图片描述
7. 基于AOP的转账案例(作业)

面试问题:
AOP:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值