3、AOP技术

该栏目会系统的介绍Spring的知识体系,共分为基础部分、源代码和综合实例等模块,有兴趣的小伙伴可以关注下,如有疑问可以多多评论



AOP简介

1、概述

  • 面向切面编程,指在扩展功能时不需要修改源代码。

2、优点

  • 减少重复代码
  • 提高开发效率
  • 维护方便

3、原理

  • 有接口时,使用动态代理创建接口的实现类的代理对象,此时动态代理对象有着和实现类一样的功能,这叫JDK动态代理
  • 没有接口时,使用动态代理创建需要扩展功能的类的子类的代理对象,这叫CGLIB动态代理

4、操作术语

  • JoinPoint(连接点): 类中那些可以被增强的方法,被称为连接点
  • Pointcut(切入点)实际被增加的方法,被称为切入点
  • Advice(通知/增强):实际增强逻辑
类型功能
前置通知方法执行之前执行
后置通知方法执行之后执行
异常通知方法出现异常时执行
最终通知在后置通知之后执行
环绕通知在方法之前和方法之后执行
  • Aspect(切面):把增强逻辑应用到具体的方法上
  • Introduction(引介):在类运行期间动态的添加方法和属性
  • Target(目标对象):增强方法所在的类
  • Weaving(织入):把advice应用到target的过程
  • Proxy(代理):类被AOP织入增强后,产生的结果代理类

AspectJ框架

1、概述

  • :是一个面向切面的框架,与Spring框架结合操作AOP

2、相关Jar包

  • spring核心jar包、spring-aop.jar
  • spring-aspectjs.jar
  • aspectjweaver.jar
  • aopalliance.jar

3、使用方式

  • 配置文件方式

    • 添加aop相关约束
    • 使用表达式配置切入点:execution(<访问修饰符>?<返回值><方法名>(<参数>)<异常>)
  • 注解方式

    • 在Spring核心配置文件中,开启aop操作
    • 在方法上面使用注解

4、配置文件方式案例

  • 被增强类
public class Book {

	public void add(){
		System.out.println("add........");
	}

}
  • 增强类
public class MyBook {

	public void befored1(){
		System.out.println("前置增强............");
	}
	
	public void arround1(ProceedingJoinPoint proceedingJoinPoint)
			throws Throwable {
		System.out.println("先执行的代码.....");
		proceedingJoinPoint.proceed();
		System.out.println("后执行的代码.....");
	}

}
  • 测试类
public class TestDemo01 {

	@Test
	public void test01(){
		ApplicationContext context = 
					new ClassPathXmlApplicationContext("ApplicationContext.xml");
		Book book = (Book) context.getBean("book");
		book.add();
	}
	
}
  • 配置文件
<?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.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- 配置对象 -->
	<bean id="book" class="cn.itcast.web.aop.Book"></bean>
	<bean id="myBook" class="cn.itcast.web.aop.MyBook"></bean>

	<!-- 配置aop -->
	<aop:config>
		<!-- 1.配置切入点 -->
		<aop:pointcut expression="execution(* cn.itcast.web.aop.Book.*(..))"
			id="pointcut1" />

		<!-- 2.配置切面 -->
		<aop:aspect ref="myBook">
			<aop:before method="befored1" pointcut-ref="pointcut1"/>
		</aop:aspect>
		
		<aop:aspect ref="myBook">
			<aop:around method="arround1" pointcut-ref="pointcut1"/>
		</aop:aspect>
	</aop:config>
</beans>

5、注解方式案例

  • 被增强类
public class Book {

	public void add(){
		System.out.println("add........");
	}

}
  • 增强类
@Aspect
public class MyBook {

	// 在方法上面使用注解
	@Before(value = "execution(* cn.itcast.aop.Book.*(..))")
	public void before1() {
		System.out.println("前置增强");
	}

}
  • 测试类
public class TestAop {

	@Test
	public void test01(){
		ApplicationContext context = 
					new ClassPathXmlApplicationContext("ApplicationContext.xml");
		Book book = (Book)context.getBean("book");
		book.add();
	}

}
  • 配置文件
<?xml version="1.0" encoding="UTF-8"?>
	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.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop.xsd">

	<!-- 开启aop操作 -->
	<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

	<!-- 创建对象 -->
	<bean id="book" class="cn.itcast.aop.Book"></bean>
	<bean id="myBook" class="cn.itcast.aop.MyBook"></bean>
</beans>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用 AOP 技术拦截并修改 SQL 语句的步骤如下: 1. 配置 AOP:在 Spring 配置文件中配置 AOP,指定要拦截的切点(Pointcut)和要执行的通知(Advice)。例如,可以使用 AspectJ 注解来定义切点和通知: ```java @Aspect public class SqlInterceptor { @Pointcut("execution(* org.example.dao.*.*(..))") public void daoMethods() {} @Around("daoMethods()") public Object interceptSql(ProceedingJoinPoint joinPoint) throws Throwable { String sql = getSql(joinPoint); // 修改 SQL 语句 String modifiedSql = modifySql(sql); // 记录日志 logSql(modifiedSql); // 执行 SQL 语句 return joinPoint.proceed(); } private String getSql(ProceedingJoinPoint joinPoint) { // 获取 SQL 语句 MethodSignature signature = (MethodSignature) joinPoint.getSignature(); Method method = signature.getMethod(); String sql = getSqlFromAnnotation(method); if (sql == null) { sql = getSqlFromStatement(method); } return sql; } // ... } ``` 上述代码定义了一个名为 "SqlInterceptor" 的切面(Aspect),包含一个名为 "daoMethods" 的切点和一个名为 "interceptSql" 的通知。切点指定了要拦截的 DAO 方法,通知使用 "Around" 类型,并在方法执行前后执行一些操作,例如获取 SQL 语句、修改 SQL 语句、记录日志等。 2. 实现通知逻辑:在通知方法中,可以使用反射等方式获取 DAO 方法的参数、返回值、注解等信息,然后根据这些信息生成或修改 SQL 语句。例如,可以使用 JSqlParser 等工具来解析 SQL 语句,然后修改其中的条件、表名、列名等信息。 ```java private String modifySql(String sql) { Statement statement = CCJSqlParserUtil.parse(sql); if (statement instanceof Select) { Select select = (Select) statement; // 修改 SELECT 语句中的列名 List<SelectItem> selectItems = select.getSelectItems(); for (SelectItem item : selectItems) { if (item instanceof SelectExpressionItem) { SelectExpressionItem expressionItem = (SelectExpressionItem) item; Expression expression = expressionItem.getExpression(); if (expression instanceof Column) { Column column = (Column) expression; column.setColumnName("modified_" + column.getColumnName()); } } } return select.toString(); } else if (statement instanceof Update) { Update update = (Update) statement; // 修改 UPDATE 语句中的表名 Table table = update.getTable(); table.setName("modified_" + table.getName()); return update.toString(); } else { return sql; } } ``` 上述代码使用 JSqlParser 解析 SQL 语句,并修改其中的列名或表名,然后返回修改后的 SQL 语句。需要注意的是,不同类型的 SQL 语句需要使用不同的方式进行修改。 3. 调用 DAO 方法:在通知方法中,调用原始的 DAO 方法,执行修改后的 SQL 语句,或者将修改后的 SQL 语句传递给下一个拦截器。如果需要执行多个拦截器,可以使用环绕通知(Around Advice),在通知方法中调用 joinPoint.proceed() 方法,将控制权传递给下一个拦截器或 DAO 方法。 上述代码实现了拦截并修改 SQL 语句的功能,可以根据实际需求进行修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值