Spring 框架之Spring AOP的认识(一)

什么是AOP?

我们先来思考一个问题:“怎么把大象放到冰箱里面”?其实,很多人已经知道答案,就三步:1.打开冰箱们,2.把大象放进冰箱,3.关上冰箱门。那同理,我们也是同样的操作水果跟蔬菜;
大象:1.打开冰箱们,2.把大象放进冰箱,3.关上冰箱门
水果:1.打开冰箱们,2.把水果放进冰箱,3.关上冰箱门
蔬菜:1.打开冰箱们,2.把蔬菜放进冰箱,3.关上冰箱门
可以看到,我们的主要业务是把目标对象(大象,水果,蔬菜)放进冰箱,而次要业务是“打开冰箱们”和“关上冰箱门”,而且这些业务都是一样的。那我们这时候就想想能不能把相同的部分抽离出来,当他们执行操作时,我们动态的监控,如果你想要把对象放到冰箱里面,那他就会在执行的过程中调用这个公共的部分。事实上,AOP就是在做这样子的事情

AOP(官方解释)

AOP:面向切面编程,相当于平面的X轴,OOP面向对象编程,相当于Y轴。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,继承或者实现,相当先有父级再有子级,从上到下继承和实现,也就是说,OOP是从上到下的关系,而不是从左到右的关系,简单来说,就像一个执行的过程,比如上面的例子“把大象放入冰箱”,实际上是有一个从左到右的过程,又或者例如日志功能,数据库事务以及异常通知等等一些公共的模块代码,它跟对象的核心功能毫无关系。如果每个OOP设计,都写这些公共的代码,那它导致了大量代码的重复,而不利于各个模块的重用。

自我理解

我的理解就是:AOP就是把一些不是目标对象的次要业务公共部分逻辑,把它封装到一个可以重用的模块;将那些与主要业务无关,却为业务模块所共同调用的逻辑或责任封装起来供给对象集体调用,达到可以让我们动态的控制程序的执行流程及执行结果,这样就减少了代码的重复性,降低模块间的耦合度,你可以想象如果每个对象都写这个打开冰箱门,关闭冰箱们这些次要逻辑代码,那是不是很冗余。

在这里插入图片描述


AOP是实现原理之动态代理

动态代理多种:JDK、CGLIB、javassist、ASM。而Spring中我们只了解其中的JDK和CGLIB两种动态代理
JDK:JDK的动态代理机制只能代理实现了接口(InvocationHandler)的类,而不能实现接口的类就不能实现JDK的动态代理。
CGLIB:针对类来实现代理的,他的原理是对指定的目标类生成一个子类,并覆盖其中方法实现增强,采用的是继承。

下面通过小例子来简单的认识一下AOP的JDK动态代理
1.创建动态代理对象,关联目标对象
2.实现代理的自我逻辑方法
在这里插入图片描述
目标对象主要业务:吃饭(目标对象)
次要业务:洗手、处理剩菜、清洗餐具、处理急事。(代理的逻辑方法)

public interface DinnerService{

	public void hava();
}

@Service
public class LanuchServiceImpl implements DinnerService{

	public void hava(){
		System.out.println("吃饭罗");
	}
}

@Service
public class DinnerProxy implements InvocationHandler{
	//目标对象
	pravite Object target = null;	
	//拦截器
	pravate DinnerInterceptor dinnerInterceptor = null
	//建立代理对象和目标对象的关联关系
	public static Object bind(Object target,DinnerInterceptor dinnerInterceptor){
		DinnerProxy dinnerProxy = new DinnerProxy();
		dinnerProxy.target = target;
		dinnerProxy.dinnerInterceptor =dinnerInterceptor ;
		Object proxy = Proxy.newProxyInstance(
			//类加载器
			target.getClass().getClassLoader(),
			//将代理对象下发到什么接口下
			target.getClass().getInterfaces(),
			//使用dinnerProxy的invoke方法作为代理逻辑
			dinnerProxy); 
		rerurn proxy ;
	}
/**
*代理对象的逻辑
*@param proxy---代理对象
*@param method---方法
*@param args ----参数
*/
	public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
		/****没有拦截器的实现方式**/
		/*System.out.println("洗手");
		Object obj = method.invoke(target,args);
		System.out.println("收拾剩饭");
		System.out.println("收拾残局");*/
		
		/****增加拦截器实现方式**/
		this.dinnerInterceptor.before();
		Object obj = null;
		try{
			obj = methdo.invoke(target,args);
		}catch(){
			flag = true;
		}finally{
			this.dinnerInterceptor.after();
		}
		if(flag){
			this.dinnerInterceptor.afterThrowing();
		}else{
			this.dinnerInterceptor.afterReturning();
		}
	}
}

public class AopMain{
	public void static main(String[] args){
		//目标对象
		DinnerService target = new LanuchServiceImpl();
		//拦截器
		DinnerInterceptorImpl interceptoy = new DinnerInterceptorImpl ();
		//这个是获取到代理对象和目标对象的关联关系,关联起来后,代理对象就可以操作目标对象的方法了。有拦截器就追加拦截器,增强对目标对象的控制,没有也是可以的。
		DinnerService proxy = (DinnerService)DinnerProxy.bind(target,interceptoy);
		proxy.hava();
	}
}


//拦截器的方法
public Interface DinnerInterceptor{
	public void before(); 
	public void after();
	public void afterReturning();  
	public void afterThrowing(); 

}

//拦截器的方法
public class DinnerInterceptorImpl implements DinnerInterceptor{
	public void before(){System.out.println("洗手")}; 
	public void after(){System.out.println("清洗餐具")};
	public void afterReturning(){System.out.println("收拾剩饭")};  
	public void afterThrowing(){System.out.println("处理急事去了")}; 

}

对于普通开发者来说,我们只需要知道执行的流程,还有暴露的接口,而里边的具体实现动态代理的细节,这个就是设计者考虑的逻辑,因为这些逻辑可能很抽象。简单来说,就是我们需要知道操作的流程图是怎么样的,还有需要调用的AOP接口。

现在的你是否已经对AOP有初步的印象了呢?当然了,这里只是一个前菜,只是作为一个小的了解,下来我们会正式的学习AOP的一些重点的概念并进行实践。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值