码迷,mamicode.com
首页 > 其他好文 > 详细

搞懂aop二(自动代理基础)

时间:2020-08-25 15:59:43      阅读:55      评论:0      收藏:0      [点我收藏+]

标签:handle   子接口   过程   代理   div   ||   closed   turn   ast   

自动代理抽象:

public abstract class AbstractAutoProxyCreator extends ProxyProcessorSupport implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware

 这个利用spring 后置处理器来拦截bean创建,在bean的创建过程中,可以通过spring的后置处理器来处理bean的创建过程,SmartInstantiationAwareBeanPostProcessor是InstantiationAwareBeanPostProcessor BeanPostProcessor 的子接口,它的实现类有机会被spring在创建bean实例前后,实例化前后执行指定的方法。

技术图片
@Override
// bean 实例化前的拦截器
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
    Object cacheKey = getCacheKey(beanClass, beanName);

    if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
        if (this.advisedBeans.containsKey(cacheKey)) {
            return null;
        }
        if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
            this.advisedBeans.put(cacheKey, Boolean.FALSE);
            return null;
        }
    }

    // Create proxy here if we have a custom TargetSource.
    // Suppresses unnecessary default instantiation of the target bean:
    // The TargetSource will handle target instances in a custom fashion.
    TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
    if (targetSource != null) {
        if (StringUtils.hasLength(beanName)) {
            this.targetSourcedBeans.add(beanName);
        }
        Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
        Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
        this.proxyTypes.put(cacheKey, proxy.getClass());
        return proxy;
    }

    return null;
}


@Override
// 初始化后的拦截器,可以返回一个新对象代替初始化后的对象
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
    if (bean != null) {
        Object cacheKey = getCacheKey(bean.getClass(), beanName);
        // 这个是判断是否已经被代理过
        if (this.earlyProxyReferences.remove(cacheKey) != bean) {
            // 这个是判断是否需要包装,并返回结果的方法
            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;
    }
    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;
}
自动代理抽象的部分源码

 

使用示例:

技术图片
/**
 * @author liangjunhui
 * @date Created in 2020-08-20 9:09
 */
@Configuration
public class MyBeanNameApc {
    @Bean
    public MethodBeforeAdvice methodBeforeAdvice(){
        MethodBeforeAdvice beforeAdvice = (method, args, target) -> System.out.println("前置增强");
        return beforeAdvice;
    }
    @Bean
    public BeanNameAutoProxyCreator beanNameAutoProxyCreator(){
        BeanNameAutoProxyCreator creator = new BeanNameAutoProxyCreator();
        creator.setBeanNames("*ultar");
        creator.setInterceptorNames("methodBeforeAdvice");
        return creator;
    }
    @Bean
    public Mathcalcultar mathcalcultar(){
        return new Mathcalcultar();
    }

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyBeanNameApc.class);
        Mathcalcultar bean = context.getBean(Mathcalcultar.class);
        bean.div(1,1);
    }
}
MyBeanNameApc

1、将AbstractAutoProxyCreator实例注入到容器,这个实例会拦截bean的创建

2、然后看AbstractAutoProxyCreator#getAdvicesAndAdvisorsForBean在子类的实现,按照子类的匹配规则设置一些数据来,然后apc判断是否需要产生代理

 

搞懂aop二(自动代理基础)

标签:handle   子接口   过程   代理   div   ||   closed   turn   ast   

原文地址:https://www.cnblogs.com/mao-yan/p/13533564.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!