AOP 学前准备

》 初识 代理模式

1.代理模式

概念:   为真实对象提供一层代理

本质:   保护真实对象

分类

      概念分类:  静态代理   动态代理

      功能分类:  虚代理   远程代理(RMI)   copy-on-write   保护代理  Cache代理   防火墙代理  同步代理 智能指引

 

静态代理 :  有一个中间类,用来调用真实对象,测试类调用该类

//	静态代理演示
//	真实对象
	private PersonRun pr = new KgcInstall();
	@Override
	public void run() {
//		判断一下让真是对象跑步的是谁
//		if(如果是教练)
		pr.run();	
//		if(如果不是教练)
//		返回 抱歉,您没有权限让真实对象跑步
		
	}

   缺点: 修改和新增 真实对象时会产生大量的冗余工作量

动态代理:    使用了反射的技术

实现步骤:

     1、 实现Invocation

     2、创建目标对象

     3、将目标对象与代理对象进行关联

     4、使用目标对象调用对应的方法

public class DynamicProxy implements InvocationHandler {
//	真实对象
	private Object obj;
	
	public Object getProxy(Object objArgs){
//		传入真实对象
		
		this.obj = objArgs;
//		创建一个代理对象返回给客户端调用
//		将代理对象与真实对象进行关联
		Object proxyObj = Proxy.newProxyInstance(
				objArgs.getClass().getClassLoader(), 
				objArgs.getClass().getInterfaces(), 
				this);
		return proxyObj;
		
	}
	
	
	@Override
//	调用方法   代理对象  待执行方法  参数列表
	public Object invoke(Object proxy, Method method, Object[] args)
			throws Throwable {
//		方法调用之前
		System.out.println("方法调用之前");
//		协助调用真实对象里的方法
		Object resultObj = method.invoke(obj, args);
//		方法调用之后
		System.out.println("方法调用之后");
		return resultObj;
	}
	
}

 调用 getProxy() 的方法,获取对象

//		演示动态代理调用
//		获取真实对象
		PersonRun pr = new KgcInstall();
		DynamicProxy dp = new DynamicProxy();
//		将真实对象传入动态代理,并生成对应的代理对象
		PersonRun proxyPr = (PersonRun)dp.getProxy(pr);  //只能代理接口
		
        	proxyPr.run();

     缺点: 只能代理接口

 

2.CGLIB

  概念 :实现动态代理

  底层 是 :   1. ASM

                      2.CGLIB 是通过创建目标对象的子类的形式来进行拦截和处理

                         (CGLIB 不能处理final 对象)

 

  使用 步骤: 

    1.引入CGLIB 的 jar 包

    2.实现methodInterceptor接口

    3.获取目标对象

    4.创建代理对象 :    Enhancer :   1.superClass        2.callback            3.Enhancer.create

    5.使用目标对象调用对应的方法

public class CglibProxy implements MethodInterceptor {

//	需要一个被代理对象(目标对象)
	private Object target;
//	传入目标对象
	public CglibProxy(Object target){
		this.target = target;
	}
	
//	返回客户一个代理对象
	public Object getProxy(){
		Enhancer e = new Enhancer();
//		CGLIB 会创建一个目标对象的子对象,通过反射对父对象的内容进行拦截和处理
		e.setSuperclass(target.getClass());
		e.setCallback(this);
//		创建代理对象
		return e.create();
	}
	
	
	@Override
	public Object intercept(Object arg0, Method arg1, Object[] arg2,
			MethodProxy methodProxy) throws Throwable {
		System.out.println(" CGLIB - 方法调用之前");
//		使用目标对象进行方法调用
		Object result = methodProxy.invoke(target,arg2);
		
		System.out.println(" CGLIB - 方法凋用之后");
		
		return result;
	}

}

  注意: 这边是 new 对象时,调用有参构造函数 将对象 传入,其实跟上面 那个 动态代理一样

		KgcInstall pr = new KgcInstall();
		CglibProxy cp = new CglibProxy(pr);
//		将真实对象传入动态代理 ,并生成相应的代理对象
		KgcInstall proxyPr = (KgcInstall)cp.getProxy();
		
		proxyPr.run();

 

 

》 AOP 的引入

现状(AOP 的演变过程):

  1. 有一个支付接口,有很多具体的实现类
  2. 现在我想统计每一种支付方式都需要花费多久

解决方案 :

1、每一个类的方法里都加入两个部分:

    1.   加入开始时间统计
    2.   加入结束时间统计
    3.   结束时间减去开始时间

 

2、提取工具类

         将1.2 和 1.3 进行合并

	public static void actionTime(long beginTime){
		long endTime = System.currentTimeMillis();
		
		System.out.println("执行使用了="+(endTime-beginTime));
		
	}

 

3、问题: 如果有1000 个类需要修改

         3.1 修改的太多,工作量太大

         3.2 还原的时候很容易出现遗忘

     解决方案 :

          引入动态代理

          引入CGLIB

思想: 不关心具体的事物,关注的是任意对象里的某一个点

 

4、问题 : 无论是动态代理还是CGLIB,对象里的方法都是一个完整的整体,不可分割

      引入 AOP

AOP

 概念: 是一种 编程范式(思想),用来帮助我们完善面向对象编程

             面向 切面编程·

主要功能

     日志记录,性能统计,安全控制,事务处理,异常处理等等。

主要意图

        将日志记录,性能统计,安全控制,事务处理,异常处理等代码从业务逻辑代码中划分出来,通过对这些行为的分     离,我们希望可以将它们独立到非指导业务逻辑的方法中,进而改变这些行为的时候不影响业务逻辑的代码。

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值