Spring另一种增强的切面IntroductionAdvisor

本文介绍了如何使用Java的动态代理和CGLIB库,在不修改原有类的情况下,使一个Java类实现某个接口的功能,通过定义接口、拦截器和切面来实现增强功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

/**
 * 引入增强(Introduction Advice)的概念:
 * 一个Java类,没有实现X接口,在不修改Java类的情况下,使其具备X接口的功能
 */

/**
 * 定义一个接口
 */
interface IX {
    void xx();
}

/**
 * 定义目标类,在不实现IX的情况下,拥有IX的所有功能
 */
static class Person {
    void run() {
        System.out.println("run");
    }

    void say() {
        System.out.println("say");
    }
}

/**
 * 定义一个通知,这个通知会应用到目标类,执行目标方法是会被invoke方法拦截
 */
static class IOtherInteIntroductionInterceptor implements IntroductionInterceptor, IX {
    /**
     * 判断调用的方法是否为指定类中的方法
     * 如果Method代表了一个方法 那么调用它的invoke就相当于执行了它代表的这个方法
     */
    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        // 核心在这个方法,当前类是拦截器,执行代理类的目标方法都会被这个方法拦截
        // 只需要这个对这个方法进行逻辑处理就OK
        System.out.println("增强增强");
        // 判断当前正在执行的目标方法类是不是实现了要增强的接口
        boolean son = this.implementsInterface(invocation.getMethod().getDeclaringClass());
        // 如果实现了要增强的接口,那么就代表了要增强,执行增强方法
        if (son) {
            return invocation.getMethod().invoke(this, invocation.getArguments());
        }
        // 如果没有实现增强接口,表示是执行的是一个非增强的,按照常规拦截器的逻辑,直接放行到下一个拦截器就可以
        // 通过拦截器链来最终执行目标方法
        return invocation.proceed();
    }

    /**
     * 判断clazz是否为给定接口IOtherBean的实现
     */
    @Override
    public boolean implementsInterface(Class clazz) {
        return clazz.isAssignableFrom(IX.class);
    }

    /**
     * 增强方法
     */
    @Override
    public void xx() {
        System.out.println("给人贴标签 doOther...");
    }
}


    // 创建代理对象
    public static void main(String[] args) {
        ProxyFactory factory = new ProxyFactory(new Person());
        // 强制私用CGLIB 以保证我们的Person方法也能正常调用
        factory.setProxyTargetClass(true);
        // 创建我们自定义的通知
        Advice advice = new IOtherInteIntroductionInterceptor();
        // 定义切面,包含了通知和需要对目标类附加的接口功能
        Advisor advisor = new DefaultIntroductionAdIOtherIntevisor(advice, () -> new Class[]{IX.class});
        factory.addAdvisor(advisor);
        Object proxy = factory.getProxy();
        IX x= (IX) proxy;
        x.xx();
        // Person本身自己的方法  也得到了保留
        Person p = (Person) proxy;
        p.run();
        p.say();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值