1. 程式人生 > 實用技巧 >搞懂aop二(自動代理基礎)

搞懂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判斷是否需要產生代理