我来详细讲解一下 "聊聊Spring——AOP详解(AOP概览)" 这篇文章的完整攻略。
什么是AOP
AOP(Aspect-Oriented Programming)是一种编程思想,它通过将横切关注点(Cross-cutting Concern)从主业务逻辑中分离出来,将其封装为一种独立的模块化方式,从而使程序结构更加清晰,维护更加方便。
AOP的术语
Join Point
Join Point(连接点)是指程序执行过程中的一个特定点,比如方法调用、异常抛出等。
Pointcut
Pointcut(切点)是指我们对哪些 Join Point 感兴趣,通常是通过表达式的方式指定。
Advice
Advice(通知)是指在切点上执行的代码,有 Before、After、Around、Throws 等多种类型。
Aspect
Aspect(切面)是切点和通知的组合体。
AOP的实现方式
经典的 AOP 实现方式有两种
基于动态代理的实现方式
Java JDK 提供了动态代理机制来实现 AOP,也可以使用第三方 JDK 动态代理库,比如 CGLIB。
代码示例:
public interface IUserService {
public void addUser(String username, String password);
}
public class UserServiceImpl implements IUserService{
public void addUser(String username, String password) {
System.out.println("添加用户 " + username + "|" + password);
}
}
public class LogInterceptor implements InvocationHandler {
private Object target;
public LogInterceptor(Object target) {
this.target = target;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("开始记录日志");
Object result = method.invoke(target, args);
System.out.println("结束记录日志");
return result;
}
}
public class Client {
public static void main(String[] args) {
IUserService userService = new UserServiceImpl();
InvocationHandler handler = new LogInterceptor(userService);
IUserService proxy = (IUserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(), handler);
proxy.addUser("lucy", "123456");
}
}
基于字节码增强的实现方式
基于字节码增强的 AOP 实现方式,就是通过修改类的字节码,来实现切面逻辑。目前比较流行的字节码框架是 AspectJ。
代码示例:
public aspect LogAspect {
pointcut addUser(String username, String password) : execution(* addUser(String, String)) && args(username, password);
before(String username, String password) : addUser(username, password) {
System.out.println("开始记录日志");
}
after(String username, String password) : addUser(username, password) {
System.out.println("结束记录日志");
}
}
public interface IUserService {
public void addUser(String username, String password);
}
public class UserServiceImpl implements IUserService{
public void addUser(String username, String password) {
System.out.println("添加用户 " + username + "|" + password);
}
}
public class Client {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
IUserService userService = (IUserService) ctx.getBean("userService");
userService.addUser("lucy", "123456");
}
}
总结
AOP 是一种非常重要的编程思想,可以让我们将公共代码模块化、解耦,从而提高程序的可维护性和可重用性。AOP 的实现方式有两种,基于动态代理的方式和基于字节码增强的方式。我们需要根据具体应用场景,选择合适的实现方式。
以上就是关于 "聊聊Spring——AOP详解(AOP概览)" 的完整攻略。
另外,我再来举一些示例:
示例1:使用AOP实现日志记录
@Component
@Aspect
public class LogAspect {
@Pointcut("execution(public * com.example.demo.controller..*.*(..))")
public void webLog() {
}
@Before("webLog()")
public void doBefore(JoinPoint joinPoint) {
// 处理日志记录逻辑
}
@AfterReturning(returning = "ret", pointcut = "webLog()")
public void doAfterReturning(Object ret) throws Throwable {
// 处理日志记录逻辑
}
}
示例2:使用AOP实现事务管理
@Component
@Aspect
public class TransactionAspect {
@Pointcut("@annotation(com.example.demo.anno.Tranctional)")
public void tranction() {
}
@Before("tranction()")
public void doBefore(JoinPoint joinPoint) {
// 开启数据库事务
}
@AfterReturning("tranction()")
public void doAfterReturning(JoinPoint joinPoint) {
// 提交数据库事务
}
@AfterThrowing("tranction()")
public void doAfterThrowing(JoinPoint joinPoint) {
// 回滚数据库事务
}
}
以上就是两个使用AOP的示例。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:聊聊Spring——AOP详解(AOP概览) - Python技术站