标签:
AOP(Aspect Oriented Programming),是面向切面编程的技术。AOP基于IoC基础,是对OOP的有益补充。spring中AOP的配置方式有2种方式:xml配置和AspectJ注解方式。
一、xml配置的方式:
1、service接口和服务类:切入点类,是要被切入的业务类,如DemoServiceImpl ,切入点方法是切入点类中,被切入的方法。
二、注解方式:
1、service接口和服务类:(同上)
2、切面类开发:
packagecn.edu.nuc.SpringTest.interceptor;
importjava.lang.reflect.Method;
importorg.aspectj.lang.JoinPoint;
importorg.aspectj.lang.ProceedingJoinPoint;
importorg.aspectj.lang.Signature;
importorg.aspectj.lang.annotation.After;
importorg.aspectj.lang.annotation.AfterReturning;
importorg.aspectj.lang.annotation.AfterThrowing;
importorg.aspectj.lang.annotation.Around;
importorg.aspectj.lang.annotation.Aspect;
importorg.aspectj.lang.annotation.Before;
importorg.aspectj.lang.annotation.Pointcut;
importorg.aspectj.lang.reflect.MethodSignature;
importorg.springframework.stereotype.Component;
importcn.edu.nuc.SpringTest.common.anno.Permission;
@Component
@Aspect
public classMyInterceptor {
//切入点要拦截的类,声明一个切入点,切入点的名称其实是一个方法
@Pointcut("execution(* cn.edu.nuc.SpringTest.service..*.*(..))")
privatevoid anyMethod(){}
//声明一个切入点,切入点的名称其实是一个方法
@Pointcut(value="execution(* cn.edu.nuc.SpringTest.service..*.*(java.lang.String)) && args(name)")
privatevoid nameParameMethod(String name){}
@Around("anyMethod()")
publicObject doBasicProfiling(ProceedingJoinPoint pjp) throws Throwable{
System.out.println("环绕通知进入方法");
Objectobject=pjp.proceed();
System.out.println("环绕通知退出方法");
returnobject;
}
//后置通知(不需要获取返回值)
// @AfterReturning("anyMethod()")
@AfterReturning (pointcut="anyMethod()",returning="result")
publicvoid doAfterReturning(JoinPoint jp,String result){
Object[]args = jp.getArgs();
Objecttarget = jp.getTarget();
Signaturesignature = jp.getSignature();
MethodSignaturemethodSignature = (MethodSignature)signature;
Method targetMethod =methodSignature.getMethod();
boolean b =targetMethod.isAnnotationPresent(Permission.class);
if (b) {
Permission perm =targetMethod.getAnnotation(Permission.class);
String value =perm.value();
System.out.println("@@@@@@@@@@@@@@@@@"+value);
}
System.out.println("======="+signature.getName()+";"+jp.getThis().toString());
System.out.println("后置通知:"+args[0]+target.toString()+";返回值:"+result);
}
//@AfterThrowing("anyMethod()")
@AfterThrowing(pointcut="anyMethod()" ,throwing="e")
publicvoid doAfterThrowing(Exception e){
System.out.println("例外通知:");
}
//最终通知
@After(value="anyMethod()")
publicvoid doAfter(JoinPoint jp){
Object[]args = jp.getArgs();
System.out.println("最终通知:================="+args[0]);
}
//前置通知(不需要获取输入参数)
@Before("nameParameMethod(name)")//第一个参数为切入点的名称,第二个是测试获取输入参数,此处为string类型的,参数名称与方法中的名称相同,如果不获取输入参数,可以不要
//@Before("anyMethod()")//第一个参数为切入点的名称
public void doAccessCheck(JoinPoint jp,String name){
System.out.println("前置通知:"+name);
}
}
3、配置文件:
<?xmlversion="1.0" encoding="UTF-8"?>
<beansxmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-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">
<context:component-scanbase-package="cn.edu.nuc.SpringTest"/>
<!-- 注解方式的aop -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
</beans>
注:需要使用<aop:aspectj-autoproxy proxy-target-class="true"/> 开启注解aop功能,如果使用了ioc,那么一定要加上proxy-target-class="true"
4、测试类:(同上)
注意点:
1)后置返回通知方法中,如果要获得切入点方法返回值,需要在AfterReturning 注解中加上returning,且需要保持与后置返回通知方法的参数名一致;
2)后置异常通知方法中,如果要获得切入点方法异常,需要在AfterThrowing注解中加上throwing,且保持与方法中异常的参数名一致;
3)同样,在通知方法中,JoinPoint要 作为第一个参数,例如:public void doAccessCheck(JoinPoint jp,String name)中;
4)切面类的通知方法中获取切入点方法的参数:
1.在通知方法中,可以通过JoinPoint 获取切入点方法的所有参数;
2.在切面类的注解上配置andargs(name),name要和切入点方法参数名、通知方法的参数名一致,这样就可以在通知方法中的参数获取切入点方法的参数了;
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>cn.edu.nuc</groupId> <artifactId>SpringTest</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>SpringTest</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <org.springframework.version>3.1.1.RELEASE</org.springframework.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${org.springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${org.springframework.version}</version> <type>jar</type> <scope>test</scope> </dependency> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.2</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.2.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.2.3</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.2.3</version> </dependency> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2</version> </dependency> </dependencies> </project>
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/liuxiao723846/article/details/47278157