cauchy4932的博客

你的孤独虽败犹荣

代理模式(proxy)

        转眼间工作一年多了,感觉技术没有什么提升,只是对开发工具熟悉了一些,对复制粘贴熟悉了一些,可是对程序的了解还是停留在入职前。可能是平时不喜欢钻研,只要把工作完成好就行了,至于为什么这样做,很少去考虑。平时自己利用休息时间自学的时候也是三天打鱼两天晒网,而且很少自己动手做,这样很快就忘光了,跟没学没两样。有一个同事跟我差不多一起入职的,已经辞职一个星期了,面试了十几家公司,面试官问的很多技术问题,他只是知道,面试官深入去问的时候,就一概不知了。他把大多面试官问的问题都告诉我了,结果我发现自己也是什么都不知道,突然感觉好迷茫,什么程序员工作两年后工资就翻倍,什么月薪10k以上,感觉像我现在的状态别说两年后了,就是五年后工资翻倍都是问题。因此,在此立个flag,以后每周要写一篇博客来记录学习的笔记。鄙人从小语文就差,因此在语言组织方面有缺陷,希望大家谅解。这是我的第一个博客笔记,原谅我前面的废话,如果笔记中有错误希望博友能够直接留言指出,在此谢谢各位博友了。下面谈谈java中的代理

代理是一种设计模式,可以通过代理对象来访问目标对象。这样可以在访问目标对象的方法前后,增加额外的功能操作。扩展了目标对象的功能。

一、静态代理

优点:静态代理可以在不修改目标对象功能的前提下,对目标对象功能进行扩展。

缺点:代理对象与目标对象实现一样的接口,因此要写很多代理类,而且一旦接口增加了方法,代理对象和目标对象都要去实现,维护麻烦。样的接口

package test.proxy_static;
/**
 * 目标对象类
 * @author Shepherd
 *
 */
public class UserDao implements IUserDao{
	@Override
	public void save() {
		System.out.println("执行目标对象save方法");//业务方法
	}
}

package test.proxy_static;
/**
 * 目标对象实现的接口
 * @author Shepherd
 *
 */
public interface IUserDao {
	public void save();
}

package test.proxy_static;
/**
 * 代理对象类(需要实现目标对象一样的接口)
 * @author Shepherd
 *
 */
public class UserDaoProxy implements IUserDao{
	private IUserDao target;	//代理对象中维护的目标对象
	public UserDaoProxy(IUserDao userDao) {
		this.target = userDao;
	}
	@Override
	public void save() {
		System.out.println("执行目标对象前");
		target.save();			//实际执行的是目标对象中的save()方法
		System.out.println("执行目标对象后");
	}

}

package test.proxy_static;
/**
 * 测试程序
 * @author Shepherd
 *
 */
public class App {
	public static void main(String[] args) {
		UserDao userDao = new UserDao();	//创建目标对象
		IUserDao userDaoProxy = new UserDaoProxy(userDao);//创建代理对象,里面维护一个目标对象
		userDaoProxy.save();	//执行代理对象的save()方法
	}
}
/*以下是输出结果:
执行目标对象前
执行目标对象save方法
执行目标对象后*/

二、动态代理中的jdk代理

代理对象的创建是利用jdk的api,动态在在内存中构建代理对象。

优点:代理对象是由jdk动态构建,可以代理不同类型的目标对象,不需要引用第三方jar包

缺点:目标对象也必须实现接口,否则不能代理

目标对象及其实现的接口与静态代理一样,下面是利用jdk代理创建代理工厂

package test.proxy_static;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
 * jdk代理工厂类
 * @author Shepherd
 *
 */
public class JDKProxyFactory {
	private Object target;						//维护的目标对象
	public JDKProxyFactory(Object target) {
		this.target = target;
	}
	public  Object getProxyInstance(){				//返回代理对象实例
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), //当前目标对象的类加载器
			target.getClass().getInterfaces(), 						//当前目标对象实现的接口类型
			new InvocationHandler() {								//事件处理器
				
				@Override
				public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
					System.out.println("执行目标对象前");
					Object returnValue = method.invoke(target, args);
					System.out.println("执行目标对象后");
					return returnValue;
				}
			});
	}
}
package test.proxy_static;
/**
 * 测试程序
 * @author Shepherd
 *
 */
public class App {
	public static void main(String[] args) {
		UserDao userDao = new UserDao();	//创建目标对象
		System.out.println("目标对象:"+userDao.getClass());//输出目标对象的类型
		JDKProxyFactory proxyFactory = new JDKProxyFactory(userDao);
		IUserDao userDaoProxy = (IUserDao) proxyFactory.getProxyInstance();//利用代理工厂创建一个代理对象
		System.out.println("代理对象:"+userDaoProxy.getClass());//输出代理对象的类型
		userDaoProxy.save();	//执行代理对象的save()方法
	}
}
/*以下是输出结果:
目标对象:class test.proxy_static.UserDao
代理对象:class com.sun.proxy.$Proxy0
执行目标对象前
执行目标对象save方法
执行目标对象后
*/

三、cglib动态代理

Cglib代理,也叫做子类代理。在内存中构建一个子类对象从而实现对目标对象功能的扩展。

优点:代理对象不需要实现目标对象实现的接口,目标对象也可以不实现接口

缺点:需要引用第三方cglib-*.jar包

package test.proxy_cglib;
/**
 * 需要代理的目标对象类
 * @author Shepherd
 */
public class UserDao {
	public void save() {
		System.out.println("执行目标对象save方法");
	}
}

package test.proxy_cglib;

import java.lang.reflect.Method;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
/**
 * cglib代理工厂
 * @author Shepherd
 */
public class CglibProxyFactory implements MethodInterceptor{	//代理工厂类需实现MethodInterceptor接口
	private Object target;					//工厂类里维护的目标对象
	public CglibProxyFactory(Object target) {
		this.target = target;
	}
	public Object getProxyInstance(){	//返回子类代理对象
		Enhancer en = new Enhancer();		//创建子类代理的工具类
		en.setSuperclass(target.getClass());//指定该代理对象的父类
		en.setCallback(this);				//设置回掉函数
		return en.create();		//创建子类代理对象
	}
	@Override
	public Object intercept(Object obj, Method method, Object[] arg2, MethodProxy arg3)
			throws Throwable {
			System.out.println("执行目标方法前");
			Object returnValue = method.invoke(target, arg2);
			System.out.println("执行目标方法后");
		return returnValue;
	}
}

/**
 * 主程序
 * @author Shepherd
 */
public class App {
	public static void main(String[] args) {
		UserDao userDao = new UserDao();
		System.out.println("目标对象:"+userDao.getClass());
		CglibProxyFactory proxyFactory = new CglibProxyFactory(userDao);//创建cglib代理工厂
		//因为子类代理继承了目标对象,所以可以用目标对象类型接收
		UserDao proxyInstance = (UserDao) proxyFactory.getProxyInstance();//利用代理工厂创建子类代理对象
		System.out.println("cglib代理对象:"+proxyInstance.getClass());//输出cglib代理对象类型
		proxyInstance.save();
	}
}
/*以下是输出结果:
目标对象:class test.proxy_cglib.UserDao
cglib代理对象:class test.proxy_cglib.UserDao$$EnhancerByCGLIB$$9373ca85
执行目标方法前
执行目标对象save方法
执行目标方法后
*/







阅读更多
版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cauchy4932/article/details/79948241
文章标签: proxy java
个人分类: javaEE
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

关闭
关闭