Java代理模式
- 什么是代理模式
在代理模式中,一个类代表另一个类的功能,一般用于对要访问的的类做的一些控制,功能增强,同时又不想影响原来类的正常业务,不改变源代码的情况下,实现对目标对象的功能扩展,甚至也可以对目标对象进行覆盖和重写(Spring AOP 就是用了代理模式) - 例子:
租房子,通过房屋中介
找工作,通过招聘平台
找对象,通过婚恋平台 - 代理模式分为 “静态代理” 和 “动态代理”
静态代理:(目标接口,目标接口实现,代理类)
- 优点:可以实现不对目标对象进行修改的前提下,对目标对象进行功能的扩展和 增强,也就是扩展原来的功能,不污染代码
- 缺点:应为代理对象,需要实现与无标对象一样的接口,如果目标接口类繁多,也会导致代理类繁多,同时一旦接口增加方法,则目标对象和代理类都需要维护 正应为有这个缺点所以我们就出了“动态代理”
动态代理 :(目标接口,目标接口实现,实现InvocationHandler的类)
-
目的:为了解决静态代理的弊端,我们可以使用动态代理,想代理哪一个类就代理哪一个类
-
实现步骤
1:新建一个接口
2: 为接口创建一个实现类
3: 创建代理类实现java.lang.reflect.InvocationHandler接口
4: 创建一个动态代理类进行测试(动态代理会在程序运行时生成一个$Proxy0.Class,该class类在代码中看不到 在磁盘中也没有保 存,是程序运行的时候在jvm内存中生成的)
了解了这么多,我们来看一个简单的动态代理的例子吧
简单案例:
- 1:首先我们新建一个接口TargetClass
package com.zcl.dynamicproxy;
/**
* 接口
*/
public interface TargetClass {
//一个输出方法
public void sayHi();
}
- 2:然后我们为接口创建一个实现类
package com.zcl.dynamicproxy;
/**
* TargetClass接口实现类
*/
public class TargetClassimpl implements TargetClass {
//实现接口的方法
public void sayHi() {
System.out.println("你好静态代理");
}
}
- 3: 接着创建一个代理类JDKDynamicProxy实现java.lang.reflect.InvocationHandler接口,重写invoke方法
package com.zcl.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class JDKDynamicProxy implements InvocationHandler {
private Object target;
public JDKDynamicProxy(Object target) {
this.target = target;
}
/**
*
* @param proxy :代理类
* @param method :sayHi方法(反射对象)
* @param args :代表参数方法的参数
* @return
* @throws Throwable
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("执行方法前....");
Object result = method.invoke(target, args);
System.out.println("执行方法后....");
return null;
}
}
- 4:测试类
package com.zcl.dynamicproxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
/**
* 动态代理对象
*/
public class test {
public static void main(String[] args) {
//如果使用代理模式
//Proxy.newProxyInstance方法的返回结果是我们真正的代理类
TargetClass targetClass = (TargetClass)Proxy.newProxyInstance(TargetClass.class.getClassLoader(),
new Class<?>[] {TargetClass.class},
new JDKDynamicProxy(new TargetClassimpl()));
//输出方法
targetClass.sayHi();
}
}
- 输出结果
执行方法前....
你好静态代理
执行方法后....
Spring AOP 与 动态代理
AOP 专门用于处理系统中分布于各个模块(不同方法)中的交叉关注点的问题,在 Java EE 应用中,常常通过 AOP 来处理一些具有横切性质的系统级服务,如事务管理、安全检查、缓存、对象池管理等,AOP 已经成为一种非常常用的解决方案。