java ssh spring aop 切面编程 操作日志

一、切面编程原理:

原理

AOP(Aspect Oriented Programming),也就是面向方面编程的技术。AOP基于IoC基础,是对OOP的有益补充。

  AOP将应用系统分为两部分,核心业务逻辑(Core business concerns)及横向的通用逻辑,也就是所谓的方面Crosscutting enterprise concerns,例如,所有大中型应用都要涉及到的持久化管理(Persistent)、事务管理(Transaction Management)、安全管理(Security)、日志管理(Logging)和调试管理(Debugging)等。

  AOP正在成为软件开发的下一个光环。使用AOP,你可以将处理aspect的代码注入主程序,通常主程序的主要目的并不在于处理这些aspect。AOP可以防止代码混乱。

  Spring framework是很有前途的AOP技术。作为一种非侵略性的、轻型的AOP framework,你无需使用预编译器或其他的元标签,便可以在Java程序中使用它。这意味着开发团队里只需一人要对付AOP framework,其他人还是像往常一样编程。

  AOP概念

  让我们从定义一些重要的AOP概念开始。

  — 方面(Aspect):一个关注点的模块化,这个关注点实现可能另外横切多个对象。事务管理是J2EE应用中一个很好的横切关注点例子。方面用Spring的Advisor或拦截器实现。

  — 连接点(Joinpoint):程序执行过程中明确的点,如方法的调用或特定的异常被抛出。

  — 通知(Advice):在特定的连接点,AOP框架执行的动作。各种类型的通知包括“around”、“before”和“throws”通知。通知类型将在下面讨论。许多AOP框架包括Spring都是以拦截器做通知模型,维护一个“围绕”连接点的拦截器链。

  — 切入点(Pointcut):指定一个通知将被引发的一系列连接点的集合。AOP框架必须允许开发者指定切入点,例如,使用正则表达式。

  — 引入(Introduction):添加方法或字段到被通知的类。Spring允许引入新的接口到任何被通知的对象。例如,你可以使用一个引入使任何对象实现IsModified接口,来简化缓存。

  — 目标对象(Target Object):包含连接点的对象,也被称作被通知或被代理对象。

  — AOP代理(AOP Proxy):AOP框架创建的对象,包含通知。在Spring中,AOP代理可以是JDK动态代理或CGLIB代理。

  — 编织(Weaving):组装方面来创建一个被通知对象。这可以在编译时完成(例如使用AspectJ编译器),也可以在运行时完成。Spring和其他纯Java AOP框架一样,在运行时完成织入。

  各种通知类型包括:

  —  Around通知:包围一个连接点的通知,如方法调用。这是最强大的通知。Aroud通知在方法调用前后完成自定义的行为,它们负责选择继续执行连接点或通过返回它们自己的返回值或抛出异常来短路执行。

  —  Before通知:在一个连接点之前执行的通知,但这个通知不能阻止连接点前的执行(除非它抛出一个异常)。

  —  Throws通知:在方法抛出异常时执行的通知。Spring提供强制类型的Throws通知,因此你可以书写代码捕获感兴趣的异常(和它的子类),不需要从Throwable或Exception强制类型转换。

  —  After returning通知:在连接点正常完成后执行的通知,例如,一个方法正常返回,没有抛出异常。

  Around通知是最通用的通知类型。大部分基于拦截的AOP框架(如Nanning和Jboss 4)只提供Around通知。

  如同AspectJ,Spring提供所有类型的通知,我们推荐你使用最为合适的通知类型来实现需要的行为。例如,如果只是需要用一个方法的返回值来更新缓存,你最好实现一个after returning通知,而不是around通知,虽然around通知也能完成同样的事情。使用最合适的通知类型使编程模型变得简单,并能减少潜在错误。例如,你不需要调用在around通知中所需使用的MethodInvocation的proceed()方法,因此就调用失败。

  切入点的概念是AOP的关键,它使AOP区别于其他使用拦截的技术。切入点使通知独立于OO的层次选定目标。例如,提供声明式事务管理的around通知可以被应用到跨越多个对象的一组方法上。 因此切入点构成了AOP的结构要素。

 拦截器(也称拦截机)

    拦截机 (Interceptor), 是 AOP (Aspect-Oriented Programming) 的另一种叫法。AOP本身是一门语言,只不过我们使用的是基于JAVA的集成到Spring 中的 SpringAOP。同样,我们将通过我们的例子来理解陌生的概念。


