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框架, 以及使用注解的更多相关文章

  1. Spring AOP 框架

    引言 要掌握 Spring AOP 框架,需要弄明白 AOP 的概念. AOP 概念 AOP(Aspect Oriented Programming的缩写,翻译为面向方面或面向切面编程),通过预编译方 ...

  2. SSH(Struts2+Spring+Hibernate)框架搭建流程<注解的方式创建Bean>

    此篇讲的是MyEclipse9工具提供的支持搭建自加包有代码也是相同:用户登录与注册的例子,表字段只有name,password. SSH,xml方式搭建文章链接地址:http://www.cnblo ...

  3. Spring AOP中使用@Aspect注解 面向切面实现日志横切功能详解

    引言: AOP为Aspect Oriented Programming的缩写,意为:面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术.AOP是OOP的延续,是软件开发中的一 ...

  4. spring AOP (使用AspectJ的注解方式 的aop实现) (6)

    目录 一.在 Spring 中启用 AspectJ 注解支持 二.AspectJ 支持 5 种类型的通知注解: 2.1.使用之前的 计算器接口和实现类 ArithmeticCalculator.jav ...

  5. Spring AOP框架 AspectJ

    1 AspectJ简介 v  AspectJ是一个基于Java语言的AOP框架 v  Spring2.0以后新增了对AspectJ切点表达式支持 v  @AspectJ 是AspectJ1.5新增功能 ...

  6. Spring AOP(5)-- 注解

    applicationContext.xml <?xml version="1.0" encoding="UTF-8"?><beans xml ...

  7. Spring AOP配置简单记录(注解及xml配置方式)

    在了解spring aop中的关键字(如:连接点(JoinPoint).切入点(PointCut).切面(Aspact).织入(Weaving).通知(Advice).目标(Target)等)后进行了 ...

  8. 【Spring AOP】Spring AOP之如何通过注解的方式实现各种通知类型的AOP操作进阶篇(3)

    一.切入点表达式的各种类型 切入点表达式的作用:限制连接点的匹配(满足时对应的aspect方法会被执行) 1)execution:用于匹配方法执行连接点.Spring AOP用户可能最经常使用exec ...

  9. 循序渐进之Spring AOP(6) - 使用@Aspect注解

    前面几节的示例看起来让人沮丧,要记忆如此多的接口.类和继承关系,做各种复杂的配置.好在这些只是一种相对过时的实现方式,现在只需要使用@Aspect注解及表达式就可以轻松的使用POJO来定义切面,设计精 ...

随机推荐

  1. spring Annotation based configuration

    spring 注解相关 https://docs.spring.io/spring/docs/3.0.0.M3/reference/html/ch04s11.html

  2. BASIC-4_蓝桥杯_数列特征

    示例代码: #include <stdio.h>#include <stdlib.h> int main(void){ int n = 0 ; int i = 0 ,  max ...

  3. [UE4]GetWorld()->GetDeltaSeconds()方法

    void AAvatar::Yaw(float amount) { if (Controller && amount) { // AddControllerYawInput()函数用于 ...

  4. python + docker, 实现天气数据 从FTP获取以及持久化(五)-- 利用 Docker 容器化 Python 程序

    背景 不知不觉中,我们已经完成了所有的编程工作.接下来,我们需要把 Python 程序 做 容器化 (Docker)部署. 思考 考虑到项目的实际情况,“持久化天气”的功能将会是一个独立的功能模块发布 ...

  5. LayUI——数据表格使用

    Layui数据表格的实际项目使用 Layui的数据表格可谓是在后台管理的页面中经常用到的工具了 最近做项目就用到了,项目的要求是用数据表格显示出后台文章的列表并且每一行的文章都有对应的修改删除操作按钮 ...

  6. Linux系统查看系统硬件配置信息

    1.查看CPU信息 # 查看cpu负载 uptime # cpu使用率 (没有sar 则yum -y install sysstat) sar top bn1 |grep %Cpu # 每个cpu使用 ...

  7. redis存储对象

      redis主要存储类型最常用的五种数据类型: String Hash List Set Sorted set redis存储对象序列化和反序列化 首先来了解一下为什么要实现序列化 为什么要实现序列 ...

  8. [Flutter] 支持描边效果的Text

    新版的flutter已经自带这个功能了.TextSyle 中一个shadow . 目前flutter中没找到很好的办法给Text增加描边.自己扩展了一个TextEx,可以实现简单的描边效果,能满足大部 ...

  9. uva-784-水题-搜索

    题意:从*点开始,标记所有能走到的点,X代表墙,下划线原样输出 AC:40ms #include<stdio.h> #include<iostream> #include< ...

  10. 数据库2.0改进e-r图

    1.新建教师实体集并将1.0中的任课教师,教务老师归类为教师. 2.将实体集考勤表设置为弱实体集. 3.将学生与考勤表的关系由属于关系设置为出勤关系. 4.出勤关系中设置出勤记录属性和教师留言属性. ...