Spring/AOP框架, 以及使用注解
1, 使用代理增加日志, 也是基于最原始的办法
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; public class LoggingProxy {
/*
* 代理类, 基于接口
*/
//要被代理的对象, 目标对象
private Icalculator target;
//生成一个构造方法
public LoggingProxy(Icalculator target) {
super();
this.target = target;
}
//应用通知. 并产生对象
public Icalculator getProxy() {
Icalculator ica = null;
//应用通知
//获得类加载器: ClassLoader, 类加载器在getClass()方法里面
ClassLoader cl = target.getClass().getClassLoader(); //获得class中所有方法的数组, 数组的内容一定要是接口.class
Class[] cla= new Class[] {Icalculator.class};
//Class[] al = new Class[] {IJiSuanQi.class};//接口 //获得
InvocationHandler ih = new InvocationHandler() {
@Override
//调用invoke的时候就是实现一个切面编程
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//在这之前可以增加数据验证
Object obj = null;
System.out.println(method.getName()+" 开始调用");
try {
obj = method.invoke(target, args);
}
catch(Exception e) {
System.out.println("异常通知: "+method.getName());
}
System.out.println(method.getName()+" 结束调用");
return obj;
}
};
//产生代理对象, 引用了反射的jar包
ica = (Icalculator)Proxy.newProxyInstance(cl, cla, ih);
return ica;
}
}
2, 使用AOP框架
配置文件
<!-- 前面定义的类class -->
<bean id="cal" class="com.hanqi.Calculator">
</bean> <!-- 切面类 -->
<bean id="la" class="com.hanqi.LoggingAspect">
</bean> <!-- 定义AOP -->
<aop:config>
<!-- 配置切点表达式, 被切入的方法 -->
<!-- expression写对象必须是个接口被切入方法的名字, 如果要写所有的方法就用*号表示 -->
<aop:pointcut expression="execution(* com.hanqi.Icalculator.*(int,int))" id="loggingpointcut"/> <!-- 配置切面和通知 -->
<aop:aspect ref="la">
<!-- 方法前通知 -->
<aop:before method="beforeMethod" pointcut-ref="loggingpointcut"/>
<aop:after method="afterMethod" pointcut="execution(* com.hanqi.Icalculator.cheng(int,int))"/>
<aop:after-throwing method="exceptionMethod" pointcut-ref="loggingpointcut" throwing="ex"/>
<aop:after-returning method="returnMethod" pointcut-ref="loggingpointcut" returning="obj"/>
</aop:aspect> </aop:config>
定义切面类
import java.util.Arrays; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; public class LoggingAspect {
//切面类, 前置通知
public void beforeMethod(JoinPoint jp) {
//获取方法名
String str = jp.getSignature().getName();
//返回一个参数列表
Object[] obj = jp.getArgs();
System.out.println("方法名 = "+str);
System.out.println(Arrays.asList(obj));
System.out.println("这里是方法前的通知");
}
public void afterMethod(JoinPoint jp) {
System.out.println("这里是方法后的通知");
}
//异常通知
public void exceptionMethod(JoinPoint jp,Exception ex) {
System.out.println("异常信息"+ex);
} //返回通知
public void returnMethod(JoinPoint jp,Object obj) {
System.out.println("返回通知的结果: "+obj);
}
}
3, 使用注解的方式(标红的部分是注解), 一定记得写上返回值和, expression表达式
import org.springframework.stereotype.Component;
@Component("cal")
public class Calculator implements Icalculator {
......
方法体
......
}
import java.util.Arrays; import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component; @Aspect
@Component
public class LoggingAspect {
//切面类, 前置通知
@Before(value = "execution(* com.hanqi.Calculator.*(..))")
public void beforeMethod(JoinPoint jp) {
//获取方法名
String str = jp.getSignature().getName();
//返回一个参数列表
Object[] obj = jp.getArgs();
System.out.println("方法名 = "+str);
System.out.println(Arrays.asList(obj));
System.out.println("这里是方法前的通知");
}
//后置通知
@After("execution(* com.hanqi.Calculator.*(..))")
public void afterMethod(JoinPoint jp) {
System.out.println("这里是方法后的通知");
}
//异常通知
@AfterThrowing(pointcut="execution(* com.hanqi.Calculator.*(..))", throwing="ex")
public void exceptionMethod(JoinPoint jp,Exception ex) {
System.out.println("异常信息"+ex);
} //返回通知
@AfterReturning(pointcut="execution(* com.hanqi.Calculator.*(..))", returning="obj")
public void returnMethod(JoinPoint jp,Object obj) {
System.out.println("返回通知的结果: "+obj);
}
}
注解的配置文件
<?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/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
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.2.xsd"> <!-- 使用注解的方式 -->
<!-- 扫描器 -->
<context:component-scan base-package="com.hanqi"></context:component-scan>
<!-- 启用AOP注解 -->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
</beans>
Spring/AOP框架, 以及使用注解的更多相关文章
- Spring AOP 框架
引言 要掌握 Spring AOP 框架,需要弄明白 AOP 的概念. AOP 概念 AOP(Aspect Oriented Programming的缩写,翻译为面向方面或面向切面编程),通过预编译方 ...
- SSH(Struts2+Spring+Hibernate)框架搭建流程<注解的方式创建Bean>
此篇讲的是MyEclipse9工具提供的支持搭建自加包有代码也是相同:用户登录与注册的例子,表字段只有name,password. SSH,xml方式搭建文章链接地址:http://www.cnblo ...
- Spring AOP中使用@Aspect注解 面向切面实现日志横切功能详解
引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一 ...
- spring AOP (使用AspectJ的注解方式 的aop实现) (6)
目录 一.在 Spring 中启用 AspectJ 注解支持 二.AspectJ 支持 5 种类型的通知注解: 2.1.使用之前的 计算器接口和实现类 ArithmeticCalculator.jav ...
- Spring AOP框架 AspectJ
1 AspectJ简介 v AspectJ是一个基于Java语言的AOP框架 v Spring2.0以后新增了对AspectJ切点表达式支持 v @AspectJ 是AspectJ1.5新增功能 ...
- Spring AOP(5)-- 注解
applicationContext.xml <?xml version="1.0" encoding="UTF-8"?><beans xml ...
- Spring AOP配置简单记录(注解及xml配置方式)
在了解spring aop中的关键字(如:连接点(JoinPoint).切入点(PointCut).切面(Aspact).织入(Weaving).通知(Advice).目标(Target)等)后进行了 ...
- 【Spring AOP】Spring AOP之如何通过注解的方式实现各种通知类型的AOP操作进阶篇(3)
一.切入点表达式的各种类型 切入点表达式的作用:限制连接点的匹配(满足时对应的aspect方法会被执行) 1)execution:用于匹配方法执行连接点.Spring AOP用户可能最经常使用exec ...
- 循序渐进之Spring AOP(6) - 使用@Aspect注解
前面几节的示例看起来让人沮丧,要记忆如此多的接口.类和继承关系,做各种复杂的配置.好在这些只是一种相对过时的实现方式,现在只需要使用@Aspect注解及表达式就可以轻松的使用POJO来定义切面,设计精 ...
随机推荐
- make_heap()等函数的用法
1.make_heap() make_heap()用于把一个可迭代容器变成一个堆,默认是大顶堆. 它有三个参数.第一个参数是指向开始元素的迭代器,第二个参数是指向最末尾元素的迭代器,第三个参数是les ...
- [转] Maven.pom.xml 配置示例
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://mave ...
- cookie js案例
//存cokie function setcookie(keys,value,time){ document.cookie=keys+"="+decodeURIComponent( ...
- tomcat 启动超级慢
今天在新环境里部署tomcat, 刚开始启动很快,关闭之后再启动,却发现启动日志打印到 00:25:14.144 [localhost-startStop-1] INFO o.s.web.conte ...
- 学学Gearman
通常,多语言多系统之间的集成是个大问题,一般来说,人们多半会采用WebService的方式来处理此类集成问题,但不管采用何种风格的WebService,如RPC风格,或者REST风格,其本身都有一定的 ...
- 利用Red Blob游戏介绍A*算法
转自:http://gad.qq.com/program/translateview/7194337 在游戏中,我们经常想要找到从一个位置到另一个位置的路径.我们不只是想要找到最短距离,同时也要考虑旅 ...
- Vue 封装js
//封装模块化文件 新建的.js文件 var storage = { set(key, value) { localStorage.setItem(key, JSON.stringify(value) ...
- Hadoop恢复namenode数据
情景再现: 在修复hadoop集群某一个datanode无法启动的问题时,搜到有一个答案说要删除hdfs-site.xml中dfs.data.dir属性所配置的目录,再重新单独启动该datanode即 ...
- Hadoop2.0构成之HDFS2.0
HDFS2.0之HA 主备NameNode: 1.主NameNode对外提供服务,备NameNode同步主NameNode元数据,以待切换: 2.主NameNode的信息发生变化后,会将信息写到共享数 ...
- Spark分析之SparkContext启动过程分析
SparkContext作为整个Spark的入口,不管是spark.sparkstreaming.spark sql都需要首先创建一个SparkContext对象,然后基于这个SparkContext ...