AOP原理

本文介绍了AOP技术的基础概念,包括连接点、切入点、通知、方面等,并详细解释了AOP的实现方式,包括动态代理技术和静态织入。此外,还探讨了Spring框架下AOP的配置方法,包括使用代理工厂、advisor、XML Schema以及Annotation等方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

AOP基础 : http://wayfarer.cnblogs.com/articles/241024.html

实现AOP的技术,主要分为两大类:
一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;
二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

然而殊途同归,实现AOP的技术特性却是相同的,分别为:
1、join point(连接点):是程序执行中的一个精确执行点,例如类中的一个方法。它是一个抽象的概念,在实现AOP时,并不需要去定义一个join point。
2、point cut(切入点):本质上是一个捕获连接点的结构。在AOP中,可以定义一个point cut,来捕获相关方法的调用。
3、advice(通知):是point cut的执行代码,是执行“方面”的具体逻辑。包括前置通知,后置通知,环绕通知,
4、aspect(方面):point cut和advice结合起来就是aspect,它类似于OOP中定义的一个类,但它代表的更多是对象间横向的关系。
5、introduce(引入):为对象引入附加的方法或属性,从而达到修改对象结构的目的。有的AOP工具又将其称为mixin。

上述的技术特性组成了基本的AOP技术,大多数AOP工具均实现了这些技术。它们也可以是研究AOP技术的基本术语。

AOP有些特有的概念,如:advisor、advice和pointcut等等,使用或配置起来有点绕,让人感觉有些距离感,其实它的实现就是一组标准的设计模式的组合使用:Factory、Proxy、Chain of Responsibility,只要搞清楚这几个设计模式,读AOP的源码是比较容易的。

spring AOP配置中,可以通过三种方式配置:在 Spring AOP 第一代中, AOP 的 Advice 必须实现特定接口,而配置设置依赖于 XML 的繁琐设置。在 Spring2.0 之后,对于 AOP 功能的实现与设置新增了两种方法:一种是基于 XML Schema 的设置;一种是基于 Annotation 的支持。两种方式对于 AOP 在使用上的简化都有极大地帮助。

一是基于Spring API的配置文件,基于sprint API的方式时,advice类必须implements MethodInterceptor, AfterAdvice等接口。
二是使用Spring 2.0基于XML Schema的AOP设置方式,此种方式您必须在XML设档的开头加入AOP的names,此种方式advice无须实现implements MethodInterceptor, AfterAdvice等接口。
三是基于Annotation的AOP设置方式,此种方式在XML中必须配置<aop:aspectj-autoproxy/>,此种方式advice无须实现implements MethodInterceptor, AfterAdvice等接口。


配置方法一: 使用代理工厂的方式配置
<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">

<beans>
<bean id="beforeAdvice" class="com.dragon.Advice.BeforeAdvice"></bean>
<bean id="afterAdvice" class="com.dragon.Advice.AfterAdvice"></bean>
<bean id="compareInterceptor" class="com.dragon.Advice.CompareInterceptor"></bean>
<bean id="studenttarget" class="com.dragon.study.Impl.StudentImpl"></bean>

<bean id="student" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.dragon.study.IStudent</value>
</property>
<property name="interceptorNames">
<list>
<value>beforeAdvice</value>
<value>afterAdvice</value>
<value>compareInterceptor</value>
</list>
</property>
<property name="target">
<ref bean="studenttarget"/>
</property>
</bean>
</beans>
ApplicationContext ctx = new FileSystemXmlApplicationContext("/com/dragon/applicationContext.xml");
IStudent person = (IStudent)ctx.getBean("student");
person.addStudent("dragon");

配置方法二:使用advisor的方式配置
<beans>  
<bean id="log" class="com.gc.action.LogAround"/>
<bean id="timeBook" class="com.gc.action.TimeBook"/>
<!--代理目标类的指定方法-->
<bean id="logAdvisor"class="org.springframework.aop.support.RegexpMethodPointcutAdvisor">
<property name="advice">
<ref bean="log"/>
</property>
<!--指定要代理的方法-->
<property name="patterns">
<value>.*doAuditing.* </value>
</property>
</bean>
<!--设定代理类-->
<bean id="logProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
<property name="proxyInterfaces">
<value>com.gc.impl.TimeBookInterface</value>
</property>
<property name="target">
<ref bean="timeBook"/>
</property>
<property name="interceptorNames">
<list>
<value>logAdvisor</value>
</list>
</property>
</bean>
</beans>


