目录
3.1.3、Spring AOP与Spring事务管理的关系,如何结合使用
1、Spring AOP介绍
AOP思想是基于代理模式, 因为Java中一般采用JDK动态代理模式,由于Spring同时支持CGLIB、AspectJ、JDK动态代理,但是JDK动态代理只能 代理接口不能代理类,所以Spring会这样子进行切换:
(1)如果目标对象的实现类实现了接口,则直接采用JDK动态代理生成AOP代理类;
(2)如果目标对象类没有实现接口,SpringAOP则会采用CGLIB来生成AOP代理类。
1.1、什么是AOP
AOP,即面向切面编程。允许通过分离应用的业务逻辑与系统级服务(如审计、日志、权限校验、事物管理)进行内聚性的开发——原理就是使用代理模式。应用对象只实现它们应该做的事情,完成业务逻辑。
1.2、AOP与面向对象编程(OOP)区别
(1)关注点不同
OOP更关注于对象的行为和交互,通常将数据和行为封装在对象中,实现模块化和可重用;
AOP关注横切点,例如日志记录、事物管理、安全检查等,可能涉及多个对象而不是单个对象
(2)实现方式不同
OOP通过继承、多态等实现模块化和可重用;
AOP通过切面、通知、切点将横切关注点从业务逻辑抽离出来
1.3、静态代理介绍(类的代理)
1.3.1、什么是AspectJ
也称编译时增强,AOP框架在编译阶段生成AOP代理类,并将AspectJ切面织入java字节码,运行之后就是增强后的AOP对象了。
1.3.2、Spring AOP与AspectJ区别
(1)实现方式不同
AOP基于代理机制实现对目标方法的拦截和增强;AspectJ是一个独立的AOP框,对目标类进行字节码级别的增强。
(2)功能和灵活性不同
AOP较简单,只支持一部分AspectJ的功能,比如切点表达式;AspectJ更强大粒度更细
1.4、动态代理介绍
1.4.1、JDK动态代理(接口代理)
JDK代理只支持接口代理不支持类代理,要求被代理对象实现接口。
JDK代理核心是InvocationHandler接口和 Proxy代理类,在获取代理对象时使用Proxy类来动态创建目标类的代理类,当代理对象调用真实对象的方法时,InvocationHandler通过invoke()方法反射来调用目标类中的代码,动态将横切逻辑和业务编织在一起。
1.4.2、CGLIB动态代理(继承代理)
也称运行时增强,如果代理类没有实现接口,AOP会选择CGLIB代理。它可以在运行时生成指定类的一个子类对象,并覆盖区中特定方法并添加增强代码。是通过继承的方式实现的代理,所以某个类被标记为final,则无法使用CGLIB做代理。
1.5、AOP基本概念
1.5.1、通知(五种类型)
通知是在切点上执行的动作。
-
Before
(无条件 前置通知) -
After
(无条件 后置通知) -
After-returning
(方法成功 后置通知) -
After-throwing
(方法抛异常 后置通知) -
Around
(方法前后 环绕通知)
1.5.2、切点(连接点的集合)
对应系统中的方法(定义在切面中的方法),和通知一起使用组成切面。
可以用@Pointcut注解定义切点,使用execution关键字来匹配方法的执行,使用@annotation来匹配带有特定注解的方法。
@Pointcut("execution(* com.example.service.*.*(..))")
private void serviceMethods() {}
@Before("serviceMethods()") // 匹配带有特定注解的方法
public void doSomethingBeforeServiceMethods() {}
1.5.3、连接点
程序执行过程中能够被拦截的特定点。比如方法调用、执行(a.b())、方法执行字段设置/获取(a.set())等。
1.5.4、切面(切点+通知的集合)
一般单独作为一个类。
如何定义一个切面?-使用@Aspect注解
@Aspect
@Component
public class LoggingAspect {
@Pointcut("execution(* com.example.service.*.*(..))")
private void serviceMethods() {}
@Before("serviceMethods()")
public void logBeforeServiceMethods() {
System.out.println("Logging before executing service methods");
}
}
描述: 在上面的示例中,@Aspect注解用于标记LoggingAspect类为一个切面。@Pointcut注解定义了一个切点serviceMethods(),它使用切点表达式来匹配com.example.service包下的所有方法。然后使用@Before注解来指定在`serviceMethods`切点匹配的方法执行之前执行的逻辑,即logBeforeServiceMethods()方法。
1.5.5、引入
是AOP的一个功能。允许向现有类添加新的方法或者属性,扩展功能。允许 在不修改现有类代码情况下向类中添加新的行为。
1.5.6、织入
将切面的行为应用到目标对象的过程。是AOP实现切面的核心步骤。
2、Spring IOC介绍
2.1、Spring IOC是什么
IOC指的是控制翻转。指将程序的控制权转移给Spring,由Spring来控制对象的生命周期(如创建和销毁)和对象的依赖关系
2.2、什么是DI
DI是IOC的一种具体实现,指的是依赖注入。即将对象之间的依赖关系由容器来注入,依赖注入使得对象之间的依赖关系更加灵活。
2.3、依赖注入的3种方式
2.3.1、注解注入
如@Autowired、@Resource
@Autowired、@Resource区别?
(1)父类不同:@Autowired是Spring提供的注解,@Resource是java EE提供的,更通用;
(2)依赖查找顺序不同(@Autowired-先类型,@Resource先名称)
@Autowired先根据类型(byType)查找,如果存在多个 Bean 再根据名称(byName)进行查找。@Resource 相反。
2.3.2、构造器注入
通过构造函数注入依赖
private UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
}
2.3.3、setter注入
如实体的setter方法
3、常见问题
3.1、AOP
3.1.1、Spring AOP的工作原理
Spring AOP的工作原理是通过动态代理模式来实现对目标对象的增强,目标对象的实现类实现了接口,则直接采用JDK动态代理,没有实现接口使用CGLIB动态代理。
如果这个Bean被代理了,Spring容器就会为这个Bean创建一个代理对象,代理对象中包含了增强的逻辑。当调用代理对象的方法时,增强逻辑会被织入到目标对象的方法执行前、执行后或者抛出异常时 等时机执行,从而实现对目标对象的增强。
3.1.2、Spring AOP如何实现对目标对象的增强
(1)定义切点
通过切点表达式定义在目标对象的哪些连接点上应用切面的逻辑。
(2)编写通知
通知是切面中的具体逻辑,包括前置通知、后置通知、环绕通知等,用于在切点处执行相应的增强逻辑。
(3)创建切面(类)
切面是包含了切点和通知的模块,它定义了在哪些连接点上执行哪些通知。
(4)使用代理机制
Spring使用代理机制来织入切面的逻辑到目标对象的方法中。代理机制包括JDK动态代理和CGLIB代理两种方式。
3.1.3、Spring AOP与Spring事务管理的关系,如何结合使用
(1)事务管理通知
AOP中的通知,可以在方法执行前或执行后开启、提交、回滚事务
(2)结合声明式事务 \ 编程式事物管理
使用@Transactional注解可以在业务方法执行时自动开启、提交、回滚事务,无需在业务逻辑中显式管理事务。也可编程式事物,手动控制事务的开启、提交、回滚。
3.1.4、Spring AOP应用场景
日志记录、性能监控、安全控制、事物管理、异常处理