静态代理, 动态代理, cglib代理

代理技术被一些优秀的框架广泛的使用, 比如spring 的中aop 事务就是通过 动态代理和cglib 代理,共同实现的, hibernate 中的懒加载, 通过返回代理对象延迟加载, 下面我们学习java 中的三种代理技术


定义一个通用的接口

package com.zzq.response.test;

public interface IUserDao {

	void save();
}

实现接口

package com.zzq.response.test;

public class UserDao  implements IUserDao{

	public void save() {
		 System.out.println("----已经保存数据!----");
	}
}

静态代理

要球 : 要实现静态代理, 代理对象和被代理对象一定同时继承同一个父类, 或者是接口,我们用代码演示

静态代理的本质就是通过在加载新的方法中调用原有的方法 我们看代码

package com.zzq.response.test;

public class UserDaoProxy  implements IUserDao{

	 //接收保存目标对象
    private IUserDao target;
    public UserDaoProxy(IUserDao target){
        this.target=target;
    }

    public void save() {
        System.out.println("开始事务...");
        target.save();//执行目标对象的方法
        System.out.println("提交事务...");
    }
}

测试

package com.zzq.response.test;

public class test {

	public static void main(String[] args) {
        //目标对象
        UserDao target = new UserDao();

        //代理对象,把目标对象传给代理对象,建立代理关系
        UserDaoProxy proxy = new UserDaoProxy(target);

        proxy.save();//执行的是代理的方法
    }
}

静态代理是由缺陷的, 因为他每次只能代理一个方法,如果多个呢? 这时候我们就出现了和静态代理对应的动态代理技术,

动态代理

动态代理相对于静态代理来说, 可以实现动态的对方法,进行代理, 也就是弥补了静态代理的缺点,一次书写,指定代理的方法, 该代理方式是通过 接口代理, 也就是说被代理对象必须,要有接口, 不然不能进行动态代理,该代理技术在jdk 中, 因此也叫做jdk代理, 接口代理

动态代理的方法

proxy .newProxyInstance(被代理对象的类加载器,被代理对象的接口,被代理对象具体的代理细节)

   我们通过代理进行演示

接口中定义方法

package com.zzq.response.test2;

public interface IUserService {

	
	void add(); 
	void delete(); 
	void update(); 
	void insert(); 
}

实现类

package com.zzq.response.test2;

public class UserServiceImpl implements IUserService {

	public void add() {
		System.out.println("add........");
	}

	public void delete() {
		// TODO Auto-generated method stub
		System.out.println("delete........");

	}

	public void update() {
		// TODO Auto-generated method stub

		System.out.println("update........");
	}

	public void insert() {
		// TODO Auto-generated method stub

		System.out.println("insert........");
	}

}

实现代理

package com.zzq.response.test2;

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

public class UserServiceProxyFactory {

	private IUserService userService ; 
	
	public UserServiceProxyFactory(IUserService userService){
		this.userService = userService ; 
	}
	
	public  IUserService getIUserService(){
		
		
		return (IUserService) Proxy.newProxyInstance(
				userService.getClass().getClassLoader()
				,userService.getClass().getInterfaces(),
				new InvocationHandler() {
					
					public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
						System.out.println("开启事务");
						Object invoke = method.invoke(userService, args); 
						System.out.println("关闭事务");
						return invoke ; 
					}
				}); 
	}
}

测试

package com.zzq.response.test2;

public class App {

	public static void main(String[] args) {
		IUserService userService = new UserServiceImpl(); 
		
		UserServiceProxyFactory userServiceProxyFactory = new UserServiceProxyFactory(userService); 
		
		IUserService iUserService = userServiceProxyFactory.getIUserService(); 
		iUserService.add(); 
		
	}
}

其实spring aop 事务就是 使用 动态代理, 它整合了动态代理和cglib 代理技术

Cglib 代理

cglib 代理相对于 java 来说属于第三方代理, 他的好处是 ,不用实现接口, 不用继承 , 代理实现原理是, 通过继承原对象的方式进行代理,下面我们来看代码演示

这里代码直接基于 动态代理的基础上进行书写

package cn.itcast.c_proxy;

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

import org.springframework.cglib.proxy.Callback;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import cn.itcast.service.UserService;
import cn.itcast.service.UserServiceImpl;

//观光代码=>cglib代理
public class UserServiceProxyFactory2 implements MethodInterceptor {
	

	public UserService getUserServiceProxy(){
		
		Enhancer en = new Enhancer();//帮我们生成代理对象
		
		en.setSuperclass(UserServiceImpl.class);//设置对谁进行代理
		
		en.setCallback(this);//代理要做什么
		
		UserService us = (UserService) en.create();//创建代理对象
		
		return us;
	}

	@Override
	public Object intercept(Object prxoyobj, Method method, Object[] arg, MethodProxy methodProxy) throws Throwable {
		//打开事务
		System.out.println("打开事务!");
		//调用原有方法
		Object returnValue = methodProxy.invokeSuper(prxoyobj, arg);
		//提交事务
		System.out.println("提交事务!");
		
		return returnValue;
	}


}
好了这就是java 中的三种代理技术,其实想想挺简单的, 但是我们在实际开发中不会使用这些技术的, 因为spring 为我们整合好了,但是多知道,没有坏处对吧 微笑





















猜你喜欢

转载自blog.csdn.net/qq_39148187/article/details/80558147