动态代理的两种实现方式小案例

关于反射和动态代理的使用

动态代理的方式简化业务层的大量重复代码

Interface

package com.xwl;
/**
 * 动态代理
 * @author Administrator
 *
 *我们可以使用动态代理的方式简化销售公司的大量重复代码
 *
 */
//苹果需要生产四种产品 交给中国工厂
interface Iphone{	
	public void product6s();
	public void product6Plus();
	public void product7();
	public void productX();
}

service

//生产厂商生产苹果手机
class Phone implements Iphone{
	public void product6s() {
		System.out.println("6s");
	}
	public void product6Plus() {
		System.out.println("6Plus");
	}
	public void product7() {
		System.out.println("7");
	}
	public void productX() {
		System.out.println("X");
	}
}

业务

//销售公司Agent 宣传  销售
class Agent{
	//首先我需要手机
	private Iphone phone;
	
	public Iphone getPhone() {
		return phone;
	}
	public void setPhone(Iphone phone) {
		this.phone = phone;
	}
	//  **1.宣传 我们 2.生产(phone.product6s()) 3.销售发货**
	public void product6s(){
		System.out.println("宣传");
		phone.product6s();//生产的什么?
		System.out.println("销售和发货");
	}
	// **1.宣传 我们 2.生产(phone.product6Plus()) 3.销售发货**
	public void product6Plus(){
		System.out.println("宣传");
		phone.product6Plus();
		System.out.println("销售和发货");
	}
	// **1.宣传 我们 2.生产(phone.product7()) 3.销售发货**
	public void product7(){
		System.out.println("宣传");
		phone.product7();
		System.out.println("销售和发货");
	}
	// **1.宣传 我们 2.生产(phone.productX()) 3.销售发货**
	public void productX(){
		System.out.println("宣传");
		phone.productX();
		System.out.println("销售和发货");
	}
}
public class Test_fanse {
	public static void main(String[] args) {
		
	}
}

我们可以通过动态代理的方式简化销售公司的任务,动态代理的实现有两种一种是JDK的原生方式,另一种是封装了(字节码处理框架ASM)的CGLIB动态代理实现。

首先我们要细化上面的代码

苹果生产厂商提供的生产苹果手机的接口(规范)

package com.xwl;
public interface PhoneService {
	//苹果生产四种产品 交给中国工厂
		public void product6s();
		public void product6Plus();
		public void product7();
		public void productX();
}

中国富士康给出了实现制造出来实现(实现)

package com.xwl;
public class PhoneServiceImpl implements PhoneService {
		public void product6s() {
			System.out.println("6s");
		}
		public void product6Plus() {
			System.out.println("6Plus");
		}
		public void product7() {
			System.out.println("7");
		}
		public void productX() {
			System.out.println("X");
		}
}

一、JDK实现动态代理(销售公司)

代理对象JdkProxy :

	package com.xwl;
	import java.lang.reflect.InvocationHandler;
	import java.lang.reflect.Method;
	import java.lang.reflect.Proxy;
	public class JdkProxy implements InvocationHandler{
		//要代理的对象
		private Object target;
		public JdkProxy(Object target) {
			super();
			this.target = target;
		}
		public JdkProxy() {
			super();
		}
		//给一个代理对象
		public Object getProxy(){
			 return Proxy.newProxyInstance(Thread.currentThread()
		                .getContextClassLoader(), target.getClass().getInterfaces(),
		                this);
		}
		public Object invoke(Object proxy, Method method, Object[] args)
				throws Throwable {
			System.out.println("宣传");
			Object reslut = method.invoke(target, args);
			System.out.println("销售和发货");
			return reslut;
		}
	}

生产出了一个phone7开始宣传

package com.xwl;
public class TestJdk {
	public static void main(String[] args) {
		PhoneService phoneService = new PhoneServiceImpl();
		JdkProxy jdkProxy = new JdkProxy(phoneService);
		PhoneService proxy = (PhoneService) jdkProxy.getProxy();
		proxy.product7();
	}
}

CGLIB实现动态代理

代理对象CglibProxy :

package com.xwl;	
import java.lang.reflect.Method;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

public class CglibProxy implements MethodInterceptor{
	public Object intercept(Object proxy, Method method, Object[] args,
			MethodProxy methodProxy) throws Throwable {
		System.out.println("宣传");
		Object result = methodProxy.invokeSuper(proxy, args);
		System.out.println("销售和发货");
		return result;
	}
}

生产出来了一个6s开始宣传:

package com.xwl;
import org.springframework.cglib.proxy.Enhancer;
public class TestCglib {
	public static void main(String[] args) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(PhoneServiceImpl.class);//继承被代理类
		enhancer.setCallback(new CglibProxy());//设置回调
		PhoneServiceImpl PhoneProxy = (PhoneServiceImpl) enhancer.create();//生成代理对象
		PhoneProxy.product6s();
	}
}

总结

动态代理的好处是什么?
Java动态代理的优势是实现无侵入式的代码扩展,也就是方法的增强;让你可以在不用修改源码的情况下,增强一些方法;在方法的前后你可以做你任何想做的事情(甚至不去执行这个方法就可以)。
动态代理和静态代理的区别?
1.静态代理类:由程序员创建或者由第三方工具生成,再进行编译;在程序运行之前,代理类的.class文件已经存在了。
动态代理类:在程序运行时,通过反射机制动态生成。
2.静态代理类通常只代理一个类。动态代理类通常代理接口下的所有类。
3.静态代理事先知道要代理的是什么。动态代理事先不知道要代理的是什么,只有在运行的时候才能确定。
4.动态代理的调用处理程序必须事先InvocationHandler接口,及使用Proxy类中的newProxyInstance方法动态的创建代理类。
5.Java动态代理只能代理接口,要代理类需要使用第三方的CLIGB等类库。
JDK动态代理和CGLIB动态代理的区别?
JDK的动态代理机制只能代理实现了接口的类,而不能实现接口的类就不能实现JDK的动态代理,cglib是针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,但因为采用的是继承,所以不能对final修饰的类进行代理。
Enhancer
Enhancer动态创建了给定类型的子类但是拦截了所有的方法。和Proxy不一样的是,不管是接口还是类他都能正常工作。

你可能感兴趣的:(java基础)