关于java代理

静态代理:使用硬编码的方式,为每个要被代理的方法写一个对应的代理方法:

被代理类:

package red.sea.daelly.proxy.dao.impl;

import red.sea.daelly.proxy.dao.Count;

public class CountImpl implements Count {

	@Override
	public void queryCount() {
		System.out.println("查看账户的方法……");

	}

	@Override
	public void updateCount() {
		System.out.println("修改账户的方法……");

	}

}
代理类:

package red.sea.daelly.proxy.dao.impl;

import red.sea.daelly.proxy.dao.Count;

public class CountProxy implements Count {
	
	//被代理的类
	private CountImpl countImpl;
	
	public CountProxy(CountImpl countImpl){
		this.countImpl = countImpl;
	}

	@Override
	public void queryCount() {
		System.out.println("事物处理前……");
		countImpl.queryCount();
		System.out.println("事物处理后……");
	}

	@Override
	public void updateCount() {
		System.out.println("事物处理前……");
		countImpl.updateCount();
		System.out.println("事物处理后……");
	}

}
这种方式太死板,而且工作量太大。

jdk动态代理:

被代理类:

package red.sea.daelly.proxy.dao;

public interface Bookfacade {
	public void addBook();
}

package red.sea.daelly.proxy.dao.impl;

import red.sea.daelly.proxy.dao.Bookfacade;

public class BookfacadeImpl implements Bookfacade {

	@Override
	public void addBook() {
		System.out.println("曾加图书的方法……");
	}
}

代理类:
package red.sea.daelly.proxy.dao.proxy;

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

public class BookFacadeProxy implements InvocationHandler {
	
	private Object target;
	
	public Object bind(Object target){
		this.target = target;
		return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this);
	}

	@Override
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
		Object result = null;
		System.out.println("事物开始……");
		result = method.invoke(target, args);
		System.out.println("事物结束……");
		return result;
	}

}

调用:
package red.sea.daelly.proxy.test;

import red.sea.daelly.proxy.dao.Bookfacade;
import red.sea.daelly.proxy.dao.impl.BookfacadeImpl;
import red.sea.daelly.proxy.dao.proxy.BookFacadeProxy;
/**
 * 动态代理的测试类
 * @author daelly
 *
 */
public class DynamicProxyTest {
	public static void main(String[] args){
		BookFacadeProxy proxy = new BookFacadeProxy();
		Bookfacade bookfacade = (Bookfacade) proxy.bind(new BookfacadeImpl());
		bookfacade.addBook();
	}
}

这种方式灵活,相同的事物控制代码字需要写一遍就可以了,但是有个小问题,就是被代理的类必须是一个接口的实现。最后介绍的Cglib动态代理方式就不会有这个限制。

cglib动态代理:

被代理类

package red.sea.daelly.cglib.demo;

/**
 * 定义一个被代理的类
 * @author daelly
 *
 */
public class HelloWorld {
	public String sayHello(String name){
		System.out.println("执行sayHello()");
		return "hello,"+name;
	}
}
定义一个拦截器:

package red.sea.daelly.cglib.demo;

import java.lang.reflect.Method;

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

public class MyMethodInterceptor implements MethodInterceptor {

	/**
	 * obj:代理对象实例
	 * method:原对象的方法
	 * args:传递给方法的参数
	 * proxy:与原对象中method相互对应的代理对象的方法
	 */
	@Override
	public Object intercept(Object obj, Method method, Object[] args,MethodProxy proxy) throws Throwable {
		System.out.println("执行方法"+method+"前");
		//这里如果写成invoke(obj, args);就会死循环调用自己,千万记住,我们要调用原方法
		Object returnVal = proxy.invokeSuper(obj, args);
		System.out.println("执行方法"+method+"后");
		return returnVal;
	}

}
定义一个创建代理对象的factory方法:

package red.sea.daelly.cglib.demo;

import net.sf.cglib.proxy.Enhancer;

public class ProxyFactory {
	public static Object getProxyObj(String classz) throws ClassNotFoundException{
		Class<?> superClass = Class.forName(classz);
		Enhancer enhancer = new Enhancer();
		//设置代理对象的父类
		enhancer.setSuperclass(superClass);
		//设置回调对象,调用代理对象里面的方法时,实际上执行的是回调对象(里的interept方法)
		enhancer.setCallback(new MyMethodInterceptor());
		//创建代理对象
		return enhancer.create();
	}
}

调用测试:

package red.sea.daelly.cglib.demo;

public class CglibDemoTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			//只需要通过类的名字,就能代理之歌方法的执行
			HelloWorld hello = (HelloWorld) ProxyFactory.getProxyObj(HelloWorld.class.getName());
			String result = hello.sayHello("Cglib");
			System.out.println(result);
		} catch (Exception e) {
			e.printStackTrace();
		}

	}

}


三种方式已介绍完



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、付费专栏及课程。

余额充值