Spring---面向切面AOP代理模式(上)

AOP 面向切面编程
Aspect Oriented Programming

最基本的实现原理是一种代理模式(跟装饰模式很像),

所谓代理模式就是:原始类的方法功能都不够强,于是不使用原始类,而是在原始类上的基础上写代理类。java中可以通过一个原始类得到一个代理类。

装饰模式:当原始类的原始方法不好用,于是继承原始类,重写里面的方法。

新建包结构:
在这里插入图片描述
新建JDK代理工厂类:JDKProxyFactory.java

package net.seehope.spring.demo.ioc.aop;

import java.lang.reflect.Proxy;
public class JDKProxyFactory {
	public static Object bind(Object origin) {
		
		// 被代理的类必须实现某一接口,jdk会根据代理类的所有接口,创建一个具有相同实现关系的类,
		//原始类和代理类之间相当于兄弟关系
		// 第三个参数,要如何增强原始类,将所有增强的逻辑写在InvocationHandler的invoke中
		return Proxy.newProxyInstance(origin.getClass().getClassLoader(), origin.getClass().getInterfaces(), 
				new JDKProxyProcessor(origin));
	}
}

之所以业务层一般都有接口,是因为基本都会通过代理增强异常回滚和日志记录功能

在创建的bind()绑定方法中,因为我们不知道传进来的和返回的参数是什么,所以使
用Object(一般为原始类对象)接收。Proxy.newProxyInstance(参数1,参数2,参数3)
返回的是一个代理类,

参数1:原始类加载器(用哪个类加载器去加载代理对象);
参数2:接口(动态代理类需要实现的接口);
参数3:实现InvocationHandler标准的类的对象,动态代理方法在执行时,会调用参数3这个对象里面的invoke()方法去执行;

代理模式会对传进来的原始类Object object进行加工,获取其类加载器和接口,在JDK允许范围内,实现目标类的所有接口,然后再创建这个接口的实现(跟原始类一样),因此原始类和代理类为兄弟关系(类加载器和接口都是一样的,所以要通过第三个参数进行区分)。
我们所有要增强的功能逻辑都放在invoke()方法中

创建代理类JDKProxyProcessor.java

import java.lang.reflect.InvocationHandler;

public class JDKProxyProcessor implements InvocationHandler {
	//原始类对象
	private Object origin;
	public JDKProxyProcessor(Object origin) {
		this.origin= origin;
	}
	
	//覆盖方法
	//目标类的所有方法都会被该方法增强
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		//如果method.invoke(method, args);不执行,那么所有原始类的方法都不会执行
		Object result = method.invoke(ori, args);
		if(method.getName().contentEquals("add")) {
			System.out.println(new Date()+"  使用参数:"+Arrays.deepToString(args)+"  执行了方法:"+method.getName()+ " 得到了: "+ result + "结果");
		}
		return result;
	}
}

invoke三个参数:

proxy:就是代理对象,newProxyInstance方法的返回对象

method:调用的方法

args: 方法中的参数

代理接口及其实现类:

public interface Service {//接口
	public void service();
	
	public int add(int x);
}

public class Service1 implements Service{//子实现
	public void service() {
		System.out.println("service 1");
	}
	public int add(int x) {
		return x+1;
	}
}

public class Service2 implements Service{//子实现
	public void service() {
		System.out.println(" service 2");
	}
	public int add(int x) {
		return x-1;
	}
}

创建代理测试主类:ProxyMain.java

public class ProxyMain {
	public static void main(String [] args) {
		Service service1 = new Service1();//原始类
		service1.service();
		System.out.println(service1.add(3));
		System.out.println("-----------------");
		
		Service proxyService2 = (Service)JDKProxyFactory.bind(service1);//代理类
		proxyService2.service();
		System.out.println(proxyService2.add(3));
	}
}

代理模式实现步骤总结:

  1. 创建JDK代理工厂类,添加bind(Object object)方法,传入原始类对象object,通过Proxy.newProxyInstance(object.类加载器, object.接口, new JDKProxyProcessor(object))返回代理类对象;
  2. 创建JDKProxyProcessor.java代理类,定义一个Object类型的参数,提供构造方法。添加invoke()方法,将所有要增强的逻辑写在该方法中。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值