JDK动态代理 四种实现方法和CGLib生成子类代理

总结:一、四种invoke方法的不同实现手段(四种生成代理类的方法),第一种是通过重写InvocationHandler中的invoke

第二种和第三种是通过InvocationHandler的匿名内部类实现(其中第三种用final修饰目标对象,不用在内部创建,也不用通过实现类UserHandler.this.targetObject的这种方式调用,而是在invoke方法中直接调用)

第四种是创建一个继承了InvocationHandler接口的中间类,并在该类中实现invoke方法,

二、

 

Jdk动态代理只针对接口的实现类

三、CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,反之,使用JDK方式要更为合适一些。

同时,由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。

CGLib是第三方,不是jdk带的。用它就要导入CGLib的jar包。

(一) 继承InvocationHandler接口,实现其方法(拦截并增强),返回代理对象

package com.soft.service4;

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

import javax.servlet.jsp.tagext.TryCatchFinally;

//JDK动态代理    四种方法生成代理(一)、继承InvocationHandler接口,实现其方法(拦截并增强),返回代理对象
public class UserHandler implements InvocationHandler{

	private Object targetObject;//私有的目标对象

	//返回一个代理对象
	public Object newProxy(Object targetObject){
		this.targetObject = targetObject;
		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//调用目标对象的类获得类加载器
				targetObject.getClass().getInterfaces(),//通过目标对象类型获取其继承的接口
				this);//继承并实现了InvocationHandler的当前类(即UserHandler)
	}
	//当目标对象中的方法被调用时就会执行invoke方法,所以在此方法中实现方法的增强
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		checkBefore();
		Object ret = null;//声明返回值
		try{
			ret = method.invoke(targetObject, args)	;//捕获每一个方法并调用
		}catch (Exception e) {
			e.printStackTrace();
		}
		checkAfter();
		return ret;
	}
	
	public void checkBefore(){
		System.out.println("---Before----");
	}
	public void checkAfter(){
		System.out.println("---After----");
	}
	
}

(二)用InvocationHandler的匿名内部类,不用继承InvocationHandler,内部实现invoke方法

package com.soft.service4;

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

import javax.servlet.jsp.tagext.TryCatchFinally;

//JDK动态代理    四种方法生成代理(二)、使用InvocationHandler的匿名内部类,不用继承InvocationHandler,内部实现invoke方法
public class UserHandler1 {

	private Object targetObject;//私有的目标对象

	//返回一个代理对象
	public Object newProxy( Object targetObject){
		this.targetObject = targetObject;
		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//调用目标对象的类获得类加载器
				targetObject.getClass().getInterfaces(),//通过目标对象类型获取其继承的接口
				new InvocationHandler() {
			//当目标对象中的方法被调用时就会执行invoke方法,所以在此方法中实现方法的增强
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						checkBefore();
						Object ret = null;//声明返回值
						try{
							ret = method.invoke(UserHandler1.this.targetObject, args)	;//捕获每一个方法并调用
						}catch (Exception e) {
							e.printStackTrace();
						}
						checkAfter();
						System.out.println("--匿名内部类实现----");
						System.out.println(ret);
						System.out.println(method.getName());
						for(Object x :args){
							System.out.println(x.toString());
						}
						return ret;
					}
				});//继承并实现了InvocationHandler的当前类(即UserHandler)
	}
	
	
	public void checkBefore(){
		System.out.println("---Before----");
	}
	public void checkAfter(){
		System.out.println("---After----");
	}
	
}

(三)InvocationHandler的匿名内部类,使用final的targetObject,
不用再创建目标对象,内部类中直接调用(而不是UserHandler2.this.targetObject)

package com.soft.service4;

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

import javax.servlet.jsp.tagext.TryCatchFinally;