2、切面代码实现

首先是接口类,然后是实现类,aop的拦截都是主要面向接口的,所以最好有个接口类,当然也可以就用一般的方法。


2、1切面日志类


package cn.com.cardinfo.merchantlink.aspect;

import java.lang.reflect.Method;

import org.apache.log4j.Logger;
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  
@Aspect
public class LogAspect {
	Logger logger= Logger.getLogger(LogAspect.class);
	@Pointcut("execution(* cn.com.cardinfo.merchantlink.service.*.*(..))")  
	
    public void 	Controller(){        
    }
	
		
	@Before("Controller()")  
    public void beforeLog(JoinPoint jp){  
		jp.getArgs();
		//Object result = jp.proceed();
        System.out.println("log前");  
    }  
	
	@AfterReturning(pointcut="Controller()",returning="retVal")
	public void AfterreLog(JoinPoint jp,Object retVal)
	{
		Object object = null;  
        object = jp.getThis();//返回代理对象  
        Object[] args = jp.getArgs();
        String logvalues="";
        for(int i=0;i<args.length;i++)
        {
        	logvalues+="属性"+i+"::"+args[i].toString()+"--";
        }
        /*切入点主体方法的名字*/  
        String methodName = jp.getSignature().getName();  
        String ClassName = jp.getTarget().getClass().toString(); 
     // 获取目标对象
        
        Object target = jp.getTarget();
        
        // 执行完方法的返回值:调用proceed()方法,就会触发切入点方法执行
        
        
        if (retVal!=null) {  
            System.out.println(logvalues+"执行类:"+ClassName+"的方法:"+methodName+"()"+"执行成功;");  
            logger.fatal(logvalues+"执行类:"+ClassName+"的方法:"+methodName+"()"+"执行成功;");
        }  
        else
        {
        	System.out.println(logvalues+"执行类:"+ClassName+"的方法:"+methodName+"()"+"执行失败;");  
        	logger.fatal(logvalues+"执行类:"+ClassName+"的方法:"+methodName+"()"+"执行失败;");
        }
	}
	
	@After(value="Controller()")  
    public void afterLog(JoinPoint jp){  
		Object object = null;  
        object = jp.getThis();//返回代理对象  
        /*切入点主体方法的名字*/  
        String methodName = jp.getSignature().getName();  
            System.out.println("方法:"+methodName+"()"+"成功执行;"+"登录成功!");  
    } 
	@AfterThrowing(value="Controller()" ,throwing = "e")
	public void afterThrowing(JoinPoint jp, Throwable e) {  
        System.out.println(jp.getSignature().getName()+">>>>>异常"+e.getMessage());
    }  
	
	
}


以上用的是注解的方法,所以在xml配置的时候不用那么复杂不过需要引入一些注解的jar接下来是spring文件的配置

先加入

xmlns:aop="http://www.springframework.org/schema/aop"


然后在xsi:schemaLocation="中加入http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "

<tx:annotation-driven />
<bean id="myAdvice" class="cn.com.cardinfo.merchantlink.aspect.LogAspect" />


<aop:aspectj-autoproxy />


加上这些后配置就ok了,现在主要就是修改之前类你要指定的aop拦截的一些接口的路径了,参考以上就可以大概明白了


然后这里需要加入log4j的配置文件和xml配置,才能运行,请大家自行测试吧~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值