Spring探索(五):AOP实现机制

1. 代理模式(Proxy Pattern):静态代理
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.动态代理(Dynamic Proxy)
为指定的接口在系统运行期间动态的生成代理对象。
java.lang.reflect.Proxy和java.lang.reflect.InvocationHandler
在这里插入图片描述
在这里插入图片描述

/**
*动态创建实现了interfaces数组中所有指定接口的实现类对象
*ClassLoader:类加载器,把.class文件加载到内存,形成Class对象
*Class[] interfaces:指定要实现的接口们
*InvocationHandler:代理对象的所有方法(个别不执行,getClass())都会调用InvocationHandler的invoke()方法
*/
Object proxyObject = Proxy.newProxyInstance(ClassLoader classLoader, Class[] interfaces, InvocationHandler h);

InvocationHandler
//在调用代理对象所实现接口中的方法时该方法被调用
public Object invoke(Object proxy, Method method, Object[] args);
* Object proxy:当前对象,即代理对象!在调用谁的方法!
* Method method:当前被调用的方法(目标方法)
* Object[] args:实参!

下面使用JDK的动态代理实现前置/后置增强:

public interface Waiter {
	 void serve();	
     void shouQian();
}

public class ManWaiter implements Waiter {
	@Override
	public void serve() {
		System.out.println("服务中...");
	}
	
	public void shouQian() {
		System.out.println("混蛋,给我钱!");
	}
}

/**
 * 前置增强
 */
public interface BeforeAdvice {
    void before();
}

/**
 * 后置增强
 */
public interface AfterAdvice {
	 void after();
}
package com.hong.proxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;
import java.util.Objects;

/**
 * 它用来生成代理对象
 * 它需要所有的参数
 * * 目标对象
 * * 增强
 */
/**
 * 1. 创建代理工厂
 * 2. 给工厂设置三样东西:
 *   * 目标对象:setTargetObject(xxx);
 *   * 前置增强:setBeforeAdvice(该接口的实现)
 *   * 后置增强:setAfterAdvice(该接口的实现)
 * 3. 调用createProxy()得到代理对象
 *   * 执行代理对象方法时:
 *   > 执行BeforeAdvice的before()
 *   > 目标对象的目标方法
 *   > 执行AfterAdvice的after()
 */
public class ProxyFactory{
	private Object targetObject;//目标对象
	private BeforeAdvice beforeAdvice;//前置增强
	private AfterAdvice afterAdvice;//后置增强
	
	/**
	 * 用来生成代理对象
	 * @return
	 */
	public Object createProxy() {
		/*
		 * 1. 给出三大参数
		 */
		ClassLoader loader = this.getClass().getClassLoader();
		Class[] interfaces = targetObject.getClass().getInterfaces();
		InvocationHandler h = (proxy,method,args) -> {
			/*
			 * 在调用代理对象的方法时会执行这里的内容
			 */
			// 执行前置增强
			if(Objects.nonNull(beforeAdvice)) {
				beforeAdvice.before();
			}

			Object result = method.invoke(targetObject, args);//执行目标对象的目标方法
			// 执行后置增强
			if(Objects.nonNull(afterAdvice)) {
				afterAdvice.after();
			}

			// 返回目标对象的返回值
			return result;
		};

		/*
		 * 2. 得到代理对象
		 */
		Object proxyObject = Proxy.newProxyInstance(loader, interfaces, h);
		return proxyObject;
	}
	
	
	public Object getTargetObject() {
		return targetObject;
	}
	public void setTargetObject(Object targetObject) {
		this.targetObject = targetObject;
	}
	public BeforeAdvice getBeforeAdvice() {
		return beforeAdvice;
	}
	public void setBeforeAdvice(BeforeAdvice beforeAdvice) {
		this.beforeAdvice = beforeAdvice;
	}
	public AfterAdvice getAfterAdvice() {
		return afterAdvice;
	}
	public void setAfterAdvice(AfterAdvice afterAdvice) {
		this.afterAdvice = afterAdvice;
	}
}
	public static void main(String[] args) {
		/**
		 *  目标是让目标对象和增强都可以切换!
		 */
		//创建工厂
		ProxyFactory factory = new ProxyFactory();
		//设置目标对象
		factory.setTargetObject(new ManWaiter());
		factory.setBeforeAdvice(() -> System.out.println("您好不好!"));
		factory.setAfterAdvice(() -> System.out.println("再见不见!"));

		Waiter waiter = (Waiter)factory.createProxy();
		waiter.shouQian();
		
		//打印结果
		您好不好!
		混蛋,给我钱!
		再见不见!
	}

3.动态字节码生成
在这里插入图片描述

public class Requestable {
    public void request(){
        System.out.println("method in Requestable without implement any interface");
    }
}

import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;

import java.lang.reflect.Method;

/**
 * Created by John on 2018/10/31.
 */
public class RequestCtrlClallback implements MethodInterceptor {

    @Override
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        if (method.getName().equals("request")){
            System.out.println("CGLIB proxy");
            return methodProxy.invokeSuper(o,objects);
        }
        return null;
    }
}

import net.sf.cglib.proxy.Enhancer;

public class Demo3 {
	public static void main(String[] args) {
		Enhancer enhancer = new Enhancer();
		enhancer.setSuperclass(Requestable.class);
		enhancer.setCallback(new RequestCtrlClallback());
		Requestable proxy = (Requestable) enhancer.create();
		proxy.request();
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值