Spring框架-AOP添加日志记录功能
需求,在调用业务方法的时候,在被调用的业务方法的前面和后面添加上日志记录功能
整体架构:
日志处理类:
1 package aop;
2
3 import java.util.Arrays;
4
5 import org.apache.log4j.Logger;
6 import org.aspectj.lang.JoinPoint;
7
8 //日志处理类 增强处理类-日志
9 public class UserServiceLogger {
10 private Logger logger = Logger.getLogger(UserServiceLogger.class);
11
12 // 前置增强
13 public void before(JoinPoint joinPoint) {
14 logger.info("调用" + joinPoint.getTarget() + "的"
15 + joinPoint.getSignature() + "方法,方法参数是:"
16 + Arrays.toString(joinPoint.getArgs()));
17 }
18
19 // 后置增强
20 public void afterReturning(JoinPoint joinPoint,Object result) {
21 logger.info("调用" + joinPoint.getTarget() + "的"
22 + joinPoint.getSignature() + "方法,方法的返回值是:"
23 +result);
24 }
25 }
下面是一个三层架构模式:
1 package dao;
2
3 import entity.User;
4
5 /**
6 * 增加DAO接口,定义了所需的持久化方法
7 */
8 public interface UserDao {
9 public void save(User user);
10 }
package dao.impl;
import dao.UserDao;
import entity.User;
/**
* 用户DAO类,实现IDao接口,负责User类的持久化操作
*/
public class UserDaoImpl implements UserDao {
public void save(User user) {
// 这里并未实现完整的数据库操作,仅为说明问题
System.out.println("保存用户信息到数据库");
}
}
1 package entity;
2
3 /**
4 * 用户实体类
5 */
6 public class User implements java.io.Serializable {
7 private Integer id; // 用户ID
8 private String username; // 用户名
9 private String password; // 密码
10 private String email; // 电子邮件
11
12 // getter & setter
13 public Integer getId() {
14 return id;
15 }
16
17 public void setId(Integer id) {
18 this.id = id;
19 }
20
21 public String getUsername() {
22 return username;
23 }
24
25 public void setUsername(String username) {
26 this.username = username;
27 }
28
29 public String getPassword() {
30 return password;
31 }
32
33 public void setPassword(String password) {
34 this.password = password;
35 }
36
37 public String getEmail() {
38 return email;
39 }
40
41 public void setEmail(String email) {
42 this.email = email;
43 }
44
45 }
1 package service;
2
3 import entity.User;
4
5 /**
6 * 用户业务接口,定义了所需的业务方法
7 */
8 public interface UserService {
9 public void addNewUser(User user);
10 }
1 package service.impl;
2
3 import service.UserService;
4 import dao.UserDao;
5 import entity.User;
6
7 /**
8 * 用户业务类,实现对User功能的业务管理
9 */
10 public class UserServiceImpl implements UserService {
11
12 // 声明接口类型的引用,和具体实现类解耦合
13 private UserDao dao;
14
15 // dao 属性的setter访问器,会被Spring调用,实现设值注入
16 public void setDao(UserDao dao) {
17 this.dao = dao;
18 }
19
20 public void addNewUser(User user) {
21 // 调用用户DAO的方法保存用户信息
22 dao.save(user);
23 }
24 }
编写单元测试方法:
package test;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import service.UserService;
import service.impl.UserServiceImpl;
import entity.User;
public class AopTest {
@Test
public void aopTest() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserService service = (UserService) ctx.getBean("service");
User user = new User();
user.setId(1);
user.setUsername("test");
user.setPassword("123456");
user.setEmail("test@xxx.com");
service.addNewUser(user);
}
}
applicationContext.xml核心配置文件:
1 <?xml version="1.0" encoding="UTF-8"?> 2 <beans xmlns="http://www.springframework.org/schema/beans" 3 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 4 xmlns:aop="http://www.springframework.org/schema/aop" 5 xsi:schemaLocation="http://www.springframework.org/schema/beans 6 http://www.springframework.org/schema/beans/spring-beans-3.2.xsd 7 http://www.springframework.org/schema/aop 8 http://www.springframework.org/schema/aop/spring-aop-3.2.xsd"> 9 <bean id="dao" class="dao.impl.UserDaoImpl"></bean> 10 <bean id="service" class="service.impl.UserServiceImpl"> 11 <property name="dao" ref="dao"></property> 12 </bean> 13 <!-- 声明增强方法所在的Bean --> 14 <bean id="theLogger" class="aop.UserServiceLogger"></bean> 15 <!-- 配置切面 --> 16 <aop:config> 17 <!-- 定义切入点 --> 18 <aop:pointcut id="pointcut" 19 expression="execution(public void addNewUser(entity.User))" /> 20 <!-- 引用包含增强方法的Bean --> 21 <aop:aspect ref="theLogger"> 22 <!-- 将before()方法定义为前置增强并引用pointcut切入点 --> 23 <aop:before method="before" pointcut-ref="pointcut"></aop:before> 24 <!-- 将afterReturning()方法定义为后置增强并引用pointcut切入点 --> 25 <!-- 通过returning属性指定为名为result的参数注入返回值 --> 26 <aop:after-returning method="afterReturning" 27 pointcut-ref="pointcut" returning="result" /> 28 </aop:aspect> 29 </aop:config> 30 </beans>
运行结果:
1 12-29 15:13:06[INFO]org.springframework.context.support.ClassPathXmlApplicationContext
2 -Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@2db0f6b2: startup date [Sun Dec 29 15:13:06 CST 2019]; root of context hierarchy
3 12-29 15:13:06[INFO]org.springframework.beans.factory.xml.XmlBeanDefinitionReader
4 -Loading XML bean definitions from class path resource [applicationContext.xml]
5 12-29 15:13:06[INFO]org.springframework.beans.factory.support.DefaultListableBeanFactory
6 -Pre-instantiating singletons in org.springframework.beans.factory.support.DefaultListableBeanFactory@3701eaf6: defining beans [userDao,service,theLogger,org.springframework.aop.config.internalAutoProxyCreator,pointcut,org.springframework.aop.aspectj.AspectJPointcutAdvisor#0,org.springframework.aop.aspectj.AspectJPointcutAdvisor#1]; root of factory hierarchy
7 12-29 15:13:06[INFO]aop.UserServiceLogger
8 -调用service.impl.UserServiceImpl@3c130745的void service.UserService.addNewUser(User)方法,方法参数是:[entity.User@2e4b8173]
9 保存用户信息到数据库
10 12-29 15:13:06[INFO]aop.UserServiceLogger
11 -调用service.impl.UserServiceImpl@3c130745的void service.UserService.addNewUser(User)方法,方法的返回值是:null