//JDK动态代理    四种方法生成代理(二)、InvocationHandler的匿名内部类,使用final的targetObject,
//不用再创建目标对象,内部类中直接调用(而不是UserHandler2.this.targetObject)
//只要实现了InvocationHandler接口,可以代理所有接口
public class UserHandler2 {

	
	//返回一个代理对象
	public Object newProxy( final Object targetObject){
		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//调用目标对象的类获得类加载器
				targetObject.getClass().getInterfaces(),//通过目标对象类型获取其继承的接口
				new InvocationHandler() {
			//当目标对象中的方法被调用时就会执行invoke方法,所以在此方法中实现方法的增强
					@Override
					public Object invoke(Object proxy, Method method, Object[] args)
							throws Throwable {
						checkBefore();
						Object ret = null;//声明返回值
						try{
							ret = method.invoke(targetObject, args)	;//终态的targetObject直接调用
						}catch (Exception e) {
							e.printStackTrace();
						}
						checkAfter();
						System.out.println("--匿名内部类实现----");
						System.out.println(ret);
						System.out.println(method.getName());
						for(Object x :args){
							System.out.println(x.toString());
						}
						return ret;
					}
				});//继承并实现了InvocationHandler的当前类(即UserHandler)
	}
	
	
	public void checkBefore(){
		System.out.println("---Before----");
	}
	public void checkAfter(){
		System.out.println("---After----");
	}
	
}

(四)创建一个受保护的类继承InvocationHandler接口,并实现invoke方法,调用时传入目标对象创建代理对象

package com.soft.service4;

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

import javax.servlet.jsp.tagext.TryCatchFinally;

//JDK动态代理    四种方法生成代理(二)、创建一个受保护的类继承InvocationHandler接口,并实现invoke方法,调用时传入目标对象创建代理对象
//只要实现了InvocationHandler接口,可以代理所有接口
public class UserHandler3 {

	
	//返回一个代理对象
	public Object newProxy( final Object targetObject){
		return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),//调用目标对象的类获得类加载器
				targetObject.getClass().getInterfaces(),//通过目标对象类型获取其继承的接口
				new custInvocationHandler(targetObject));
	}
	class custInvocationHandler implements InvocationHandler{

		private Object targetObject;
		public  custInvocationHandler(Object targetObject){
			this.targetObject = targetObject;
		}
		@Override
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			checkBefore();
			Object ret = null;//声明返回值
			try{
				ret = method.invoke(targetObject, args)	;//终态的targetObject直接调用
			}catch (Exception e) {
				e.printStackTrace();
			}
			checkAfter();
			System.out.println("--匿名内部类实现333----");
			System.out.println(ret);
			System.out.println(method.getName());
			for(Object x :args){
				System.out.println(x.toString());
			}
			return ret;
		}
		
	}
	
	public void checkBefore(){
		System.out.println("---Before----");
	}
	public void checkAfter(){
		System.out.println("---After----");
	}
	
}

 

 

Cglib代理没有实现接口的类,也可以实现有接口的代理类

package com.soft.service6;

import java.lang.reflect.Method;

import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

public class CGLibProxy implements MethodInterceptor {

	private Enhancer enhancer =new Enhancer();
	public Object getProxy(Class clazz){
		//设置需要创建子类的类
		Enhancer enhancer  = new Enhancer();
		enhancer.setSuperclass(clazz);
		enhancer.setCallback(this);//设置回调函数
		//通过字节码技术动态创建子类实例
		return enhancer.create();
	}
	@Override
	public Object intercept(Object object, Method method, Object[] arg2,
			MethodProxy proxy) throws Throwable {
		System.out.println("--前置代理");
		Object result = proxy.invokeSuper(object, arg2);
		System.out.println("---后置代理");
		return result;
	}
}

test

public static void main(String[] args) {
		CGLibProxy cglibProxy = new CGLibProxy();
		//没有继承接口的类,通过CGlib给该类生成子类代理
		/*SayHello sayHello = (SayHello) cglibProxy.getProxy(SayHello.class);
		sayHello.say();*/
		
		UserManager userManager = (UserManager) cglibProxy.getProxy(UserManagerImpl.class);
		userManager.addUser("ada", "124");
	}

没有实现接口的类生成代理类只需传入该类类型,实现了接口的传入实现类的类型(都是创建子类代理)

转载于:https://my.oschina.net/8824/blog/2250718

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值