关于AOP,我之前对AOP和OOP进行过对比Spring——闲扯AOP与OOP,在宏观上对AOP部分知识有了一个较清晰的了解。但是AOP的应用只在声明式事务处理时用过。还不能够对AOP进行灵活运用。人尽言AOP是OOP的补充,下面就通过AOP处理log4j记录日志的例子,学习AOP。
首先,AOP处理日志是必需的,不使用AOP处理日志有诸多不便。
日志处理是每个项目当中一个非常重要的内容。没有了日志,也就失去了对系统的可控性。没有日志,系统出现任何问题,都会没有踪迹可寻,这对一个信息系统而言是非常危险的。
然而,使用纯OOP思想进行日志处理,我们会发现,每个逻辑部分中总会混入日志处理的代码,导致纯OOP思想的设计略显不伦不类。同时,如果记录日志的类型需求有变更,那么我们就要去每个逻辑单元中修改Java代码。另外,如果需求今天变了明天再变的话,我想这将是一个非常繁重并且惹人厌的工作。
其实日志处理应该是软件系统中单独的一大部分,开发人员在进行系统开发时,不应该再来考虑日志处理。AOP能够做到这一点,让开发人员更加专注于系统的业务编码,而无需顾虑日志问题(这一点大家可以联系声明式事务处理的方式,配置好了处理事务的配置文件,编写Manager或者action时,都无需顾虑事务)。
然后,介绍例子中的代码实现。
1、引入jar包:
2、切面Aspect代码:
package com.lzq.spring.aop;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import com.lzq.spring.test.AOPTest;
/**
* 切面
* @author lzq
*
*/
public class Aspect {
Logger logger = Logger.getLogger(AOPTest.class);
String strLog = null ;
/**
* 前置通知:在某连接点之前执行的通知,但这个通知不能阻止连接点前的执行
* @param jp 连接点:程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者抛出的异常行为
*/
public void doBefore(JoinPoint jp) {
strLog = "log Begining method: "
+ jp.getTarget().getClass().getName() + "."
+ jp.getSignature().getName();
logger.warn(strLog);
}
/**
* 环绕通知:包围一个连接点的通知,可以在方法的调用前后完成自定义的行为,也可以选择不执行
* 类似Web中Servlet规范中的Filter的doFilter方法。
* @param pjp 当前进程中的连接点
* @return
* @throws Throwable
*/
public Object doAround(ProceedingJoinPoint pjp) throws Throwable {
long time = System.currentTimeMillis();
Object retVal = pjp.proceed();
time = System.currentTimeMillis() - time;
System.out.println("process time: " + time + " ms");
return retVal;
}
/**
* 抛出异常后通知 : 在方法抛出异常退出时执行的通知。
* @param jp 连接点:程序执行过程中的某一行为,例如,AServiceImpl.barA()的调用或者抛出的异常行为
*/
public void doAfter(JoinPoint jp) {
strLog ="doAfter:log Ending method: "
+ jp.getTarget().getClass().getName() + "."
+ jp.getSignature().getName();
logger.warn(strLog);
}
}
3、业务代码:
业务逻辑接口:
package com.lzq.spring.service;
/**
* 接口 AService
*/
public interface AService {
public void cool(String _msg);
public void cool();
}
业务接口的实现:
package com.lzq.spring.service;
/**
* 接口的实现
* @author lzq
*
*/
public class AServiceImpl implements AService {
@Override
public void cool() {
System.out.println("哇,楼主好帅!");
}
@Override
public void cool(String name) {
System.out.println("哇,楼主"+name+",你好帅啊!");
}
}
4、测试AOPTest:
package com.lzq.spring.test;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.lzq.spring.service.AService;
public class AOPTest{
public static void main(String[] args){
BeanFactory factory = new ClassPathXmlApplicationContext("ApplicationContext.xml");
AService aService = (AService)factory.getBean("aService");
aService.cool();
aService.cool("泉浴五江");
}
}
5、Spring配置文件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"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd"
default-autowire="autodetect">
<aop:config>
<aop:aspect id="aspect" ref="aspectBean">
<!--配置com.lzq.spring.service包下所有类或接口的所有方法-->
<aop:pointcut id="logService"
expression="execution(* com.lzq.spring.service.*.*(..))" />
<aop:before pointcut-ref="logService" method="doBefore"/>
<aop:after pointcut-ref="logService" method="doAfter"/>
<aop:around pointcut-ref="logService" method="doAround"/>
</aop:aspect>
</aop:config>
<bean id="aspectBean" class="com.lzq.spring.aop.Aspect" />
<bean id="aService" class="com.lzq.spring.service.AServiceImpl" />
</beans>
6、log4j的properties文件主要配置:
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=d:/test_log.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n
log4j.rootLogger=warn, stdout,file
log4j.logger.org.hibernate.type=info
log4j.logger.org.hibernate.tool.hbm2ddl=debug
com.lzq.spring.service = debug
7、显示结果:
Console窗口
文件位置:
日志文件内容:
8、源码下载:(网络不好,传不上来,下午补上。。。)
最后总结一下这个例子。
本文从通过记录日志的Demo,简单实现了记录日志的功能。相信通过声明式事务与本文中的例子,您对AOP的理解将会更上一层楼。
分享到:
相关推荐
ssh+aop+log4j+日志拦截器+注解
AOP能够做到这一点,让开发人员更加专注于系统的业务编码,而无需顾虑日志问题(这一点大家可以联系声明式事务处理的方式,配置好了处理事务的配置文件,编写Manager或者action时,都无需顾虑事务)
NULL 博文链接:https://miaoxianjie.iteye.com/blog/2067308
aop+swagger,拦截记录日志功能,博客会有详细描述
SpringBoot+AOP+TraceID.pdf
基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)基于Cglib简单实现Spring体系(Ioc+Aop+Mvc)...
内容概要:springboot+拦截器+aop+自定义注解+本地线程实现统一接口日志记录,记录下接口所在模块、接口描述、接口请求参数、接口返回参数、接口请求时间以及接口耗时用于接口优化,接口记录参数以及操作人防止使用...
使用springmvc,利用aop aspectj log4j 实现进入函数,退出函数的日志的记录
aop + exception aop + exception
基于Log4j+SpringAOP+Annotation的可注解日志切面组件 使用方式 @Log(logAfter = true, logBefore = true) public returntype methodName(params) 测试类com.liam.aop.aspect.test.AopLogAnnotationTest 测试输出 ...
Spring mvc Aop+annotation实现系统日志记录功能实现的jar包asm-3.3.jar ,aspectjrt.jar , aspectjweaver.jar , cglib-nodep-2.1_3.jar , spring-aop.jar
千行代码实现代理式AOP+属性的自动装配
aop+mvc+facAop完整案例,基于c#的应用,给初学者提供帮助
Spring AOP + SpringMVC +Mybatis做动态数据源,实现读写分离Spring AOP + SpringMVC +Mybatis做动态数据源,实现读写分离Spring AOP + SpringMVC +Mybatis做动态数据源,实现读写分离
SpringMVC+springAOP+spring security+Hibernate整合实例代码,包含框架jar包
包含Jmail例子,AOP面向切面编程的日志处理例子,HttpInvoker的例子,RMI远程调用的例子,定时任务的例子,自己没事写的,简单易懂
可以直接运行,springboot+shiro+mybatis+redis+通用mapper+aop+CodeGenerator,redis和通用mapper集合在一起,并且代码可以自动生成,
手写spring框架ioc+aop+mvc
SpringBoot 中的 Aop + 自定义注解 1. @AspectJ 1.1 `@AspectJ` 切面类 1.2 `@Pointcut` 创建切入点 1.3 通知 1.4 Spring AOP 和 AspectJ AOP 有什么区别? 2. 在 SpringBoot 中使用 Aop 功能 2.0 创建一个...
使用SpringBoot通过自定义注解+AOP+全局异常处理实现参数统一非空校验