Java 代理

JAVA 三种代理

一. 静态代理

    通过继承被代理类的父类或者接口,然后在创建代理类时传入一个被代理类对象,然后在使用代理类中方法时调用被代理类中相应的方法达到代理效果。

缺点: 因为代理对象需要与目标对象实现一样的接口,所以会有很多代理类,类太多.同时,一旦接口增加方法,目标对象与代理对象都要维护.

二. 动态代理

    利用 java.lang.reflect.Proxy 类中 

        static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) 方法实现代理

interface Interface1 {
	void method1();

	void method2();
}

interface Interface2 {
	void method3();
}

class Test implements Interface1, Interface2 {
        @Override
	public void method1() {
		System.out.println("Test.method1");
	}

	@Override
	public void method2() {
		System.out.println("Test.method2");
	}

	@Override
	public void method3() {
		System.out.println("Test.method3");
	}

}
Test test = new Test();
    //只能用接口进行强转,不能用(Test)
	//所以代理对象只能保留一个接口中的方法
	Interface1 proxy=(Interface1) Proxy.newProxyInstance(
	test.getClass().getClassLoader(), 
		new Class[] {Interface1.class, Interface2.class}, 
//		test.getClass().getInterfaces(),  //也可以直接用这种写法
		new InvocationHandler() {
			@Override
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				String methodName = method.getName();
				//只调用method1方法时进行处理
				if("method1".equals(methodName)) {//调用接口中所有方法之前都会调用invoke方法,可以自己根据某一个方法名进行处理
					System.out.println("开始调用 Test method1 方法");
					test.method1();
					System.out.println("调用 Test method1 方法结束");
				} else {//其他方法不进行处理
					return method.invoke(test, args); //返回值
				}
					return null;
				}
		});
	proxy.method1();
	proxy.method2();
//	proxy.method3(); //错误,interface1 接口中没有method3

缺点:被代理类必须要实现一个接口,如果实现了多个接口,只能对一个接口的方法进行保留(个人理解,如有错误欢迎指出)

三. Cglib动态代理

上面的静态代理和动态代理模式都是要求目标对象是实现一个接口的目标对象, 
Cglib代理,也叫作子类代理,是基于asm框架,实现了无反射机制进行代理,利用空间来换取了时间,代理效率高于jdk ,它是在内存中构建一个子类对象从而实现对目标对象功能的扩展. 
它有如下特点:

  1. JDK的动态代理有一个限制,就是使用动态代理的对象必须实现一个或多个接口,如果想代理没有实现接口的类,就可以使用Cglib实现.
  2. Cglib是一个强大的高性能的代码生成包,它可以在运行期扩展java类与实现java接口.它广泛的被许多AOP的框架使用,例如Spring AOP和synaop,为他们提供方法的interception(拦截)
  3. Cglib包的底层是通过使用一个小而块的字节码处理框架ASM来转换字节码并生成新的类.不鼓励直接使用ASM,因为它要求你必须对JVM内部结构包括class文件的格式和指令集都很熟悉.

    注意

  4. 需要引入cglib的jar文件,但是Spring的核心包中已经包括了Cglib功能,所以直接引入spring-core-3.2.5.jar即可.(否则要导入两个jar 包,cglib-3.2.7.jar     asm-6.2.1.jar
  5. 引入功能包后,就可以在内存中动态构建子类
  6. 代理的类不能为final,否则报错
  7. 目标对象的方法如果为final/static,那么就不会被拦截,即不会执行目标对象额外的业务方法.

class Test {
	public void method1() {
		System.out.println("Test.method1");
	}

	public void method2() {
		System.out.println("Test.method2");
	}

	public void method3() {
		System.out.println("Test.method3");
	}

}
public static void cglibProxy(String[] args) {
		
	Test test=new Test();
		
	//创建代理对象
	Enhancer enhancer=new Enhancer();//cglib中的工具类
	enhancer.setSuperclass(test.getClass());//设置父类
	enhancer.setCallback(new MethodInterceptor() {//设置代理的函数,与InvocationHandler中的invoke类似
		@Override
		public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
			String methodName = method.getName();
			Object result=null;
			if("method1".equals(methodName)) {//对method1进行代理
				System.out.println("cglib method1 代理");
				test.method1();
			} else if ("method2".equals(methodName)) {//对method2进行代理
				System.out.println("cglib method2 代理");
				test.method2();
			} else { //其他方法直接调用其本身,不进行任何操作
				result=method.invoke(test, args);
			}
		    	return result;
			}
		});
		Test proxy = (Test) enhancer.create();
		proxy.method1();
		proxy.method2();
		proxy.method3();
}

使用CGLIB即使代理类没有实现任何接口也可以实现动态代理功能。CGLIB具有简单易用,它的运行速度要远远快于JDK的 
CGLIB的核心类: 
net.sf.cglib.proxy.Enhancer – 主要的增强类 
net.sf.cglib.proxy.MethodInterceptor – 主要的方法拦截类,它是Callback接口的子接口,需要用户实现 
net.sf.cglib.proxy.MethodProxy – JDK的java.lang.reflect.Method类的代理类,可以方便的实现对源对象方法的调用

python023基于Python旅游景点推荐系统带vue前后端分离毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值