配置方法三: 基于XML Schema的AOP设置方式
<bean id="userManager" class="cn.com.manager.UserManagerImpl"></bean>  
<bean id="securitHandler" class="cn.com.aop.SecurityHandler"></bean>
<aop:config>
<!-- 面相当于拦截器中的通知 -->
<aop:aspect ref="securitHandler">
<!-- 对所有的类以add开头的任何方法使用该方法。相当于拦截器中的目标 -->
<aop:pointcut id="poicut" expression="execution(* add*(..))" />
<!-- method 指出before要调用的方法 指定在接入点处调用的面的方法,如果securitHandler 继承 mothdBefore可不这样写-->
<aop:before method="check" pointcut ref="poicut"/>
</aop:aspect>
</aop:config>

<!-- 加入aop名称空间后,就可以使用spring2.0的标签aop了 -->
<bean id="logBeforeAdvise" class="AOP2Schema.LogBeforeAdvice"/>
<bean id="helloSpeaker" class="AOP2Schema.HelloSpeaker"/>
<aop:config>
<aop:aspect id="logging" ref="logBeforeAdvise">
<aop:before pointcut="execution(* AOP2Schema.ISpeaker.* (..))" method="before"/>
</aop:aspect>
</aop:config>



配置方式四:基于Annotation的AOP设置方式
@Aspect
public class LogBeforeAdvice {
@Pointcut("execution(* com.edu.cug.IHello.*(..)) ")
public void anymethod(){}
@Before("anymethod()")
public void before(JoinPoint joinPoint) {
System.out.println(joinPoint.getSignature().getName()
+ ",start.............LogBeforeAdvice");
}
}
### AOP(面向切面编程)工作原理 #### 定义与概念 AOP 即面向切面编程,是对 OOP 的一种补充而非替代[^1]。这种编程范式旨在处理程序中的横切关注点,即那些跨越多个模块或类的功能,比如日志记录、性能监控、安全性和事务管理等。 #### 关键术语解释 - **连接点(Join Point)**:指应用程序执行过程中的特定位置,在这里可以插入额外的行为。 - **通知(Advice)**:定义了当某个连接点被触发时应采取的动作。常见的有前置通知(Before Advice),后置返回通知(After Returning Advice),异常抛出通知(Around Advice)等。 - **切入点(Pointcut)**:用于指定哪些连接点应该应用该通知的表达式或者模式匹配规则。 - **方面(Aspect)**:包含了通知和切入点定义的对象;它是用来封装横切逻辑的地方。 - **引入(Introduction)**:允许向现有类添加新方法或属性的能力。 #### 工作流程概述 在 Java 生态系统里,Spring 框架提供了对 AOP 支持的主要实现方式——基于代理的方式以及基于注解配置的通知机制[^2]。具体来说: 对于**基于代理的 AOP**而言,Spring 使用 JDK 动态代理或是 CGLIB 库创建目标对象的目标接口/子类实例,并在其上调用的方法前后织入相应的增强处理代码片段。这种方式适用于实现了接口的服务组件。 而对于**基于注解的 AOP**, 开发者可以在源码级别上利用 `@Before`, `@AfterReturning` 等自定义元数据标签标记要拦截的操作并编写对应的处理器函数。编译期或运行时期间会自动扫描这些标注并将它们注册到容器中作为可执行单元参与后续调用链路。 最后值得注意的是,借助于 Spring AOP, 可以有效地将业务功能同通用型服务隔离开来,从而提高系统的灵活性与可维护性[^3]. ```java // 示例代码展示如何声明一个简单的 Aspect 切面 import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class LoggingAspect { @Before("execution(* com.example.service.*.*(..))") public void logMethodCall() { System.out.println("Logging method call..."); } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值