假如AOP日志功能,步骤以下四个:
(1)添加SpringAOP相关jar包:
aspectjweaver-1.6.10.jar + aopalliance-1.0.jar;
(2)编写实现功能的前置增强和后置增强:
新建一个包(com.smbms.AopLog),并新建一个增强类 UserserviceLogger.java:
package com.smbms.AopLog;
import java.util.Arrays;
import org.apache.log4j.Logger;
import org.aspectj.lang.JoinPoint;
public class UserserviceLogger {
private static final Logger log = Logger.getLogger(UserserviceLogger.class);
//前置增强方法
public void before (JoinPoint jp) throws Throwable{
log.info("************before:调用了"+jp.getTarget()+" 的"+jp.getSignature().getName()
+" 方法。方法入参:"+Arrays.toString(jp.getArgs()));
try{
log.info("调用了 "+jp.getTarget()+" 的 "+jp.getSignature().getName()
+" 方法。");
}catch(Throwable e){
log.error(jp.getSignature().getName()+" 方法发生异常: "+e);
throw e;
}finally{
log.info(jp.getSignature().getName()+"方法执行结束");
}
}
//后置增强方法
public void after (JoinPoint jp,Object result) throws Throwable{
log.info("**************after:调用了 "+jp.getTarget()+" 的"+jp.getSignature().getName()
+" 方法。方法入参:"+Arrays.toString(jp.getArgs())+result);
try{
log.info("调用了 "+jp.getTarget()+" 的 "+jp.getSignature().getName()
+" 方法");
}catch(Throwable e){
log.error(jp.getSignature().getName()+" 方法发生异常: "+e);
throw e;
}finally{
log.info(jp.getSignature().getName()+"方法执行结束");
}
}
}
(3)编写Spring配置文件,对设置好的业务方法进行增强处理:
在配置文件添加以下内容:
<bean id="theLogger" class="com.smbms.AopLog.UserserviceLogger"></bean>
<aop:config>
<aop:pointcut expression="execution(* com.smbms.pojo..*.*(..))"
id="pointcut"/>
<aop:aspect ref="theLogger">
<!-- before()方法定义为前置 ,after()方法为后置-->
<aop:before method="before"
pointcut-ref="pointcut"/>
<aop:after-returning method="after"
pointcut-ref="pointcut" returning="result"/>
</aop:aspect>
</aop:config>
(4)写单元测试,获取有增强处理的业务对象;
单元测试UserServiceImpTest.java并不需要作任何改动,因为切面编程就是为了降低耦合而生,所以不需要再测试类中添加任何方法或对象:
package com.smbms.pojo;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserServiceImpTest {
@SuppressWarnings("resource")
@Test
public void test() {
ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext-mybatis.xml");
UserService userService = (UserService)ctx.getBean("userService");
User userCondition = new User();
userCondition.setUserName("mmb");
userCondition.setUserRole(110);
List<User> userList = new ArrayList<User>();
userList = userService.findUsersWithConditions(userCondition);
for(User userResult:userList){
System.out.println("testGetUserList userCode:"+userResult.getUserCode()+
"userName: "+userResult.getUserName()+
"userRole: "+userResult.getUserRole()+
"userRoleName: "+userResult.getUserRoleName()+
"userAddress: "+userResult.getCreationDate());
}
}
}
(5)输出结果(标红部分为AOP使用的效果):
INFO 12-28 21:53:51,212 ************before:璋冪敤浜哻om.smbms.pojo.UserServiceImpl@6253c26 鐨刦indUsersWithConditions 鏂规硶銆傛柟娉曞叆鍙傦細[com.smbms.pojo.User@4f80542f] (UserserviceLogger.java:11)
INFO 12-28 21:53:51,212 璋冪敤浜? com.smbms.pojo.UserServiceImpl@6253c26 鐨? findUsersWithConditions 鏂规硶銆? (UserserviceLogger.java:14)
INFO 12-28 21:53:51,212 findUsersWithConditions鏂规硶鎵ц缁撴潫 (UserserviceLogger.java:20)
DEBUG 12-28 21:53:51,213 Returning cached instance of singleton bean 'theLogger' (AbstractBeanFactory.java:247)
INFO 12-28 21:53:51,213 ************before:璋冪敤浜哻om.smbms.pojo.UserMapperImpl@437da279 鐨刧etUserList 鏂规硶銆傛柟娉曞叆鍙傦細[com.smbms.pojo.User@4f80542f] (UserserviceLogger.java:11)
INFO 12-28 21:53:51,213 璋冪敤浜? com.smbms.pojo.UserMapperImpl@437da279 鐨? getUserList 鏂规硶銆? (UserserviceLogger.java:14)
INFO 12-28 21:53:51,213 getUserList鏂规硶鎵ц缁撴潫 (UserserviceLogger.java:20)
DEBUG 12-28 21:53:51,217 Creating a new SqlSession (JakartaCommonsLoggingImpl.java:54)
DEBUG 12-28 21:53:51,222 SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ffaf86] was not registered for synchronization because synchronization is not active (JakartaCommonsLoggingImpl.java:54)
DEBUG 12-28 21:53:51,233 Fetching JDBC Connection from DataSource (DataSourceUtils.java:110)
DEBUG 12-28 21:53:52,536 JDBC Connection [jdbc:mysql://127.0.0.1:3306/test?
useUnicode=true&characterEncoding=utf-8, UserName=root@localhost, MySQL Connector Java] will not be managed by Spring (JakartaCommonsLoggingImpl.java:54)
DEBUG 12-28 21:53:52,546 ==> Preparing: select u.* ,r.roleName from smbms_user u ,smbms_role r where u.userName like CONCAT('%',?,'%') and u.userRole = ? and u.userRole = r.id (JakartaCommonsLoggingImpl.java:54)
DEBUG 12-28 21:53:52,639 ==> Parameters: mmb(String), 110(Integer) (JakartaCommonsLoggingImpl.java:54)
DEBUG 12-28 21:53:52,855 <== Columns: id, userCode, userName, userPassword, gender, birthday, phone, address, userRole, createBy, createDate, modifyBy, modifyDate, roleName (JakartaCommonsLoggingImpl.java:59)
DEBUG 12-28 21:53:52,857 <== Row: 1, test01, mmb02, 9876543210, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 10:50:04.0, null, null, guan_li_yuan (JakartaCommonsLoggingImpl.java:59)
DEBUG 12-28 21:53:52,872 <== Row: 2, test01, mmb02, scua, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 10:56:48.0, null, null, guan_li_yuan (JakartaCommonsLoggingImpl.java:59)
DEBUG 12-28 21:53:52,873 <== Row: 3, test01, mmb02, scua, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 10:58:46.0, null, null, guan_li_yuan (JakartaCommonsLoggingImpl.java:59)
DEBUG 12-28 21:53:52,874 <== Row: 4, test01, mmb02, scua, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 11:01:42.0, null, null, guan_li_yuan (JakartaCommonsLoggingImpl.java:59)
DEBUG 12-28 21:53:52,876 <== Row: 5, test01, mmb02, scua, 2, 1991-12-29, 0000, maoming, 110, 1, 2017-12-17 11:03:05.0, null, null, guan_li_yuan (JakartaCommonsLoggingImpl.java:59)
DEBUG 12-28 21:53:52,877 <== Total: 5 (JakartaCommonsLoggingImpl.java:54)
DEBUG 12-28 21:53:52,881 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@1ffaf86] (JakartaCommonsLoggingImpl.java:54)
DEBUG 12-28 21:53:52,881 Returning JDBC Connection to DataSource (DataSourceUtils.java:327)
DEBUG 12-28 21:53:52,882 Returning cached instance of singleton bean 'theLogger' (AbstractBeanFactory.java:247)
INFO 12-28 21:53:52,882 **************after:璋冪敤浜? com.smbms.pojo.UserMapperImpl@437da279 鐨刧etUserList 鏂规硶銆傛柟娉曞叆鍙傦細[com.smbms.pojo.User@4f80542f][com.smbms.pojo.User@20b2475a, com.smbms.pojo.User@7857fe2, com.smbms.pojo.User@6f15d60e, com.smbms.pojo.User@1be2019a, com.smbms.pojo.User@29d80d2b] (UserserviceLogger.java:25)
INFO 12-28 21:53:52,882 璋冪敤浜? com.smbms.pojo.UserMapperImpl@437da279 鐨? getUserList 鏂规硶 (UserserviceLogger.java:28)
INFO 12-28 21:53:52,882 getUserList鏂规硶鎵ц缁撴潫 (UserserviceLogger.java:34)
DEBUG 12-28 21:53:52,883 Returning cached instance of singleton bean 'theLogger' (AbstractBeanFactory.java:247)
INFO 12-28 21:53:52,883 **************after:璋冪敤浜? com.smbms.pojo.UserServiceImpl@6253c26 鐨刦indUsersWithConditions 鏂规硶銆傛柟娉曞叆鍙傦細[com.smbms.pojo.User@4f80542f][com.smbms.pojo.User@20b2475a, com.smbms.pojo.User@7857fe2, com.smbms.pojo.User@6f15d60e, com.smbms.pojo.User@1be2019a, com.smbms.pojo.User@29d80d2b] (UserserviceLogger.java:25)
INFO 12-28 21:53:52,883 璋冪敤浜? com.smbms.pojo.UserServiceImpl@6253c26 鐨? findUsersWithConditions 鏂规硶 (UserserviceLogger.java:28)
INFO 12-28 21:53:52,883 findUsersWithConditions鏂规硶鎵ц缁撴潫 (UserserviceLogger.java:34)
testGetUserList userCode:test01userName: mmb02userRole: 110userRoleName: guan_li_yuanuserAddress: null
testGetUserList userCode:test01userName: mmb02userRole: 110userRoleName: guan_li_yuanuserAddress: null
testGetUserList userCode:test01userName: mmb02userRole: 110userRoleName: guan_li_yuanuserAddress: null
testGetUserList userCode:test01userName: mmb02userRole: 110userRoleName: guan_li_yuanuserAddress: null
testGetUserList userCode:test01userName: mmb02userRole: 110userRoleName: guan_li_yuanuserAddress: null
(6)总结:
【1】增强类的编写很重要:
6.1 getTarget()方法:得到被代理的目标对象;
6.2 getSignature()方法:返回被代理的目标方法;
6.3 getArgs()方法:返回传递给目标方法的参数数组;
6.4 对于实现后置增强的afterReturning()方法,还能定义 一个参数(Object result)用于接收目标方法的返回值。
【2】增强类(和切入点)的配置也很重要:
注意标签的嵌套逻辑和顺序。

本文介绍如何利用Spring AOP实现方法级别的日志记录功能,包括添加依赖、编写前置及后置增强方法、配置Spring切点等内容。

被折叠的 条评论
为什么被折叠?



