代理创建器
点击查看代码
package org.springframework.aop.framework.autoproxy;
import org.aopalliance.intercept.MethodInterceptor;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ConfigurationClassPostProcessor;
import org.springframework.context.support.GenericApplicationContext;
import java.util.List;
public class S16 {
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean("s16Aspect", S16Aspect.class);
context.registerBean("s16Config", S16Config.class);
context.registerBean(ConfigurationClassPostProcessor.class);
context.registerBean(AnnotationAwareAspectJAutoProxyCreator.class);
context.refresh();
AnnotationAwareAspectJAutoProxyCreator proxyCreator
= context.getBean(AnnotationAwareAspectJAutoProxyCreator.class);
List<Advisor> advisors = proxyCreator.findEligibleAdvisors(S16Bean1.class, "s16Bean1");
S16Bean1 s16Bean1 = new S16Bean1();
Object o1 = proxyCreator.wrapIfNecessary(s16Bean1, "s16Bean1", "s16Bean1");
Object o2 = proxyCreator.wrapIfNecessary(new S16Bean2(), "s16Bean2", "s16Bean2");
((S16Bean1) o1).s16B();
}
}
class S16Bean1 {
public void s16A() {
System.out.println("s16A running1...");
}
public void s16B() {
System.out.println("s16B running1...");
}
}
class S16Bean2 {
public void s16A2() {
System.out.println("s16A running2...");
}
public void s16B2() {
System.out.println("s16B running2...");
}
}
@Aspect
class S16Aspect{
@Before("execution(* s16B())")
public void s16Advice1() {
System.out.println("s16Advice1 before...");
}
@After("execution(* s16A())")
public void s16Advice2() {
System.out.println("s16Advice2 after...");
}
}
@Configuration
class S16Config {
@Bean("s16Advisor")
public Advisor advisor(MethodInterceptor s16Advice3) {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* s16B())");
return new DefaultPointcutAdvisor(pointcut,s16Advice3);
}
@Bean
public MethodInterceptor s16Advice3() {
return invocation -> {
System.out.println("s16Advice3 before...");
Object result = invocation.proceed();
System.out.println("s16Advice3 after...");
return result;
};
}
}
- AnnotationAwareAspectJAutoProxyCreator 的作用
- 将高级 @Aspect 切面统一为低级 Advisor 切面
- 在合适的时机创建代理
- findEligibleAdvisors 找到有【资格】的 Advisors
- 有【资格】的 Advisor 一部分是低级的, 可以由自己编写, 如本例 S16 中的 advisor3
- 有【资格】的 Advisor 另一部分是高级的, 由解析 @Aspect 后获得
- wrapIfNecessary
- 它内部调用 findEligibleAdvisors, 只要返回集合不空, 则表示需要创建代理
- 它的调用时机通常在原始对象初始化后执行, 但碰到循环依赖会提前至依赖注入之前执行
代理创建时机
点击查看代码
public static void main(String[] args) {
GenericApplicationContext context = new GenericApplicationContext();
context.registerBean(ConfigurationClassPostProcessor.class);
context.registerBean(Config.class);
context.refresh();
context.close();
}
@Configuration
static class Config {
@Bean
public AnnotationAwareAspectJAutoProxyCreator annotationAwareAspectJAutoProxyCreator() {
return new AnnotationAwareAspectJAutoProxyCreator();
}
@Bean
public AutowiredAnnotationBeanPostProcessor autowiredAnnotationBeanPostProcessor() {
return new AutowiredAnnotationBeanPostProcessor();
}
@Bean
public CommonAnnotationBeanPostProcessor commonAnnotationBeanPostProcessor() {
return new CommonAnnotationBeanPostProcessor();
}
@Bean
public Advisor advisor(MethodInterceptor advice) {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* foo())");
return new DefaultPointcutAdvisor(pointcut, advice);
}
@Bean
public MethodInterceptor advice() {
return (MethodInvocation invocation) -> {
System.out.println("before...");
return invocation.proceed();
};
}
@Bean
public Bean1 bean1() {
return new Bean1();
}
@Bean
public Bean2 bean2() {
return new Bean2();
}
}
static class Bean1 {
public void foo() {
}
public Bean1() {
System.out.println("Bean1()");
}
@Autowired public void setBean2(Bean2 bean2) {
System.out.println("Bean1 setBean2(bean2) class is: " + bean2.getClass());
}
@PostConstruct public void init() {
System.out.println("Bean1 init()");
}
}
static class Bean2 {
public Bean2() {
System.out.println("Bean2()");
}
@Autowired public void setBean1(Bean1 bean1) {
System.out.println("Bean2 setBean1(bean1) class is: " + bean1.getClass());
}
@PostConstruct public void init() {
System.out.println("Bean2 init()");
}
}
}
- 代理的创建时机
- 初始化之后 (无循环依赖时)
- 实例创建后, 依赖注入前 (有循环依赖时), 并暂存于二级缓存
- 循环依赖,A 中要依赖注入 B,B 中要注入 A
- 依赖注入与初始化不应该被增强, 仍应被施加于原始对象
- 高级切面利用 @Order 注解可以设置通知的优先级,值越小优先级越高,低级切面可以通过 setOrder 方法来设置值,Order 加在方法和 @Bean 上不生效。
点击查看代码
@Aspect
@Order(2)
class S16Aspect{
@Before("execution(* s16B())")
public void s16Advice1() {
System.out.println("s16Advice1 before...");
}
@After("execution(* s16A())")
public void s16Advice2() {
System.out.println("s16Advice2 after...");
}
}
@Configuration
class S16Config {
@Bean("s16Advisor")
public Advisor advisor(MethodInterceptor s16Advice3) {
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression("execution(* s16B())");
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, s16Advice3);
advisor.setOrder(1);
return advisor;
}
}
@Before 对应的低级通知
点击查看代码
public class S16Test {
public static void main(String[] args) {
SingletonAspectInstanceFactory factory = new SingletonAspectInstanceFactory(new S16Aspect());
List<Advisor> advisors = new ArrayList<>();
Method[] methods = S16Aspect.class.getDeclaredMethods();
for (Method method : methods) {
if (method.isAnnotationPresent(Before.class)) {
String execution = method.getAnnotation(Before.class).value();
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(execution);
AspectJMethodBeforeAdvice advice = new AspectJMethodBeforeAdvice(method, pointcut, factory);
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
advisors.add(advisor);
} else if (method.isAnnotationPresent(After.class)) {
String execution = method.getAnnotation(After.class).value();
AspectJExpressionPointcut pointcut = new AspectJExpressionPointcut();
pointcut.setExpression(execution);
AspectJAfterAdvice advice = new AspectJAfterAdvice(method, pointcut, factory);
DefaultPointcutAdvisor advisor = new DefaultPointcutAdvisor(pointcut, advice);
advisors.add(advisor);
}
}
for (Advisor advisor : advisors) {
System.out.println(advisor);
}
}
@Order(2)
@Aspect
static class S16Aspect {
@Before("execution(* s16B())")
public void s16Advice1() {
System.out.println("s16Advice1 before...");
}
@After("execution(* s16A())")
public void s16Advice2() {
System.out.println("s16Advice2 after...");
}
}
static class S16Bean1 {
public void s16A() {
System.out.println("s16A running1...");
}
public void s16B() {
System.out.println("s16B running1...");
}
}
static class S16Bean2 {
public void s16A2() {
System.out.println("s16A running2...");
}
public void s16B2() {
System.out.println("s16B running2...");
}
}
}
- @Before 前置通知会被转换为原始的 AspectJMethodBeforeAdvice 形式, 该对象包含了如下信息
- 通知代码从哪儿来
- 切点是什么(这里为啥要切点, 后面解释)
- 通知对象如何创建, 本例共用同一个 Aspect 对象
- 类似的还有
- AspectJAroundAdvice (环绕通知)
- AspectJAfterReturningAdvice(返回后通知)
- AspectJAfterThrowingAdvice (异常通知)
- AspectJAfterAdvice (后置通知)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)