java动态代理 JDK、Cglib动态代理

      代理模式是常用的java设计模式,他的特征是代理类委托类有同样的接口,

      代理类主要负责为委托类预处理消息、过滤消息、把消息转发给委托类,以及事后处理消息等。

      代理类与委托类之间通常会存在关联关系,一个代理类的对象与一个委托类的对象关联,代理类的对象本身并不真正实现服务,而是通过调用委托类的对象的相关方法,来提供

特定的服务。

      有了解动态代理你必须先了解java的反射机制(点击查看)

1.Java动态代理有两种实现:

      1.      JDK动态代理(委托类必须接口实现,代理类实现InvocationHandler接口,springAop默认的实现方式)

      2.      Cglib动态代理(委托类可以不实现接口,也可以实现接口,代理类实现MethodInterceptor,spring的bean在没实现接口时使用的Cglib实现AOP),使用Cglib提供的过滤器CallbackFilter 可以明确表明,被代理的类(InfoManager)中不同的方法,被哪个拦截器(interceptor,即代理类)拦截。

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

2.JDK动态代理

 //接口

public interface Count {
	public void CountAll();
	public void AddMethod();
}

//实现 委托类

public class CountImpl implements Count{
	@Override
	public void CountAll() {
		try{
			Thread.sleep(2000);
			System.out.println("count start...");
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	@Override
	public void AddMethod() {
		System.out.println("AddMethod start...");
	}
}

//代理类 实现 InvocationHandler

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

public class JDKProxy implements InvocationHandler{
	private Count count;
	public JDKProxy(Count count){
		this.count = count;
	}
	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		// TODO Auto-generated method stub
		System.out.println("begin...");
		method.invoke(count, args);
		System.out.println("end...");
		return null;
	}

}

//工厂

import java.lang.reflect.Proxy;

public class CountFactory {
	public static Count getProxyInstance(Count count){
		return (Count)Proxy.newProxyInstance(count.getClass().getClassLoader(), count.getClass().getInterfaces(), new JDKProxy(count));
	}
}

//客户端

public class Client {
	public static void main(String[] arg){
		Count count = new CountImpl();
		Count countProxy = CountFactory.getProxyInstance(count);
		countProxy.CountAll();
		count.CountAll();
	}
	
}

@输出:begin...
                count start...
                end...
               count start...


2.Cglib动态代理

cglib(Code Generation Library)是一个强大的,高性能,高质量的Code生成类库。它可以在运行期扩展Java类与实现Java接口。
cglib封装了asm,可以在运行期动态生成新的class。CGLib采用了非常底层的字节码技术,其原理是通过字节码技术为一个类创建子类,并在子类中采用方法拦截的技术拦截所有父类方法的调用,顺势织入横切逻辑。

它广泛的被许多AOP的框架使用,例如Spring AOP和dynaop,为他们提供方法的interception(拦截)。最流行的OR Mapping工具hibernate也使用CGLIB来代理单端single-ended(多对一和一对一)关联(对集合的延迟抓取,是采用其他机制实现的)


@代码:

//委托类

public class InfoManager {
    public void query() {
        System.out.println("query");
    }
    public void delete() {
        System.out.println("delete");
    }
}
//代理类 实现 MethodInterceptor
public class AuthProxy implements MethodInterceptor{
    String name;
    public AuthProxy(String name){
    	this.name = name;
    }
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy arg3) throws Throwable {
		if(this.name.equals("dxswzj")){//当dxswzj时才可以操作
                       //对方法进行过滤
                        if(arg1.getName().equals("delete")){
				System.out.println("you can't do delete!");
			}else{
				System.out.println("方法前置代理");
				arg3.invokeSuper(arg0, arg2);
				System.out.println("方法后置代理");
			}
		}else{
			System.out.println("you can't do anything!");
		}
		
		return null;
	}

}

//工厂类

public class InfoManagerFactory {
 public static InfoManager getInstance(AuthProxy proxy){
	 Enhancer enhancer = new Enhancer();
 	 //设置需要创建子类的类
	 enhancer.setSuperclass(InfoManager.class);
	 enhancer.setCallback(proxy);
 	 //通过字节码技术动态创建子类实例
	 return (InfoManager)enhancer.create();
	 
 }
	
}

 //客户端

	public static void main(String[] arg){
		Client c = new Client();
		AuthProxy proxy = new AuthProxy("dxswzj");
		InfoManager manager = InfoManagerFactory.getInstance(proxy); 
		manager.delete();
		manager.query();
	}

@输出:you can't do delete!
               方法前置代理
               query
               方法后置代理





你可能感兴趣的:(动态代理,java动态代理)