首页 > 代码库 > 使用spring方式来实现aop编程
使用spring方式来实现aop编程
1:什么是aop?
Aspect Oriented Programming 面向切面编程
在软件业,AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。AOP是OOP的延续,是软件开发中的一个热点,也是Spring框架中的一个重要内容,是函数式编程的一种衍生范型。利用AOP可以对业务逻辑的各个部分进行隔离,从而使得业务逻辑各部分之间的耦合度降低,提高程序的可重用性,同时提高了开发的效率。
面向对象编程是从【静态角度】考虑程序的结构,而面向切面编程是从【动态角度】考虑程序运行过程。
AOP底层,就是采用【动态代理】模式实现的。采用了两种代理:JDK动态代理和CGLIB动态代理。
2:
基本术语(一些名词):
(1)切面(Aspect)
切面泛指[*交叉业务逻辑*]。事务处理和日志处理可以理解为切面。常用的切面有通知(Advice)与顾问(Advisor)。实际就是对主业务逻辑的一种增强。
(2)织入(Weaving)
织入是指将切面代码插入到目标对象的过程。代理的invoke方法完成的工作,可以称为织入。
(3) 连接点(JoinPoint)
连接点是指可以被切面织入的方法。通常业务接口的方法均为连接点
(4)切入点(PointCut)
切入点指切面具体织入的方法
注意:被标记为final的方法是不能作为连接点与切入点的。因为最终的是不能被修改的,不能被增强的。
(5)目标对象(Target)
目标对象指将要被增强的对象。即包含主业务逻辑的类的对象。
(6)通知(Advice)
通知是切面的一种实现,可以完成简单的织入功能。通知定义了增强代码切入到目标代码的时间点,是目标方法执行之前执行,还是执行之后执行等。切入点定义切入的位置,通知定义切入的时间。
(7)顾问(Advisor)
顾问是切面的另一种实现,能够将通知以更为复杂的方式织入到目标对象中,是将通知包装为更复杂切面的装配器。
3:配置前置丶后置丶环绕丶异常通知增强
定义接口:
package methodBefore; public interface IsomeService { public void doTran(); public void doLog(); }
定义实现类:
package methodBefore; public class SomeServiceimpl implements IsomeService { @Override public void doTran() { // TODO Auto-generated method stub System.out.println("事务开始"); } @Override public void doLog() { // TODO Auto-generated method stub System.out.println("日志开始"); } }
定义代理类:
package methodBefore; import java.lang.reflect.Method; import org.aopalliance.intercept.MethodInvocation; import org.springframework.aop.MethodBeforeAdvice; //MethodBeforeAdvice 前置接口 //AfterReturningAdvice 后置接口 //MethodInterceptor环绕接口 public class MethodBeforeAdviceimpl implements MethodBeforeAdvice //AfterReturningAdvice MethodInterceptor { //MethodBeforeAdvice 接口中重写的方法 @Override public void before(Method arg0, Object[] arg1, Object arg2) throws Throwable { System.out.println("==before"); //System.out.println("==after"); } /*@Override * AfterReturningAdvice 接口中重写的方法 public void afterReturning(Object arg0, Method arg1, Object[] arg2, Object arg3) throws Throwable { System.out.println("===after====="); }*/ /*@Override * MethodInterceptor接口中重写的方法 public Object invoke(MethodInvocation arg0) throws Throwable { System.out.println("after"); arg0.proceed(); System.out.println("before"); return null; }*/ }
配置文件:
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"> <bean id="impl" class="MyThrowsException.SomeServiceimpl"></bean> <bean id="before" class="MyThrowsException.MethodBeforeAdviceimpl"></bean> <bean id="beanfactory" class="org.springframework.aop.framework.ProxyFactoryBean"> <property name="target" ref="impl"></property> <property name="interceptorNames" value="before"></property> </bean> </beans>
但是使用以上方式代码的灵活度不高:原因是无法指定在具体哪个业务方法之前(或之后)配置增强代码
在配置文件中注入这段代码:配置advisor来包装advice 来配置各种增强类型
<!-- 03.配置顾问 advisor 包装 advice--> <bean id="beforeAdvisor" class="org.springframework.aop.support.RegexpMethodPointcutAdvisor"> <property name="advice" ref="beforeAdvice"></property> <property name="pattern" value=".*do.*"></property> </bean>
4:当然 spring集成了另一种方式来实现aop编程:aspectj
切面类:
package cn.happy.aop; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; //普通类 切面类 @Aspect public class MyAspect { @Before(value = "execution(* *..service.*.*(..))") public void MyBeforeAdvice(){ System.out.println("====before"); } }
配置文件:如此简单
<aop:config> <aop:pointcut expression="execution(* *..SomeServiceImpl.doLog(..))" id="beforePointcut"/> <aop:aspect ref="myAspect"> <aop:before method="myBefore(org.aspectj.lang.JoinPoint)" pointcut-ref="beforePointcut"/> </aop:aspect> </aop:config>
使用spring方式来实现aop编程