AOP实例 – 环绕增强日志记录

一、创建商品日志记录表 Product_Log

在这里插入图片描述

-- 创建表
create table Product_Log(
  pl_id number primary key,
  action_class varchar2(100),
  method_name varchar2(100),
  args varchar2(100),
  create_date date default sysdate
  )
-- 创建序列
create sequence seq_pl start with 1;
-- 插入一条数据
insert into product_log values(seq_pl.nextval,'select()','select','eeeeeeee',sysdate)
-- 查询
select * from product_log

结果展示:
在这里插入图片描述

二、完成日志记录表的插入逻辑

  1. 先看一下我的包结构:
    在这里插入图片描述
  2. 需要导入的jar包
    在这里插入图片描述
  3. 日志的插入逻辑,俗称:在数据库上插入信息。过程分为:
    (1)在mybatis中配置mapper文件的路径
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
	PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

	<!-- 配置数据库连接信息 -->
	<environments default="development">
		<environment id="development">
				<transactionManager type="JDBC"/>
				<dataSource type="POOLED">
					<property name="driver" value="oracle.jdbc.OracleDriver"/>
					<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:orcl"/>
					<property name="username" value="hr"/>
					<property name="password" value="123456"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 配置mapper文件的路径 -->
	<mappers>
		<mapper resource="com/gxy/dao/ProductMapper.xml"/>
		<mapper resource="com/gxy/dao/ProductLogMapper.xml"/>
	</mappers>
	
</configuration>

(2)编写mapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
	PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
	"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.gxy.dao.ProductLogDao">

	    <!-- 通用查询映射结果 -->
	    <resultMap id="BaseResultMap" type="com.gxy.entity.ProductLog">
	        <id column="pl_id" property="plId" />
	        <result column="action_class" property="actionClass" />
	        <result column="method_name" property="methodName" />
	        <result column="args" property="args" />
	        <result column="create_date" property="createDate" />
	    </resultMap>
    	
    	<!-- 插入 -->
    	<insert id="insertLog">
    		insert into product_log values(seq_pl.nextval,#{actionClass},#{methodName},#{args},sysdate)
    	</insert>

</mapper>

(3)编写dao层

package com.gxy.dao;

import org.apache.ibatis.annotations.Param;

public interface ProductLogDao {
	//插入
	public void insertLog(@Param("actionClass")String actionClass,
			@Param("methodName")String methodName,
			@Param("args")String args);
}

(4)编写service层

package com.gxy.service;


public interface ProductLogService {
	//插入
	public void insertLog(String actionClass,String methodName,String args);
}

(5)编写service层的接口impl层

package com.gxy.service.impl;

import org.apache.ibatis.session.SqlSession;
import com.gxy.dao.ProductLogDao;
import com.gxy.service.ProductLogService;
import com.gxy.util.MyBatisUtil;

public class ProductLogServiceimpl implements ProductLogService {
   //插入
   public void insertLog(String actionClass, String methodName, String args) {
   	//获取连接
   	SqlSession session = MyBatisUtil.getSqlSession();
   	//通过代理生成对象
   	ProductLogDao logDao = session.getMapper(ProductLogDao.class);
   	//对象调方法
   	logDao.insertLog(actionClass, methodName, args);
   	//提交事务
   	session.commit();
   	//关闭流
   	MyBatisUtil.close();
   }
}

(6)配置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-4.0.xsd
			http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
	
	<bean id="serviceimpl" class="com.gxy.service.impl.ProductServiceimpl"></bean>
	<bean id="logserviceimpl" class="com.gxy.service.impl.ProductLogServiceimpl"></bean>
	
	<!-- 前置增强功能 -->
	<bean id="myBeforeAdvice" class="com.gxy.aop.MyBeforeAdvice"></bean>
	<!-- 后置增强 -->
	<bean id="myAfterAdvice" class="com.gxy.aop.MyAfterAdvice"></bean>
	<!-- 异常增强 -->
	<bean id="myThrowsAdvice" class="com.gxy.aop.MyThrowsAdvice"></bean>
	<!-- 环绕增强 -->
	<bean id="myInterceptor" class="com.gxy.aop.MyInterceptor"></bean>
	
	<!-- aop的配置 -->
	<aop:config>
		<!-- 切入点  -->
		<aop:pointcut expression="execution(* com.gxy.service.ProductService.*(..))" id="myPointCut"/>
		<!-- 编织 -->
		<!-- <aop:advisor advice-ref="myBeforeAdvice" pointcut-ref="myPointCut"/> -->
		<!-- <aop:advisor advice-ref="myAfterAdvice" pointcut-ref="myPointCut"/> -->
		<!-- <aop:advisor advice-ref="myThrowsAdvice" pointcut-ref="myPointCut"/> -->
		<aop:advisor advice-ref="myInterceptor" pointcut-ref="myPointCut"/>
	</aop:config>
	
</beans>

(7)编写环绕增强

package com.gxy.aop;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

public class MyInterceptor implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		System.out.println("环绕增强");
		//获取目标实现类对象
		String actionClass = arg0.getThis().getClass().toString();
		System.out.println("arg0.getThis():"+actionClass);
		//获取目标方法名称
		String methodName = arg0.getMethod().getName();
		System.out.println("arg0.getMethod():"+methodName);
		//获取目标方法参数的实参列表
		Object[] arg = arg0.getArguments();
		for (int i = 0; i < arg.length; i++) {
			System.out.println("arg0.getArguments():"+arg[i]);
		}
		//由于启动了环绕增强,目标类的方法将不会执行,而被.proceed取代,并返回目标类的反参
		//执行目标方法
		Object object = arg0.proceed();
		return object;
	}
}

