zoukankan      html  css  js  c++  java
  • 搞懂aop二(自动代理基础)

    自动代理抽象:

    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判断是否需要产生代理

  • 相关阅读:
    使用ViewPager实现三个fragment切换
    handler
    Android 源码解析之AsyncTask
    android的生命周期
    安卓在SQLiteOpenHelper类进行版本升级和降级
    安卓ListView操作的两种方法
    表格布局TableLayout
    线性布局和相对布局
    遇到tomcat端口被占用问题解决方案
    easyUI笔记09.03
  • 原文地址:https://www.cnblogs.com/mao-yan/p/13533564.html
Copyright © 2011-2022 走看看