如何理解spring AOP 框架,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。
spring AOP?面向切面编程,区别于面向对象编程OOP
AspectJ: 是Java社区里面最完整最流行的AOP框架,下面就用aspectJ来上例子
步骤如下:
引入jar包(spring的必要jar包 以及aspectj的jar包)
业务方法HelloworldService (类上加上注解@Component,放入到spring ioc容器中)
切面LogingAop (类上加上注解@Component使其加入到ioc容器中,还需要注解@Aspect,使其成为一个切面)
spring配置文件applicationContext.xml (扫描包,以及aop生成代理类的配置<aop:aspectj-autoproxy/>)
测试
结构如下:
HelloworldService代码实现:
package com.aop.demo;import org.springframework.stereotype.Component;
@Componentpublic class HelloworldService { public int add(int i, int j){ return i+j;
}
}
LogingAop代码实现:
package com.aop.demo;import java.util.Arrays;import java.util.List;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.stereotype.Component;
@Component
@Aspectpublic class LogingAop {
@Pointcut("execution(public int com.aop.demo.HelloworldService.add (int,int))") public void pointcut(){};
@Before(value="pointcut()") public void beforeMethod(JoinPoint jointPoint){
String methodName = jointPoint.getSignature().getName();
List args = Arrays.asList(jointPoint.getArgs());
System.out.println("Method("+methodName+") args("+args+") Start");
}
}
applicationContext.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"><context:component-scan base-package="com.aop.demo"></context:component-scan><aop:aspectj-autoproxy/></beans>
测试代码如下
package com.aop.demo;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class AopTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
HelloworldService helloworldService = (HelloworldService) ctx.getBean("helloworldService");
int result = helloworldService.add(1, 2);
System.out.println("Result is "+result);
}
}
测试结果如下:
Method(add) args([1, 2]) Start
Result is 3
AOP中的概念介绍:
切面:跨越应用程序多个模块的功能,比如打日志,比如参数验证,类似这种被模块化的特殊对象
通知: 上面切面中的方法
切入点:相当于查询条件,在哪些业务方法中需要加入通知,spring自动生成新的代理对象
AspectJ支持5中类型的通知注解:
@Before: 前置通知,在方法执行之前执行
@After: 后置通知,在方法执行之后执行 (不管是否有异常,都会执行)
@AfterRuning: 返回通知,在方法返回结果之后执行 (只在没有异常时候才执行)
@AfterThrowing: 异常通知,在方法抛出异常之后
@Around: 环绕通知,围绕着方法执行
AspectJ的5中注解的代码示例
package com.aop.demo;import java.util.Arrays;import java.util.List;import org.aspectj.lang.JoinPoint;import org.aspectj.lang.ProceedingJoinPoint;import org.aspectj.lang.annotation.After;import org.aspectj.lang.annotation.AfterReturning;import org.aspectj.lang.annotation.AfterThrowing;import org.aspectj.lang.annotation.Around;import org.aspectj.lang.annotation.Aspect;import org.aspectj.lang.annotation.Before;import org.aspectj.lang.annotation.Pointcut;import org.springframework.stereotype.Component;
@Component
@Aspectpublic class LogingAop {
@Pointcut("execution(public int com.aop.demo.HelloworldService.add (int,int))") public void pointcut(){};
@Before(value="pointcut()") public void beforeMethod(JoinPoint jointPoint){
String methodName = jointPoint.getSignature().getName();
List args = Arrays.asList(jointPoint.getArgs());
System.out.println("Method("+methodName+") args("+args+") Start");
}
@After(value="pointcut()") public void afterMethod(JoinPoint jointPoint){
String methodName = jointPoint.getSignature().getName();
List args = Arrays.asList(jointPoint.getArgs());
System.out.println("Method("+methodName+") args("+args+") After");
}
@AfterReturning(value="pointcut()",returning="result") public void afterReturingMethod(JoinPoint jointPoint,Object result){
String methodName = jointPoint.getSignature().getName();
List args = Arrays.asList(jointPoint.getArgs());
System.out.println("Method("+methodName+") args("+args+") After Runing + Result:"+result);
}
@AfterThrowing(value="pointcut()",throwing="e") public void afterThrowingMethod(JoinPoint jointPoint,Exception e){
String methodName = jointPoint.getSignature().getName();
List args = Arrays.asList(jointPoint.getArgs());
System.out.println("Method("+methodName+") args("+args+") After Throw Exception:" +e);
}
@Around(value="pointcut()") public Object aroundMethod(ProceedingJoinPoint jointPoint){
Object result = null;
String methodName = jointPoint.getSignature().getName(); try {
System.out.println(methodName+"前置通知.....");
result = jointPoint.proceed();
System.out.println("后置通知.....");
} catch (Throwable e) {
System.out.println("异常通知....."); throw new RuntimeException();
}
System.out.println("返回通知....."); return result;
}
}
注意:@Around环绕通知,必须携带对象ProceedingJoinPoint参数
环绕通知类似于动态代理的全部过程,可以决定是否执行目标方法
切面的优先级
可以在切面上注解@Order,其中值越小,切面的优先级越高
步骤如下:
将上面的三个类移到其他包里面,去掉类以及方法中的所有注解
定义新的配置文件applicationContext-xml.xml
结构如下:
applicationContext-xml.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:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
<!-- 配置业务bean -->
<bean id="helloworldService" class="com.aop.demo.xml.HelloworldService"></bean>
<!-- 配置切面 -->
<bean id="logingAop" class="com.aop.demo.xml.LogingAop"></bean>
<!-- 配置AOP -->
<aop:config>
<aop:pointcut expression="execution(public int com.aop.demo.xml.HelloworldService.add (int,int))" id="pointCut" />
<aop:aspect ref="logingAop">
<aop:before method="beforeMethod" pointcut-ref="pointCut" />
</aop:aspect>
</aop:config></beans>
看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注亿速云行业资讯频道,感谢您对亿速云的支持。
亿速云「云服务器」,即开即用、新一代英特尔至强铂金CPU、三副本存储NVMe SSD云盘,价格低至29元/月。点击查看>>
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。