[Java学习笔记]Spring(二)AOP思想及其实现

何为AOP ?

AOP(Aspect Oriented Programming)是Spring提供的关键特性之一。AOP即面向切面编程,是OOP编程的有效补充。

使用AOP技术,可以将一些系统性相关的编程工作,独立提取出来,独立实现,然后通过切面切入进系统。从而避免了在业务逻辑的代码中混入很多的系统相关的逻辑——比如权限管理,事物管理,日志记录等等。这些系统性的编程工作都可以独立编码实现,然后通过AOP技术切入进系统即可。从而达到了 将不同的关注点分离出来,可以单独维护大大降低了代码重复率以及不同层之间的耦合。

Struts2内部的AOP思想在这里插入图片描述

举个例子,在Struts2中Params拦截器做的事情就是把前端请求过来的参数通过OGNL表达式对值栈里面的对象赋值,而这项操作正是对于每个Action执行前都要做的,因此选择了用拦截器将这部分代码分隔开来由Struts2自行完成不需要程序员干预。

Spring中对于事务的AOP处理

在这里插入图片描述
再如对于事务,我们在Service层要调用Dao层方法做增删查改需要开启事务/提交或回滚事务,这部分代码散落在每处的Service方法中,不宜与我们修改维护,不妨选择将他们独立封装起来,与其他业务分隔开。

AOP名词解释

在这里插入图片描述

Spring中实现AOP的方法(代理模式)

动态代理

被代理对象必须要实现父接口,才能产生代理对象.这种方式下我们生成的代理对象和被代理对象是同一个父接口的,如果被代理对象没有接口将不能使用动态代理技术

public class ProxyTest {
	@Test
	public void test() {
		System.out.println("——————————");
		PersonService ps = new PersonServiceImp();
		User login2 = ps.login();
		ps.regist();
		System.out.println("——————————");
		
		/*
		 * loader: 类加载器
		 * interfaces: 被代理对象所有的父接口
		 * InvocationHandler: 代理后的增强方法的封装形式
		 */
		PersonService psProxy = (PersonService) Proxy.newProxyInstance(PersonServiceImp.class.getClassLoader(), PersonServiceImp.class.getInterfaces(), 
				new InvocationHandler() {
			@Override
			/* 
			 * proxy:增强后的对象-代理对象
			 * method:要通过代理对象增强的方法
			 * args:执行原方法的参数
			 */
			public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
				// 前置通知
				System.out.println("开启事务OpenTransfaction");
				//连接点
				Object res = method.invoke(ps, args);
				// 后置通知
				System.out.println("提交事务Commit");
				return res;
			}
		});
		User login = psProxy.login();
		psProxy.regist();
	}
}

cglib代理

第三方代理技术,cglib代理.当被代理对象没有父接口的时候则需要选择这种代理方式.代理的原理是对目标对象进行继承代理. 如果目标对象被final修饰.那么该类无法被cglib代理.

public class ProxyTest2 {
	public static void main(String[] args) {
		Enhancer eh = new Enhancer();
		
		// 1.设置父类
		eh.setSuperclass(UserServiceImpl.class);
		// 2.增强代码
		/**
		** arg0:代理对象
		** arg1:原方法
		** arg2:方法参数列表
		** arg3:代理后的子类方法对象
		**/
		eh.setCallback((MethodInterceptor) (arg0, arg1, arg2, arg3) -> {
			// 前通知
			System.out.println("开启事务");
			// 原来方法调用
			Object re = arg3.invokeSuper(arg0, arg2); 
			// 后通知
			System.out.println("提交事务");
			return re;
		});
		// 3.创建对象
		UserServiceImpl us = (UserServiceImpl) eh.create();
		us.register();
		
		System.out.println(us instanceof UserServiceImpl);
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值