AOP面向切面编程弥补了面向对象编程
连接点(Joinpoint): 在何处加入逻辑功能,对于Spring AOP,Jointpoint指的就是Method引入(Introduction): 声明额外的方法或者某个类型的字段。 Spring允许引入新的接口(以及一个对应的实现)到任何被代理的对象
通知的类型:跟AspectJ一样,Spring提供所有类型的通知,我们推荐你使用尽量简单的通知类型来实现需要的功能。 例如,如果你只是需要用一个方法的返回值来更新缓存,虽然使用环绕通知也能完成同样的事情, 但是你最好使用After returning通知而不是环绕通知。 用最合适的通知类型可以使得编程模型变得简单,并且能够避免很多潜在的错误。 比如,你不需要调用 JoinPoint(用于Around Advice)的 proceed() 方法,就不会有调用的问题。
看下面的一个例子:
业务类
public class PersonServiceBean { public String save(String name){ System.out.println("save()方法"); return "test"; } public void update(String name,int id) { System.out.println("update()方法"); } }切面类:
@Aspect //定义一个切面 如果用xml方式则这里的所有注解都不需要 public class MyInteceptor { @Pointcut("execution (* com.test.service.impl.PersonServiceBean.*(..))") private void anyMethod(){}//定义一个切入点 @Before("anyMethod() && args(name)") //满足切入点的条件且参数只有一个并为String name public void before(String name){ System.out.println("前置通知:"+name); } @AfterReturning(pointcut="anyMethod()",returning="result")//获取返回的值 public void afterReturn(String result){ System.out.println("后置通知:"+result); } @After("anyMethod()") public void after(){ System.out.println("最终通知"); } @Around("anyMethod()") //环绕通知 public Object doBasic(ProceedingJoinPoint p) throws Throwable{ System.out.println("进入方法");//可以写一些逻辑 Object result=p.proceed(); System.out.println("退出方法"); return result; } }beans.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <context:annotation-config /> <!-- Activates various annotations to be detected in bean classes --> <aop:aspectj-autoproxy/> <!--Enables the use of the @AspectJ style of Spring AOP --> <bean id="personService" class="com.test.service.impl.PersonServiceBean"/> <bean id="myInteceptor" class="com.test.service.impl.MyInteceptor"/><!-- 定义 的切面也必须交给spring管理 --> </beans>
进入方法
前置通知:abc
save()方法
后置通知:test
退出方法
最终通知
如果是xml配置,则xml如下配置:
<context:annotation-config /> <!-- Activates various annotations to be detected in bean classes --> <aop:aspectj-autoproxy/> <!--Enables the use of the @AspectJ style of Spring AOP --> <bean id="personService" class="com.test.service.impl.PersonServiceBean"/> <bean id="myInteceptor" class="com.test.service.impl.MyInteceptor"/><!-- 定义 的拦截器也必须交给spring管理 --> <aop:config> <aop:aspect id="asp" ref="myInteceptor"> <aop:pointcut id="mycut" expression="execution (* com.test.service.impl.PersonServiceBean.*(..))"/> <aop:before method="before" pointcut-ref="mycut"/> </aop:aspect> </aop:config>