理解aop先理解三个概念
切点 通知 切面
pointcut
切点包括两个部分,expression表达式和signature签名,切入点有签名就意味着可以重用.可以把公用的切入点放到一个类中,然后使用类的
全限定类名+切入点签名
通知(advises):决定声明时候通知
以前置通知为例:
@before 前置通知注解
@AfterReturning 后置通知
@After 最终通知
@AfterThrowing 异常通知
@Around 环绕通知
它会在切入点执行之前通知切面中配置@before的方法执行,前置通知只是这个注解,并不包括切面中的方法
切面是一个bean,切面中的方法就是切面的业务逻辑
package cn.aop;
import org.springframework.stereotype.Component;
@Component("person")//向容器注册,注册id为person
public class Person {
public void sayHello(){
System.out.println("Hello");
}
public void sayHello(int age,String str){
System.out.println(age+"---"+str);
}
public String getInfo(String str){
System.out.println(str);
return str;
}
}
package cn.aop;
import org.aspectj.lang.annotation.Pointcut;
public class PointCuts {
//精确到方法,(..)任意多个形参,(*)一个形参类型不限 ,(*.String)第二个形参的类型为String
//第一个* 代表返回值 第二个*紧挨着(..)所以代表方法名
@Pointcut("execution(* cn.aop.Person.*(*))")
public void getInfo(){
}
}
package cn.aop;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;
/**
*
* 切面是bean
* 第一个注解是向容器注册bean
* 第二个是声明这个bean是切面
* @author 格拉.香农
*
*/
@Component
@Aspect
public class MyAspect {
@Before("cn.aop.PointCuts.getInfo()&&args(String)")
public void doBefore(){
System.out.println("前置通知");
}
@AfterReturning(pointcut="cn.aop.PointCuts.getInfo()")
public void doAfterReturning(){
System.out.println("这是后置通知");
}
@After(value="cn.aop.PointCuts.getInfo()")
public void doAfter(){
System.out.println("这是最终通知");
}
}
package cn.aop;
import javax.annotation.Resource;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(value="/beans.xml")
public class SpringTest {
@Resource(name="person")
private Person person;
@Test
public void springTest(){
//person.sayHello();
person.sayHello(12, "Str");
person.getInfo("格拉.香农");
}
}
环境:
因为是jdk1.8所以使用的aspectjweaver.jar的版本 1.8.9
总之符合aspectjweaver.jar符合jdk版本就行,否则使用pointcut时报错
<bean id="myAspect" class="cn.aop.MyAspect"></bean>
<aop:config>
<!--aop:定义切点 -->
<aop:pointcut id="yff" expression="execution(* cn.aop.Person.*(..) )"/>
<!--aop: 定义切面 -->
<aop:aspect id="myAspect" ref="myAspect">
<aop:before pointcut-ref="yff" method="doBefore"/>
<aop:after-returning pointcut-ref="yff" method="doAfter"/>
</aop:aspect>
</aop:config>