Java代理模式,
分享于 点击 10414 次 点评:239
Java代理模式,
代理模式提供了对目标对象的其他访问方式;比如信用卡办理代理,保险代理,秘书为老板代理等等......
其中有两个对象:代理对象和目标对象;
代理的目的:是获取目标对象的代理对象,然后通过代理对象来实现对目标对象方法的扩展和调用。
代理的分类:静态代理和动态代理;
静态代理:需要我们自己创建代理对象和目标对象实现相同的接口,通过代理对象的构造器维护目标对象,最后实现调用。
//接口定义
public interface UserDao {
void save();
}
//目标对象实现接口
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("执行保存");
}
}
//代理对象实现同一接口
public class ProxyUserDaoImpl implements UserDao {
// 要代理的目标对象
private UserDaoImpl target;
//维护目标对象
public ProxyUserDaoImpl(UserDaoImpl target) {
super();
this.target = target;
}
@Override
public void save() {
System.out.println("方法执行前");
target.save();
System.out.println("方法执行后");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//创建目标对象
UserDaoImpl userDaoImpl = new UserDaoImpl();
//和代理对象产生关系
ProxyUserDaoImpl proxyUserDaoImpl = new ProxyUserDaoImpl(userDaoImpl);
//代理调用方法
proxyUserDaoImpl.save();
}
}
//执行结果
方法执行前
执行保存
方法执行后
动态代理:因为代理对象不是我们自己创建的,是通过代码在内存中创建的代理对象,所以称为动态代理
动态代理分为两种方式:一种是JDK代理;一种是Cglib代理(他们是通过不同的方式生成代理对象的)
两者的区别:JDK代理也叫接口代理,需要目标对象实现一个接口。因为生产代理对象的时候要用到目标对象的接口
//接口定义
public interface InterfaceDao {
boolean save();
}
//目标对象实现接口
public class InterfaceDaoImpl implements InterfaceDao{
@Override
public boolean save() {
User u = new User();
u.setName("张三");
System.out.println("保存用户:"+u.getName());
return true;
}
}
//代理工厂类,用于生产代理对象
public class ProxyFactory {
//维护目标对象
private Object target;
public ProxyFactory(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 result = method.invoke(target, args);
System.out.println("结束事物");
return result;
}
});
}
}
//测试类
public class DynamicTest {
public static void main(String[] args) {
//创建目标对象
InterfaceDaoImpl interfaceDaoImpl = new InterfaceDaoImpl();
System.out.println("目标对象类型"+interfaceDaoImpl.getClass());
//给目标对象创建代理对象 然后产生关联
InterfaceDao proxyInstance = (InterfaceDao)new ProxyFactory(interfaceDaoImpl).getProxyInstance();
System.out.println("代理对象类型"+proxyInstance.getClass());
proxyInstance.save();
}
}
//运行结果(注意观察代理对象的类型)
目标对象类型class xd.designmodel.proxydemo.dynamicproxy.InterfaceDaoImpl
代理对象类型class com.sun.proxy.$Proxy0
开始事物
保存用户:张三
结束事物
Cglib代理可以代理所有的类型,是以目标对象子类的方式实现代理的-在内存中构建目标对象的子类
//定义目标对象类
public class UserDao {
public void save(){
System.out.println("保存成功");
}
}
//代理工厂类(原理是通过拦截器)
public class ProxyFactory implements MethodInterceptor {
// 同样的给出目标对象
private Object obj;
//通过构造器和代理可以产生关联
public ProxyFactory(Object obj) {
this.obj = obj;
}
// 给目标对象创建代理对象
public Object getNewInstance() {
// 工具类
Enhancer e = new Enhancer();
// 设置父类
e.setSuperclass(obj.getClass());
// 设置回掉函数
e.setCallback(this);
// 创建子类(代理对象)
return e.create();
}
@Override
public Object intercept(Object arg0, Method arg1, Object[] arg2, MethodProxy arg3) throws Throwable {
System.out.println("开始执行");
Object invoke = arg1.invoke(obj, arg2);
System.out.println("执行完成");
return invoke;
}
}
//测试类
public class CglibTest {
public static void main(String[] args) {
UserDao userDao = new UserDao();
System.out.println("目标对象"+userDao.getClass());
UserDao proxy = (UserDao)new ProxyFactory(userDao).getNewInstance();
System.out.println("代理对象"+proxy.getClass());
proxy.save();
}
}
//运行结果(注意观察代理对象的类型)
目标对象class xd.designmodel.proxydemo.cglibproxy.UserDao
代理对象class xd.designmodel.proxydemo.cglibproxy.UserDao$$EnhancerByCGLIB$$2ec6c9eb
开始执行
保存成功
执行完成
相关文章
- 暂无相关文章
用户点评