Spring学习笔记——使用AOP的场景

程序员负责什么?

  寻找可重复代码,拉出来制作成通知;

  在配置文件中,声明切入点和通知间的关系。

术语生涩难懂,“翻译”过来就是在繁冗的业务代码中可能会存在大量的重复型业务代码,我们可以将这些代码抽取出来,制作成一个类,并通过CGlib动态代理或Proxy代理方式实现功能的增强。

运行阶段Spring负责什么?

时刻监控切入点方法的运行。一旦检测到切入点方法被执行,使用代理技术,动态创建目标的代理对象,根据通知类型,在对应位置加入增强代码,完善功能,最终形成一个完整的代码业务逻辑。

 

几个术语名词解释:

连接点:业务逻辑接口中的接口们就是连接点,他们作为事务的核心被Spring拦截,再被识别判断是否要被增强。

切入点:被拦截并被增强的业务就是切入点,说白了就是事务接口中被增强了的接口方法。

通知:被整合出来的加强方法实现类就是通知,根据执行时间不同,分为前置通知,后置通知、异常通知、环绕通知和最终通知。

这里有一个简单的通知类型判断方法,在进行代码功能加强时,会调用method.invoke(object, args)方法,在这之前的是前置通知,这之后catch块前的是后置通知,catch块中的是异常通知,finally块中的为最终通知。

 

/**
 * 嘴业务层的四个业务
 * @author Administrator
 *
 */
public interface IMouth {
	void drink();
	
	void chew();
	
	void eat();
	
	void rap();
}
/**
 * 不管是吃喝嚼还是rap都需要先张开嘴,这是必须的,所以张嘴就可以作为一个通知整合进通知类
 * @author Administrator
 *
 */
public class MouthImpl implements IMouth {
	
	public void openMouth() {
		System.out.println("张开嘴");
	}
	
	@Override
	public void drink() {
//		openMouth();
		System.out.println("喝饮料");
	}

	@Override
	public void chew() {
//		openMouth();
		System.out.println("嚼东西");
	}

	@Override
	public void eat() {
//		openMouth();
		System.out.println("吃汉堡");
	}

	@Override
	public void rap() {
//		openMouth();
		System.out.println("你看这个面他又长又宽,就像这个碗他又大又圆");
	}

}
/*
 * 对嘴业务的增强代码,这就是一个增强类,也叫通知类
 */
public class MouthManager {
	public static void openMouth() {
		System.out.println("张开嘴");
	}
	
	public static void closeMouth() {
		System.out.println("合上嘴");
	}
	
	public static void cantCloseMouth() {
		System.out.println("脱臼了!快去医院!");
	}
	
	public static void finallyClose() {
		System.out.println("正常的合上嘴巴");
	}
}
/**
 * 通过CGLib代理完善业务逻辑
 * @author Administrator
 *
 */
public class MouthProxy {
	public static IMouth getProxy() {
		MouthImpl mouth = new MouthImpl();
		
		MouthImpl mouthProxy = (MouthImpl) Enhancer.create(MouthImpl.class, new MethodInterceptor() {
			
			@Override
			public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
				try {
					Object rtValue = null;
					
					MouthManager.openMouth(); //前置通知
					
					rtValue = method.invoke(mouth, args);
					
					MouthManager.closeMouth(); //后置通知
					return rtValue;
				} catch (Exception e){
					MouthManager.cantCloseMouth(); // 异常通知
					throw new RuntimeException(e);
				} finally {
					MouthManager.finallyClose();  // 最终通知
				}
				
			}
		});
		
		return mouthProxy;
	}
}
public class Demo {
	public static void main(String[] args) {
		IMouth mouth = MouthProxy.getProxy();
		
		mouth.eat();
		System.out.println();
		mouth.chew();
		System.out.println();
		mouth.drink();
		System.out.println();
		mouth.rap();
	}
}

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值