自我复习spring(三)

本文介绍了Spring AOP的实现原理,重点讲解了两种动态代理方式:JDK动态代理和CGLIB动态代理。通过示例代码展示了如何生成代理类及执行代理逻辑。

spring

AOP的实现——代理模式
在这里插入图片描述
在这里插入图片描述
1.要求有接口I
2.Spring给被代理类S生成代理类P,该代理类P实现了S的接口I,并且P持有了S的实例
3.代理类在实现共同方法时,先执行代理逻辑,再调用被代理类的相应方法,实现了不改变被代理类,但是提供了新的功能
4.当我们从spring按接口获取bean时,实际得到的是代理类的实例,当调用方法时,执行的是代理类的方法

**动态代理:

1.JDK动态代理

2.cglb动态代理**

代理模式结构
• 代理类和被代理类必须实现同一个接口
• 代理类持有被代理类的实例
• 调用代理类的方法时,执行代理逻辑,并调用被代理类的方法
代理模式,能够实现在不改变被代理类的代码的情况下,为该类添加功能
待解决的问题:给定任意一个类,支持动态生成代理类

JDK动态代理

用接口实现,要求必须有接口
java.lang.reflect.Proxy
java.lang.reflect.Proxy#newProxyInstance

public static Object newProxyInstance(ClassLoader loader,  //类加载器
                                      Class<?>[] interfaces,//代理类需要实现的接口
                                      InvocationHandler h // 拦截方法并添加代理逻辑功能
                                      )

InvocationHandler

public Object invoke(Object proxy, 
                     Method method, //被拦截的方法
                     Object[] args  //被拦截的方法的参数
                     )
        throws Throwable;

//    public Object invoke(Object obj 目标对象, Object... args 参数)
//前置通知
try{
Object result = method.invoke(目标对象,args)
    }catch(exception){
	//异常通知
}finally{
	//最终通知
}
//后置通知

package com.woniuxy.framework.proxy.jdk;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.Arrays;

public class JdkProxyFactory {

    /**
     *  生成代理类
     * @param target 目标对象
     * @return
     */
    public static Object getProxy(final Object target){
        //类加载器
        ClassLoader classloader = target.getClass().getClassLoader();
        //目标对象的接口
        Class<?>[] interfaces = target.getClass().getInterfaces();
        //拦截逻辑
        InvocationHandler invocationHandler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                System.out.println("调用"+method+",参数为"+ Arrays.toString(args));
                long before = System.currentTimeMillis();

                //调用被代理类的方法
                Object result = method.invoke(target,args);

                long after = System.currentTimeMillis();
                System.out.println("调用"+method+"执行时长为"+(after-before));
                return result;

            }
        };

        Object proxy = Proxy.newProxyInstance(classloader, interfaces, invocationHandler);

        return proxy;
    }


}

public class JdkProxyApp {

    public static void main(String[] args) {

        OrderService orderService = new OrderServiceImpl();

        OrderService orderServiceProxy = (OrderService) JdkProxyFactory.getProxy(orderService);

        double result = orderServiceProxy.createOrder(1, 10);
        System.out.println("计算结果为:"+result);

        UserService userServiceProxy = (UserService) JdkProxyFactory.getProxy(new UserServiceImpl());
        userServiceProxy.login("zhangsan","wohenshuai");
    }
}
Cglib动态代理

Enhancer 增强器
MethodInterceptor 方法拦截器

package com.woniuxy.framework.proxy.cglib;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;
import java.util.Arrays;

public class CglibProxyFactory {
    /**
     *
     * @param target 目标对象
     * @return 代理类
     */
    public static Object getProxy(final Object target){

        //
        Enhancer enhancer = new Enhancer();
        //设置父类,使用继承方式实现动态代理
        enhancer.setSuperclass(target.getClass());
        //设置拦截逻辑
        MethodInterceptor callback = new MethodInterceptor() {
            @Override
            public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
                //前置通知
                System.out.println("调用方法"+method.getName()+" 参数为"+ Arrays.toString(args));
                Object result = method.invoke(target, args);

                //后置通知
                return result;
            }
        };
        enhancer.setCallback(callback);

        //创建代理对象
        return enhancer.create();
    }

}
package com.woniuxy.framework.proxy.cglib;

import com.woniuxy.framework.service.ChapterServiceImpl;

public class CglibProxyApp {

    public static void main(String[] args) {
        ChapterServiceImpl proxy = (ChapterServiceImpl) CglibProxyFactory.getProxy(new ChapterServiceImpl());

        int result = proxy.count("李四");
        System.out.println("结果为"+result);
    }

}

面试可能要问的
AOP 跟IoC是什么关系?
IoC是AOP的基础
IoC容器,控制权反转,从调用方到了spring容器
容器负责实例化,依赖注入
【i】OrderService
【c】impl.OrderServiceImpl @Service
Spring会实例化OrderServiceImpl
新增切面,拦截所有的service类的所有方法,AOP
需要动态生成OrderServiceImpl的代理类 (JDK动态代理、Cglib动态代理)
OrderServiceProxy 实现了OrderService接口,加入了代理逻辑(通知)
将代理类放入spring容器中
获取时,使用接口来获取Bean,得到的实际上代理类的实例
调用时,先执行代理逻辑,代理类的实例自动调用目标对象的相应方法
在这里插入图片描述

AOP回顾
概念
名词解释
通知类型(5种)
典型的使用场景——声明式事务
AOP的实现——代理模式
• 接口实现
• 继承实现
动态代理
• jdk动态代理
• cglib动态代理

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小小刘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值