• Spring AOP代理对象创建流程


    Spring AOP初始化的起点是在bean初始化流程后置处理中。

    /**
    * bean的初始化流程
    */
    protected Object initializeBean(final String beanName, final Object bean, @Nullable RootBeanDefinition mbd) {
    if (System.getSecurityManager() != null) {
    AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
    invokeAwareMethods(beanName, bean);
    return null;
    }, getAccessControlContext());
    }
    else {
    // 为bean包装相关属性,如名称、类加载器、所属容器等
    invokeAwareMethods(beanName, bean);
    }

    Object wrappedBean = bean;
    if (mbd == null || !mbd.isSynthetic()) {
    // 调用BeanPostProcessor的postProcessBeforeInitialization前置处理方法
    wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    }

    try {
    // 执行bean初始化方法
    invokeInitMethods(beanName, wrappedBean, mbd);
    }
    catch (Throwable ex) {
    throw new BeanCreationException(
    (mbd != null ? mbd.getResourceDescription() : null),
    beanName, "Invocation of init method failed", ex);
    }
    if (mbd == null || !mbd.isSynthetic()) {
    // 调用BeanPostProcessor的postProcessAfterInitialization后置处理方法
    wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
    }

    return wrappedBean;
    }
    applyBeanPostProcessorsAfterInitialization方法调用了BeanPostProcessor的postProcessAfterInitialization后置处理方法

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

    Object result = existingBean;
    // 为Bean添加所有BeanPostProcessor的后置处理器
    for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    Object current = beanProcessor.postProcessAfterInitialization(result, beanName);
    if (current == null) {
    return result;
    }
    result = current;
    }
    return result;
    }
    BeanPostProcessor的bean初始化前置处理和初始化后置处理方法均委派其子类实现,其实现子类有很多,其中创建AOP代理对象的子类是AbstractAutoProxyCreator,它实现了postProcessAfterInitialization方法。

    下面具体可以分析一下AbstractAutoProxyCreator类的postProcessAfterInitialization方法。

    @Override
    public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
    if (bean != null) {
    // 根据给定的bean的class和name构建一个key
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    // 如果它适合被代理,则需要封装指定的bean
    if (!this.earlyProxyReferences.contains(cacheKey)) {
    return 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;
    }
    // 无需增强
    if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
    return bean;
    }
    // 判断是否是基础设施类,或者是否配置了无需自动代理。如果是,缓存key并直接返回
    if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
    }

    // Create proxy if we have advice.
    // 如果存在增强方法则创建代理
    Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    if (specificInterceptors != DO_NOT_PROXY) {
    this.advisedBeans.put(cacheKey, Boolean.TRUE);
    // 创建代理
    Object proxy = createProxy(
    bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    this.proxyTypes.put(cacheKey, proxy.getClass());
    return proxy;
    }

    this.advisedBeans.put(cacheKey, Boolean.FALSE);
    return bean;
    }
    protected Object createProxy(Class<?> beanClass, @Nullable String beanName,
    @Nullable Object[] specificInterceptors, TargetSource targetSource) {

    ......

    return proxyFactory.getProxy(getProxyClassLoader());
    }


    通过上图可以看到,创建代理对象Spring提供了两种方式,JDK动态代理和Cglib AOP代理。

    进入createAopProxy()方法,发现这个方法最终在DefaultAopProxyFactory类中被实现。

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
    // isOptimize:用来控制通过CGLIB创建的代理是否使用激进的优化策略
    // isProxyTargetClass:为true时,目标类本身被代理而不是目标类的接口,即使用CGLIB创建代理
    // hasNoUserSuppliedProxyInterfaces:是否存在代理接口
    if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
    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.");
    }
    // 如果是接口或是一个代理对象就要jdk动态代理
    if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
    return new JdkDynamicAopProxy(config);
    }
    return new ObjenesisCglibAopProxy(config);
    }
    else {
    return new JdkDynamicAopProxy(config);
    }
    }
    如果目标对象实现了接口,默认情况下会采用JDK动态代理,但也可以通过配置(proxy-target-class=true)强制使用CGLIB。

    如果目标对象没有实现接口,必须采用CGLIB库。

    JdkDynamicAopProxy类实现了InvocationHandler接口,我们知道InvocationHandler是JDK动态代理的核心,生成的代理对象的方法调用都会委派到invoke()方法中。

    JdkDynamicAopProxy的invoke()方法的核心逻辑为:

    先获取应用到目标方法上的拦截器链(Interceptor Chain),如果有拦截器则应用拦截器(before、after、afterReturning等),并执行连接点(JoinPoint)。如果没有拦截器,则直接反射执行连接点。

    JDK动态代理与CGLIB的区别:

    JDK动态代理只能对实现了接口的类生成代理,不能针对类。

    CGLIB是针对类实现代理,主要是对指定的类生成一个子类,覆盖其中的方法,所以该类和方法要保证可以被继承与覆盖。
    ————————————————
    版权声明:本文为CSDN博主「KeepMoving++」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/u011212394/java/article/details/101795460

  • 相关阅读:
    图像全參考客观评价算法比較
    单片机project师必备的知识
    ACM-并查集之小希的迷宫——hdu1272
    ArcGIS教程:加权总和
    九度 题目1368:二叉树中和为某一值的路径
    解决solr搜索多词匹配度和排序方案
    具体解释linux文件处理的的经常使用命令
    Hotel
    Unity3D 射线指定层获取GameObject 注意 LayerMask
    ios设计一部WindowsPhone手机
  • 原文地址:https://www.cnblogs.com/sidesky/p/12718658.html
Copyright © 2020-2023  润新知