如何建网站做传奇网友,响应式的学校网站,wordpress主题的网站模板,dede网站打不开1. Spring AOP概述
1.1 什么是AOP
AOP#xff08;Aspect-Oriented Programming#xff0c;面向切面编程#xff09;是一种编程范式#xff0c;旨在将横切关注点#xff08;Cross-Cutting Concerns#xff09;从业务逻辑中分离出来。横切关注点是指那些分散在应用程序多…1. Spring AOP概述
1.1 什么是AOP
AOPAspect-Oriented Programming面向切面编程是一种编程范式旨在将横切关注点Cross-Cutting Concerns从业务逻辑中分离出来。横切关注点是指那些分散在应用程序多个模块中的通用功能例如日志记录、事务管理、安全性检查等。AOP通过定义切面Aspect来封装这些关注点从而提高代码的模块化程度和可维护性。
1.2 AOP的作用和应用场景
AOP主要有以下作用和应用场景
日志记录在方法执行前后记录日志。性能监控测量方法执行的时间。事务管理在方法执行前后进行事务的开启和提交/回滚。安全性检查在方法执行前进行权限验证。缓存在方法执行前检查缓存在方法执行后更新缓存。
通过AOP开发者可以在不修改业务代码的情况下灵活地为系统添加上述功能。
2. AOP核心概念
2.1 切面Aspect
切面是AOP的基本单位它封装了横切关注点的定义和实现。在Spring AOP中切面通常是一个类其中包含多个通知Advice和切入点Pointcut。
2.2 通知Advice
通知是指在特定的连接点Join Point执行的代码。通知类型包括
前置通知Before在方法执行之前执行。后置通知After在方法执行之后执行无论方法是否抛出异常。返回通知AfterReturning在方法成功返回结果后执行。异常通知AfterThrowing在方法抛出异常后执行。环绕通知Around在方法执行前后执行并且可以控制方法的执行。
2.3 连接点Join Point
连接点是指程序执行过程中可以插入切面的具体位置。在Spring AOP中连接点通常是方法的执行。
2.4 切入点Pointcut
切入点是指匹配连接点的断言。切入点表达式定义了在哪些连接点上应用通知。
2.5 目标对象Target Object
目标对象是被AOP代理的对象也就是被通知增强的对象。
2.6 织入Weaving
织入是指将切面应用到目标对象并创建代理对象的过程。织入可以在编译时、类加载时和运行时进行。Spring AOP采用的是运行时织入。
3. AOP的两种代理方式
3.1 JDK动态代理
3.1.1 JDK动态代理的原理
JDK动态代理是基于Java的反射机制生成代理类的。在JDK动态代理中代理类必须实现与目标对象相同的接口。通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口可以在运行时创建目标对象的代理对象。
3.1.2 JDK动态代理的实现
以下是一个简单的JDK动态代理实现示例
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;// 接口定义
public interface Service {void perform();
}// 接口实现
public class ServiceImpl implements Service {Overridepublic void perform() {System.out.println(Service is performing);}
}// 代理处理器
public class ServiceInvocationHandler implements InvocationHandler {private Object target;public ServiceInvocationHandler(Object target) {this.target target;}Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {System.out.println(Before method);Object result method.invoke(target, args);System.out.println(After method);return result;}
}// 测试类
public class Main {public static void main(String[] args) {Service target new ServiceImpl();Service proxy (Service) Proxy.newProxyInstance(target.getClass().getClassLoader(),target.getClass().getInterfaces(),new ServiceInvocationHandler(target));proxy.perform();}
}3.2 CGLib动态代理
3.2.1 CGLib动态代理的原理
CGLibCode Generation Library动态代理是基于字节码生成的技术它通过生成目标类的子类来创建代理对象。CGLib代理不需要目标对象实现接口因此适用于那些没有实现接口的类。
3.2.2 CGLib动态代理的实现
以下是一个简单的CGLib动态代理实现示例
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;import java.lang.reflect.Method;// 目标类
public class Service {public void perform() {System.out.println(Service is performing);}
}// 方法拦截器
public class ServiceMethodInterceptor implements MethodInterceptor {Overridepublic Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {System.out.println(Before method);Object result proxy.invokeSuper(obj, args);System.out.println(After method);return result;}
}// 测试类
public class Main {public static void main(String[] args) {Enhancer enhancer new Enhancer();enhancer.setSuperclass(Service.class);enhancer.setCallback(new ServiceMethodInterceptor());Service proxy (Service) enhancer.create();proxy.perform();}
}4. Spring AOP实现原理
4.1 Spring AOP的架构
Spring AOP基于代理模式实现主要包括以下组件
AOP配置用于定义切面和切入点。AOP代理JDK动态代理或CGLib代理用于创建代理对象。通知管理管理通知的执行顺序和逻辑。
4.2 Spring AOP的实现步骤
4.2.1 定义切面和通知
在Spring AOP中可以使用注解或XML配置来定义切面和通知。以下是一个使用注解的示例
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;Aspect
Component
public class LoggingAspect {Before(execution(* com.example.service.*.*(..)))public void logBefore() {System.out.println(Logging before method execution);}
}4.2.2 配置AOP
在Spring Boot中通常通过EnableAspectJAutoProxy注解启用AOP
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;SpringBootApplication
EnableAspectJAutoProxy
public class AopApplication {public static void main(String[] args) {SpringApplication.run(AopApplication.class, args);}
}4.2.3 运行时织入
Spring AOP在运行时将切面织入到目标对象中创建代理对象并添加通知逻辑。
4.3 示例代码
以下是一个完整的Spring AOP示例
// 业务逻辑类
package com.example.service;import org.springframework.stereotype.Service;Service
public class UserService {public void createUser() {System.out.println(Creating user);}
}// 切面类
package com.example.aspect;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;Aspect
Component
public class LoggingAspect {Before(execution(* com.example.service.UserService.*(..)))public void logBefore() {System.out.println(Logging before method execution);}
}// Spring Boot主应用类
package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;SpringBootApplication
EnableAspectJAutoProxy
public class AopApplication {public static void main(String[] args) {SpringApplication.run(AopApplication.class, args);}
}5. 实战案例
5.1 创建Spring Boot项目
首先创建一个新的Spring Boot项目并添加必要的依赖项包括Spring AOP。
dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-aop/artifactId
/dependency5.2 定义业务逻辑
定义一个简单的业务逻辑类例如用户服务类
package com.example.service;import org.springframework.stereotype.Service;Service
public class UserService {public void createUser() {System.out.println(Creating user);}
}5.3 实现和配置AOP
定义一个日志切面类并在其中定义前置通知
package com.example.aspect;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;Aspect
Component
public class LoggingAspect {Before(execution(* com.example.service.UserService.*(..)))public void logBefore() {System.out.println(Logging before method execution);}
}在Spring Boot主应用类中启用AOP
package com.example;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.EnableAspectJAutoProxy;SpringBootApplication
EnableAspectJAutoProxy
public class AopApplication {public static void main(String[] args) {SpringApplication.run(AopApplication.class, args);}
}5.4 验证AOP效果
运行应用程序并调用业务逻辑方法验证日志切面是否正确执行
package com.example;import com.example.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;Component
public class AppRunner implements CommandLineRunner {Autowiredprivate UserService userService;Overridepublic void run(String... args) throws Exception {userService.createUser();}
}控制台输出如下所示
Logging before method execution
Creating user