Spring AOP 大概原理

Spring AOP

Spring AOP到底是怎么实现的,是在哪里进行代理的呢,这篇文章就来初步了解一下吧

以注解的方式为例

先来以代码实现AOP代理

被代理的类

interface TargetInterface {
	void selectall();
}
// 这里使用了实现接口的方式,所以会走 jdk动态代理
public class Target implements TargetInterface {
   public void selectall(){
      System.out.println("方法被执行了");
   }
}

代理切面AOP

@Aspect
public class Aspect {
	/**
	 * 使用切入点表达式
	 */
	@Pointcut("execution(* selectall(..))")
	public void select(){}
     /**
     * 前置增强
	 */
	@Before("execution(* selectall(..))")
	public void beforeEnhance(JoinPoint joinpoint) {
		System.out.println("前置增强执行-------");
	}
    /**
     * 后置增强
	 */
    @AfterReturning("select()")
	public void afterReturnEnhance(JoinPoint joinPoint){
		System.out.println("后置增强执行------");
	}
}

启动类

@ComponentScan("com.aop")
@EnableAspectJAutoProxy
@Import({AopAspect.class})
public class AopApplication {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(AopApplication.class);
        TargetInterface target = context.getBean("target", TargetInterface.class);
        target.selectall();
    }
    @Bean
    public TargetInterface target(){
        return new Target();
    }
}

代码解读

从上面代码中看到,我们使用了@EnableAspectJAutoProxy开启AOP,看看这个注解的作用@Import({AspectJAutoProxyRegistrar.class})

class AspectJAutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    AspectJAutoProxyRegistrar() {
    }
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        AopConfigUtils.registerAspectJAnnotationAutoProxyCreatorIfNecessary(registry);
        AnnotationAttributes enableAspectJAutoProxy = AnnotationConfigUtils.attributesFor(importingClassMetadata, EnableAspectJAutoProxy.class);
        if (enableAspectJAutoProxy != null) {
            if (enableAspectJAutoProxy.getBoolean("proxyTargetClass")) {
                AopConfigUtils.forceAutoProxyCreatorToUseClassProxying(registry);
            }

            if (enableAspectJAutoProxy.getBoolean("exposeProxy")) {
                AopConfigUtils.forceAutoProxyCreatorToExposeProxy(registry);
            }
        }
    }
}

可以看出实现了ImportBeanDefinitionRegister,这个接口的作用就是可以手动的向BeanDefinitionRegistry注册一个bean定义信息

registerOrEscalateApcAsRequired(AnnotationAwareAspectJAutoProxyCreator.class, registry, source);
///=======================
RootBeanDefinition beanDefinition = new RootBeanDefinition(cls); // cls = AnnotationAwareAspectJAutoProxyCreator.class
beanDefinition.setSource(source);
beanDefinition.getPropertyValues().add("order", -2147483648);
beanDefinition.setRole(2);
registry.registerBeanDefinition("org.springframework.aop.config.internalAutoProxyCreator", beanDefinition);
return beanDefinition;

定义了一个名字org.springframework.aop.config.internalAutoProxyCreatorAnnotationAwareAspectJAutoProxyCreator.classbean

AnnotationAwareAspectJAutoProxyCreator

AnnotationAwareAspectJAutoProxyCreator 父类关系图

主要看看注册的这个bean是不是实现了BeanPostProcesor,所以会怎么样,当执行初始化方法的前后是不是会执行扩展处理,即postProcessBeforeInitialization()前置处理和postProcessAfterInitialization后置处理

我们在这个类中找是找不到这两个方法的,我们往父类上找,直到AbstractAutoProxyCreator才找到了postProcessAfterInitialization

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware {
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
        if (bean != null) {
            Object cacheKey = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return this.wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }
    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
        if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
            return bean;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return bean;
        }
    }
}

在wrapIfNecessary()进行代理如果需要的话。重点的看这行Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));

这句话的语义也能看得出来,他就是去创建代理的,返回的也是一个代理类

最后调用到了 ProxyFactory 的getProxy()方法中去获取代理类

public class ProxyFactory extends ProxyCreatorSupport {
    public Object getProxy(@Nullable ClassLoader classLoader) {
        return this.createAopProxy().getProxy(classLoader);
    }
}

在createAopProxy()中去获取Aop代理时就已经判断需要什么样的类型 AopProxy

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {
    public DefaultAopProxyFactory() {
    }

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (NativeDetector.inNativeImage() || !config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            Class<?> targetClass = config.getTargetClass();
            if (targetClass == null) {
                throw new AopConfigException("TargetSource cannot determine target class: Either an interface or a target is required for proxy creation.");
            } else {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }
}

要么返回 new JdkDynamicAopProxy(config); 要么返回 new ObjenesisCglibAopProxy(config)

我们知道 Cglib 不需要实现接口,所以!targetClass.isInterface()时就返回Cglib代理

如果代理类是接口,那么就返回jdk代理

然后回到ProxyFactory的getProxy(),根据返回来的jdk代理还是cglib代理去进行代理得到代理类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值