一文详解Spring AOP的配置与使用攻略
1. Spring AOP简介
Spring AOP是Spring框架中的一个模块,它提供了基于代理的AOP实现。
AOP(Aspect Oriented Programming)即面向切面编程,是一种编程范式。它通过在程序运行期间动态地将代码切入到类的指定方法或指定位置上,实现一些特定功能。
Spring AOP中的切面有如下几种类型:
- Before:在某个连接点(方法或者字段)之前执行。
- After:在某个连接点(方法或者字段)之后执行,不管其是否成功。
- After-returning:在某个连接点(方法或者字段)正常结束后执行。
- After-throwing:在某个连接点(方法或者字段)抛出异常时执行。
- Around:在某个连接点(方法或者字段)执行时,执行前后触发操作。
2. Spring AOP的配置
Spring AOP的配置分为三部分:切面、通知和切点。
2.1 切面
切面是切入到目标对象(被代理对象)上的一段代码。在Spring AOP中,切面的配置可以通过XML文件方式或注解方式进行。
- XML配置方式:
<aop:aspect id="logAspect" ref="logAspectBean">
<!-- 切点 -->
<aop:pointcut id="logPointCut" expression="execution(* com.example.demo.service.*.*(..))" />
<!-- 通知 -->
<aop:before method="beforeMethod" pointcut-ref="logPointCut" />
</aop:aspect>
<bean id="logAspectBean" class="com.example.demo.aspect.LogAspect" />
- 注解配置方式:
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* com.example.demo.service.*.*(..))")
public void logPointCut() {}
@Before("logPointCut")
public void beforeMethod() {}
}
2.2 通知
通知是切面中的一段代码,它就是在切入点(连接点)执行时执行的代码。通知的类型有五种,分别是Before、After、After-returning、After-throwing和Around。
- Before通知:
public void beforeMethod() {
System.out.println("Before Advice");
}
- After通知:
public void afterMethod() {
System.out.println("After Advice");
}
- After-returning通知:
public void afterReturningMethod() {
System.out.println("After Returning Advice");
}
- After-throwing通知:
public void afterThrowingMethod() {
System.out.println("After Throwing Advice");
}
- Around通知:
public Object aroundMethod(ProceedingJoinPoint point) throws Throwable {
System.out.println("Around Before Advice");
Object result = point.proceed();
System.out.println("Around After Advice");
return result;
}
2.3 切点
切点是程序中真正被代理的对象。它是代理对象要处理的方法的集合。切点可以使用表达式的方式来描述具体的哪些方法被拦截。
表达式的写法:
execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern) throws-pattern?)
其中:
- modifiers-pattern:可选的访问修饰符(public、protected等);
- ret-type-pattern:方法返回类型;
- declaring-type-pattern:方法所属的类;
- name-pattern:方法名称;
- param-pattern:方法参数;
- throws-pattern:抛出的异常。
示例1:
<aop:pointcut id="logPointCut" expression="execution(* com.example.demo.service.*.*(..))" />
示例2:
@Pointcut("execution(* com.example.demo.service.*.*(..))")
public void logPointCut() {}
3. Spring AOP的使用
下面通过一个简单的例子,来演示Spring AOP的使用。
3.1 编写被代理的类
public class HelloServiceImpl implements HelloService {
@Override
public void sayHello(String name) {
System.out.println("Hello, " + name);
}
}
3.2 编写切面
@Aspect
@Component
public class LogAspect {
@Pointcut("execution(* com.example.demo.service.HelloServiceImpl.sayHello(..))")
public void logPointCut() {}
@Before("logPointCut()")
public void beforeMethod() {
System.out.println("Before Advice");
}
}
3.3 编写Spring配置文件
<bean id="helloService" class="com.example.demo.service.HelloServiceImpl" />
<bean id="logAspect" class="com.example.demo.aspect.LogAspect" />
<aop:config>
<aop:aspect ref="logAspect">
<aop:pointcut id="logPointCut" expression="execution(* com.example.demo.service.HelloServiceImpl.sayHello(..))" />
<aop:before method="beforeMethod" pointcut-ref="logPointCut" />
</aop:aspect>
</aop:config>
3.4 测试
public class App {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
HelloService helloService = (HelloService) context.getBean("helloService");
helloService.sayHello("world");
}
}
运行结果:
Before Advice
Hello, world
4. 总结
Spring AOP的配置和使用相对来说比较简单,只需要掌握好切面、通知和切点三个概念,就可以轻松地进行AOP的配置和使用。同时,Spring AOP的代理方式是基于JDK动态代理和CGLIB动态代理实现的,也可以用来代理接口和类。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:一文详解Spring AOP的配置与使用 - Python技术站