(8)测试

package com.gxy.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.gxy.service.ProductLogService;

public class TestMain {

	@Test
	public void method1(){
		//加载Spring主配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");
		//根据Bean ID,由工厂创建对象
		ProductLogService logService = (ProductLogService)context.getBean("logserviceimpl");
		logService.insertLog("insert()", "insert", "aaaa");
	}

}

三、环绕增强搜集日志记录参数,并测试

  1. 在环绕增强中搜集日志,记录参数
package com.gxy.aop;

import java.util.Arrays;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.gxy.service.ProductLogService;
import com.gxy.service.impl.ProductLogServiceimpl;

public class MyInterceptor implements MethodInterceptor {

	@Override
	public Object invoke(MethodInvocation arg0) throws Throwable {
		System.out.println("环绕增强");
		//获取目标实现类对象
		String actionClass = arg0.getThis().getClass().toString();
		System.out.println("arg0.getThis():"+actionClass);
		//获取目标方法名称
		String methodName = arg0.getMethod().getName();
		System.out.println("arg0.getMethod():"+methodName);
		//获取目标方法参数的实参列表
		Object[] arg = arg0.getArguments();
		for (int i = 0; i < arg.length; i++) {
			System.out.println("arg0.getArguments():"+arg[i]);
		}
		String args = Arrays.toString(arg);
		//加载Spring主配置文件
		ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");
		ProductLogService logService = (ProductLogService)context.getBean("logserviceimpl");
		logService.insertLog(actionClass, methodName, args);
		//由于启动了环绕增强,目标类的方法将不会执行,而被.proceed取代,并返回目标类的反参
		//执行目标方法
		Object object = arg0.proceed();
		return object;
	}

	
}

  1. 测试(这里是product项目中的修改功能,当执行修改时,将会添加此条记录)
package com.gxy.test;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.gxy.service.ProductService;

public class TestMain {
	//加载Spring主配置文件
	ApplicationContext context = new ClassPathXmlApplicationContext("applicationcontext.xml");

	@Test
	public void test1(){
		//根据Bean ID,由工厂创建对象
		ProductService productService=(ProductService)context.getBean("serviceimpl");
		//修改
		productService.updateProduct("华硕007", "开机速度为1秒", 5632.0, 21);
	}
}

在这里插入图片描述

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值