反射的应用场景

反射的三种应用场景

1.工厂模式中的简单工厂模式优化
2.代理模式中的动态代理方式实现
3.Java JDBC数据库操作

1.工厂模式使用(log工厂模式)在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.代理模式
代理(Proxy)模式是一种设计模式,通过代理对象来访问目标对象,还可以在不修改目标对象的情况下,对代理对象进行拓展,增强目标对象的功能

在这里插入图片描述
什么是静态代理?
1.静态代理属于代理模式的一种代理方式,需要代理对象和目标对象实现相同的接口
2.静态代理的代理类是由程序员编写源码,编译后即可获取到代理类的class字节码文件,也就是在程序运行前就已经得到实际的代理类class字节码文件了
什么是动态代理?
1.动态代理也属于代理模式的一种代理方式,不过只需要目标对象实现接口,代理对象不需要实现接口~
2.动态代理的代理类编译后是没有class字节码文件的,而是在运行时利用Java反射机制动态的生成代理类的class字节码文件

jdk原生代码示例

public interface IUserDao {
    //添加数据
    public void insert();
}
public class UserDao implements IUserDao{
    @Override
    public void insert() {
        System.out.println("添加数据");
    }
}
public class UserProxy {
    private Object target; //目标对象

    public UserProxy(Object target) {
        this.target = target;
    }

    /**
     * 利用JDK API获取到代理对象
     * @return
     */
    public Object getProxyInstance() {
        //目标对象的加载器
        ClassLoader loader = target.getClass().getClassLoader();

        //目标对象的实现接口类型
        Class<?>[] interfaces = target.getClass().getInterfaces();

        //InnvocationHandler事件处理器实例对象
        InvocationHandler h = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("添加数据前:手动开启事务");
                // 执行目标对象方法
                Object value = method.invoke(target, args);
                System.out.println("添加数据后:手动提交事务");
                return null;
            }
        };
        //传入3个参数,创建代理类的实例对象,并返回
        return Proxy.newProxyInstance(loader, interfaces,h);
    }
}
public class UserProxyTest {
    @Test
    public void test() {
        IUserDao target = new UserDao();
        System.out.println("目标对象信息:" + target.getClass());
        //获取代理类实例对象
        IUserDao proxy = (IUserDao) new UserProxy(target).getProxyInstance();
        System.out.println("代理对象信息:" + proxy.getClass());
        //执行代理方法
        proxy.insert();
    }
}

运行结果

目标对象信息:class com.justin.java.reflect.UserDao
代理对象信息:class com.sun.proxy.$Proxy2
添加数据前:手动开启事务
添加数据
添加数据后:手动提交事务

cglib代码示例

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
public class EnhancerDemo {
    public static void main(String[] args) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(EnhancerDemo.class);
        enhancer.setCallback(new MethodInterceptorImpl());
        EnhancerDemo demo = (EnhancerDemo) enhancer.create();
        demo.test();
        System.out.println(demo);
    }
    
    public void test() {
        System.out.println("EnhancerDemo test()");
    }
    
    private static class MethodInterceptorImpl implements MethodInterceptor {
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.err.println("Before invoke " + method);
            Object result = methodProxy.invokeSuper(o, objects);
            System.err.println("After invoke" + method);
            return result;
        }
    }
}

运行结果

EnhancerDemo test()
After invokepublic void com.bruis.learnaop.testcglibaop.EnhancerDemo.test()
Before invoke public java.lang.String java.lang.Object.toString()
Before invoke public native int java.lang.Object.hashCode()
After invokepublic native int java.lang.Object.hashCode()
After invokepublic java.lang.String java.lang.Object.toString()
com.bruis.learnaop.testcglibaop.EnhancerDemo$$EnhancerByCGLIB$$413eae0d@53e25b76

区别

JDK代理使用的是反射机制生成一个实现代理接口的匿名类,在调用具体方法前调用InvokeHandler来处理。

CGLIB代理使用字节码处理框架asm,对代理对象类的class文件加载进来,通过修改字节码生成子类。

jdk动态代理只提供实现接口的目标类代理,不支持没有实现接口的目标类的代理。如果目标类没有实现接口,只能用cglib代理

JDK代理是不需要依赖第三方的库,只要JDK环境就可以进行代理,需要满足以下要求:
 1.实现InvocationHandler接口,重写invoke()
 2.使用Proxy.newProxyInstance()产生代理对象
 3.被代理的对象必须要实现接口
CGLib 必须依赖于CGLib的类库,需要满足以下要求:
 1.实现MethodInterceptor接口,重写intercept()
 2.使用Enhancer对象.create()产生代理对象

spring中动态代理Aop片段

![在这里插入图片描述](https://img-blog.csdnimg.cn/c222f6a69cb44732856c4b439f38d79d.png在这里插入图片描述
在这里插入图片描述
原文转载:https://blog.csdn.net/JustinQin/article/details/119850304
https://blog.csdn.net/CoderBruis/article/details/100042081

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值