前言:
由于复习mybatis知识点的时候,mapper代理涉及到了代理模式,于是阅读了相关资料以后,小结一下代理模式。
1.UML图
2.角色分类
2.1 抽象对象:是目标对象和代理对象的抽象父类。
2.2 目标对象:要被代理的对象,实现了抽象对象。比如未成年人
2.3 代理对象:作为中介,接收外界指令,传递给代理对象(生成代理对象)。比如未成年人看护人。
3.常见的代理模式
3.1 静态代理(目标对象和代理对象都要实现抽象父类)
抽象对象:接口声明playgame方法
public interface IUserDao {
void playgame();
}
目标对象:未成年人实现playgame 方法
public class UserDaoImp implements IUserDao {
public void playgame() {
System.out.println("----玩儿童游戏!----");
}
}
代理对象:未成年人人监护人,也实现palygame方法,并且生成了为目标对象,以此对目标对象进行操作。
public class UserDaoProxy implements IUserDao {
private IUserDao target;
public UserDaoProxy(IUserDao target){
this.target=target;
}
@Override
public void playgame() {
// TODO Auto-generated method stub
System.out.println("开始事务...");
target.playgame();//执行目标对象的方法
System.out.println("提交事务...");
}
}
测试类
public class Test {
public static void main(String[] args) {
//目标对象
IUserDao target = new UserDaoImp();
//代理对象,把目标对象传给代理对象,建立代理关系
UserDaoProxy proxy = new UserDaoProxy(target);
proxy.playgame();//执行的是代理的方法
}
}
3.2 动态(JDK)代理
①代理对象无需实现抽象父类
②代理对象的生成,是利用JDK的API,动态的在内存中构建代理对象
③引入 java.lang.reflect.Proxy 包
抽象对象:接口声明playgame方法
public interface IUserDao {
void playgame();
}
目标对象:未成年人实现playgame 方法
public class UserDaoImp implements IUserDao {
public void playgame() {
System.out.println("----玩儿童游戏!----");
}
}
代理工厂:相当静态代理中的代理对象
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("开始事务2");
//执行目标对象方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务2");
return returnValue;
}
}
);
}
}
测试类
//动态代理也称为 :JDK代理,接口代理
public class Test {
public static void main(String[] args) {
// 目标对象
IUserDao target = new UserDaoImp();
// 【原始的类型 class cn.itcast.b_dynamic.UserDao】
System.out.println(target.getClass());
// 给目标对象,创建代理对象
IUserDao proxy = (IUserDao) new ProxyFactory(target).getProxyInstance();
// class $Proxy0 内存中动态生成的代理对象
System.out.println(proxy.getClass());
// 执行方法 【代理对象】
proxy.playgame();
}
}
3.3 Cglib代理(用于SpringAOP)
①无需抽象对象
②引入 Spring-core-3.2.0.RELEASE.jar 包
目标对象
public class UserDaoImp{
public void playgame() {
System.out.println("----已经保存数据!----");
}
}
代理工厂:
public class ProxyFactory implements MethodInterceptor{
//维护目标对象
private Object target;
public ProxyFactory(Object target) {
this.target = target;
}
//给目标对象创建一个代理对象
public Object getProxyInstance(){
//1.工具类
Enhancer en = new Enhancer();
//2.设置父类
en.setSuperclass(target.getClass());
//3.设置回调函数
en.setCallback(this);
//4.创建子类(代理对象)
return en.create();
}
@Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
System.out.println("开始事务...");
//执行目标对象的方法
Object returnValue = method.invoke(target, args);
System.out.println("提交事务...");
return returnValue;
}
}
测试类
public class Test {
public static void main(String[] args) {
//目标对象
UserDaoImp target = new UserDaoImp();
//代理对象
UserDaoImp proxy = (UserDaoImp)new ProxyFactory(target).getProxyInstance();
//执行代理对象的方法
proxy.playgame();
}
}
4.参考
https://www.cnblogs.com/cenyu/p/6289209.html