JAVA进阶 —— 动态代理

目录

一、什么是动态代理?

 二、如何为Java对象创建代理对象?

三、两种常见的动态代理方式

1. 基于接口的动态代理

2. 基于类的动态代理 


一、什么是动态代理?

在原有代码上加入新的功能该如何操作呢?

 我们可以采用 侵入式修改 直接操作:

 但是在未来的开发中,这样操作非常不好,所以我们引入 动态代理 

  • 动态代理就是,在程序运行期,创建目标对象的代理对象,并对目标对象中的方法进行功能性增强的一种技术。在生成代理对象的过程中,目标对象不变,代理对象中的方法是目标对象方法的增强方法。可以理解为运行期间,对象中方法的动态拦截,在拦截方法的前后执行功能操作。
  • 动态代理就像中介公司,提前做好准备工作。特点:无侵入式的给代码增加额外的功能。

代理的样子就是对象要被代理的方法,那么Java如何保证代理的样子:

  • 通过接口保证,后面的对象和代理需要实现同一个接口,接口中就是被代理的所有方法。

 二、如何为Java对象创建代理对象?

  • java.lang.reflect.Proxy类:提供了为对象产生代理对象的方法

public class ProxyUtil {
	// 给对象创建代理
	public static Star createProxy(BigStar bigstar) {
		Star star = Proxy.newProxyInstance(
				//参数一:用于指定用哪个类加载容器,去加载生成的代理类
				ProxyUtil.class.getClassLoader(),
				//参数二:指定接口,这些接口用于指定生成的代理长什么,也就是有哪些方法
				new Class[] {Star.class},
				//参数三:用来指定生成的代理对象要干什么事情
				new InvocationHandler() {
					@Override
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						// TODO Auto-generated method stub
						return null;
					}
				}
	};return star;
}}

三、两种常见的动态代理方式

1. 基于接口的动态代理

  • 提供者:JDK
  • 使用JDK官方的Proxy类创建代理对象
  • 注意:代理的目标对象必须实现接口
public static Object getObject(final Object obj){
        Object proxyInstance = Proxy.newProxyInstance(
                 obj.getClass().getClassLoader(), 
                 obj.getClass().getInterfaces(), 
                 new InvocationHandler() {
        public Object invoke(Object proxy, Method method, Object[] args) 
                     throws Throwable {
                //方法执行前
                long startTime = System.currentTimeMillis();

                Object result = method.invoke(obj, args);//执行方法的调用

                //方法执行后
                long endTime = System.currentTimeMillis();
                SimpleDateFormat sdf = new SimpleDateFormat();
                System.out.printf(String.format("方法执行结束时间:方法执行耗时:"
          , method.getName()), sdf.format(endTime), endTime - startTime);
                return result;
            }
        });
        return proxyInstance;
}

2. 基于类的动态代理 

  • 提供者:第三方 CGLib
  • 使用CGLib的Enhancer类创建代理对象
  • 注意:如果报 asmxxxx 异常,需要导入 asm.jar包
public static Object getObjectByCGLib(final Object obj){
        Object proxyObj = Enhancer.create(
                          obj.getClass(),
                    new MethodInterceptor() {
        public Object intercept(Object o, Method method, 
                Object[] objects, MethodProxy methodProxy) throws Throwable {
                //方法执行前
                long startTime = System.currentTimeMillis();

                Object invokeObject = method.invoke(obj, objects);//执行方法的调用

                //方法执行后
                long endTime = System.currentTimeMillis();
                SimpleDateFormat sdf = new SimpleDateFormat();
                System.out.printf(String.format("方法执行结束时间:方法执行耗时:"
              , method.getName()), sdf.format(endTime), endTime - startTime);
                return invokeObject;
            }
        });
        return proxyObj;
    }

猜你喜欢

转载自blog.csdn.net/hdakj22/article/details/129667961