代理技术被一些优秀的框架广泛的使用, 比如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 代理相对于 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 为我们整合好了,但是多知道,没有坏处对吧