在不改变原有代码情况下,实现对原有代码的增强
张三找律师打官司
特点:代理类代码是写死的
优点:在不改变原有代码的情况下实现了对原有业务增强
缺点:一个目标类就需要一个代理类,不便于业务拓展
定义接口,规定核心业务(代理对象与目标对象做的是一样的事情)
- //规定代理对象与目标对象之间所做的核心业务
- public interface Speak {
- void say();
- }
编写目标类(实现核心的业务)
- public class 张三类 implements Speak{
- @Override
- public void say() {
- System.out.println("我每天吃一顿饭,挨三顿打。我请求离婚");
- }
- }
编写代理类(代理目标类--实现对目标的增强)
- public class 律师类 implements Speak {
- // 创建目标类
- private 张三类 张三;
- public 律师类(张三类 张三) {
- this.张三 = 张三;
- }
- @Override
- public void say() {
- System.out.println("巴拉巴拉...接下来由原告述说");
- 张三.say();// 真正做核心业务还是目标对象,代理对象只是在目的对象的基础上增强
- }
- }
测试
- public static void main(String[] args) {
- 张三类 张三 = new 张三类();
- 律师类 律师 = new 律师类(张三);
- // 真正的是代理类方法
- 律师.say();
- }
特点:代理类代码是动态生成
特点
基于接口实现(invocationhandler)
根据不同目标对象,生成不同代理对象
实现
定义接口,规定核心业务
- public interface Speak {
- void say();
- }
编写目标类
- public class 张三类 implements Speak{
- @Override
- public void say() {
- System.out.println("我每天吃一顿饭,挨三顿打。我请求离婚");
- }
- }
编写JDK动态代理
- public class JDKProxy implements InvocationHandler {
- // 目标对象
- private Object 客户;
- public JDKProxy(Object obj) {
- this.客户 = obj;
- }
- // 增强代码写在invoke方法
- // proxy:代理对象
- // method:待增强的方法(接口中定义的方法)
- // args:待增强方法的参数
- @Override
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("巴拉巴拉...接下来由原告述说");
- // 用完目标对象方法时可能有返回
- Object result = method.invoke(客户, args);
- return result;
- }
- }
生成代理对象
- public static void main(String[] args) {
- 张三类 张三 = new 张三类();
- // 调用Proxy类的newProxyInstance静态方法生成代理对象
- Speak speak = (Speak) Proxy.newProxyInstance(张三.getClass().getClassLoader(), 张三.getClass().getInterfaces(), new JDKProxy(张三));
- speak.say();
- }
特点
基于类的继承实现(MethodInterceptor)
需要导包(cglib、asm)
实现
编写目标对象
- public class 张三类{
- public void say() {
- System.out.println("我每天吃一顿饭,挨三顿打。我请求离婚");
- }
- }
编写代理类(实现MethodInterceptor)
- public class MyProxy implements MethodInterceptor {
- // 目标对象
- private Object target;
- public MyProxy(Object obj) {
- this.target = obj;
- }
- // intercept:编写增强的代码
- // method:待增强的方法
- // arg:待增强的方法需要的参数
- @Override
- public Object intercept(Object arg0, Method method, Object[] arg2, MethodProxy arg3) throws Throwable {
- System.out.println("巴拉巴拉...接下来由原告述说");
- Object result = method.invoke(target, arg2);//目标对象方法的返回值 如果为void 则为null
- return result;
- }
- }
获取代理对象
- public static void main(String[] args) {
- 张三类 张三 = new 张三类();
- MyProxy myProxy = new MyProxy(张三);
- // 第一个参数:目标对象类型
- // 第二个参数:实现MethodInterceptor类的对象
- 张三类 create = (张三类) Enhancer.create(张三.getClass(), myProxy);
- create.say();
- }
代理类中默认将接口所有方法进行增强,若想对指定方法增强可自定义注解打标记,代理类中去判断标记
创建注解
- @Target(ElementType.METHOD)
- @Retention(RetentionPolicy.RUNTIME)
- public @interface NeedAdd {}
方法中添加注解
- public interface Speak {
- @NeedAdd
- void say();
- int cry(int time);
- }
根据方法是否存在注解进行使用
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- Object result = null;
- // 判断是否存在注解标记
- if(method.isAnnotationPresent(NeedAdd.class)) {
- System.out.println("巴拉巴拉...接下来由原告述说");
- // 用完目标对象方法时可能有返回
- result = method.invoke(客户, args);
- }else {
- // 用完目标对象方法时可能有返回
- result = method.invoke(target, args);
- }
- return result;
- }