为了账号安全,请及时绑定邮箱和手机立即绑定

Spring AOP 处理流程

标签:
Spring

我们今天来聊一下Spring的AOP,我们从AnnotationAwareAspectJAutoProxyCreator开始说起。他是一个InstantiationAwareBeanPostProcessor所以我们需要看一下他的生命周期方法postProcessBeforeInstantiationpostProcessAfterInitialization,这两个是有具体处理逻辑的。首先我们看一下postProcessBeforeInstantiation

@Override
    public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {        Object cacheKey = getCacheKey(beanClass, beanName);        if (beanName == null || !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.
        if (beanName != null) {
            TargetSource targetSource = getCustomTargetSource(beanClass, beanName);            if (targetSource != null) {                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;
    }

根据beanClassbeanName创建cacheKey.如果beanName为空,并且targetSourcedBeans里面不包含此beanName进入下面的流程,如果advisedBeans包含了这个cacheKey直接返回,另外就是判断他是否是一个基础设施类(isInfrastructureClass)和是否应该跳过(shouldSkip)。首先我们看下基础设施类的判断

protected boolean isInfrastructureClass(Class<?> beanClass) {
        boolean retVal = Advice.class.isAssignableFrom(beanClass) ||
                Advisor.class.isAssignableFrom(beanClass) ||
                AopInfrastructureBean.class.isAssignableFrom(beanClass);        if (retVal && logger.isTraceEnabled()) {
            logger.trace("Did not attempt to auto-proxy infrastructure class [" + beanClass.getName() + "]");
        }        return retVal;
    }

如果beanClass是AdviceAdvisorAopInfrastructureBean是他们的中的一种,那么就是基础设施类。我们再看下shouldSkip

@Override
    protected boolean shouldSkip(Class<?> beanClass, String beanName) {        // TODO: Consider optimization by caching the list of the aspect names
        List<Advisor> candidateAdvisors = findCandidateAdvisors(); //关注点1
        for (Advisor advisor : candidateAdvisors) {            if (advisor instanceof AspectJPointcutAdvisor) {                if (((AbstractAspectJAdvice) advisor.getAdvice()).getAspectName().equals(beanName)) {                    return true;
                }
            }
        }        return super.shouldSkip(beanClass, beanName);
    }

里面有一个重要的方法,寻找候选的Advisors,这个方法的具体实现是org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors

@Override
    protected List<Advisor> findCandidateAdvisors() {        // Add all the Spring advisors found according to superclass rules.
        List<Advisor> advisors = super.findCandidateAdvisors();        // Build Advisors for all AspectJ aspects in the bean factory.
        advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());        return advisors;
    }

这个方法返回的数据分为两部分,第一部分是super.findCandidateAdvisors(),第二部分是this.aspectJAdvisorsBuilder.buildAspectJAdvisors()。我们一个个的说,第一部分是获取spring容器中的Advisor类型的Bean的实例。

public List<Advisor> findAdvisorBeans() {        // Determine list of advisor bean names, if not cached already.
        String[] advisorNames = null;        synchronized (this) {
            advisorNames = this.cachedAdvisorBeanNames;            if (advisorNames == null) {                // Do not initialize FactoryBeans here: We need to leave all regular beans
                // uninitialized to let the auto-proxy creator apply to them!
                advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(                        this.beanFactory, Advisor.class, true, false);                this.cachedAdvisorBeanNames = advisorNames;
            }
        }        if (advisorNames.length == 0) {            return new LinkedList<Advisor>();
        }

        List<Advisor> advisors = new LinkedList<Advisor>();        for (String name : advisorNames) {            if (isEligibleBean(name)) {                if (this.beanFactory.isCurrentlyInCreation(name)) {                    if (logger.isDebugEnabled()) {
                        logger.debug("Skipping currently created advisor '" + name + "'");
                    }
                }                else {                    try {
                        advisors.add(this.beanFactory.getBean(name, Advisor.class));
                    }                    catch (BeanCreationException ex) {
                        Throwable rootCause = ex.getMostSpecificCause();                        if (rootCause instanceof BeanCurrentlyInCreationException) {
                            BeanCreationException bce = (BeanCreationException) rootCause;                            if (this.beanFactory.isCurrentlyInCreation(bce.getBeanName())) {                                if (logger.isDebugEnabled()) {
                                    logger.debug("Skipping advisor '" + name +                                            "' with dependency on currently created bean: " + ex.getMessage());
                                }                                // Ignore: indicates a reference back to the bean we're trying to advise.
                                // We want to find advisors other than the currently created bean itself.
                                continue;
                            }
                        }                        throw ex;
                    }
                }
            }
        }        return advisors;
    }

整体的流程是通过BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Advisor.class, true, false)获取到所有的Advisor类型的Bean的名称,如果名称的列表为空,返回空的列表,如果不为空,遍历名称,得到对应的Bean,添加到列表中,返回列表,第一部分到此结束,我们说下第二部分,也是我们应该格外关注的this.aspectJAdvisorsBuilder.buildAspectJAdvisors()

public List<Advisor> buildAspectJAdvisors() {
        List<String> aspectNames = null;

        synchronized (this) {
            aspectNames = this.aspectBeanNames;            if (aspectNames == null) {
                List<Advisor> advisors = new LinkedList<Advisor>();
                aspectNames = new LinkedList<String>();                String[] beanNames =
                        BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false);                for (String beanName : beanNames) {                    if (!isEligibleBean(beanName)) {                        continue;
                    }                    // We must be careful not to instantiate beans eagerly as in this
                    // case they would be cached by the Spring container but would not
                    // have been weaved
                    Class<?> beanType = this.beanFactory.getType(beanName);                    if (beanType == null) {                        continue;
                    }                    if (this.advisorFactory.isAspect(beanType)) {
                        aspectNames.add(beanName);
                        AspectMetadata amd = new AspectMetadata(beanType, beanName);                        if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
                            MetadataAwareAspectInstanceFactory factory =                                    new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
                            List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);                            if (this.beanFactory.isSingleton(beanName)) {                                this.advisorsCache.put(beanName, classAdvisors);
                            }                            else {                                this.aspectFactoryCache.put(beanName, factory);
                            }
                            advisors.addAll(classAdvisors);
                        }                        else {                            // Per target or per this.
                            if (this.beanFactory.isSingleton(beanName)) {                                throw new IllegalArgumentException("Bean with name '" + beanName +                                        "' is a singleton, but aspect instantiation model is not singleton");
                            }
                            MetadataAwareAspectInstanceFactory factory =                                    new PrototypeAspectInstanceFactory(this.beanFactory, beanName);                            this.aspectFactoryCache.put(beanName, factory);
                            advisors.addAll(this.advisorFactory.getAdvisors(factory));
                        }
                    }
                }                this.aspectBeanNames = aspectNames;                return advisors;
            }
        }        if (aspectNames.isEmpty()) {            return Collections.emptyList();
        }
        List<Advisor> advisors = new LinkedList<Advisor>();        for (String aspectName : aspectNames) {
            List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);            if (cachedAdvisors != null) {
                advisors.addAll(cachedAdvisors);
            }            else {
                MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
                advisors.addAll(this.advisorFactory.getAdvisors(factory));
            }
        }        return advisors;
    }

思路差不多,通过BeanFactoryUtils.beanNamesForTypeIncludingAncestors(this.beanFactory, Object.class, true, false)获取到容器中的所有的Bean的名称,是个列表,遍历列表,根据每个Bean的名称,获取对应的Bean的类型,根据beanType判断是否是切面this.advisorFactory.isAspect(beanType)

@Override
    public boolean isAspect(Class<?> clazz) {        return (hasAspectAnnotation(clazz) && !compiledByAjc(clazz));
    }    private boolean hasAspectAnnotation(Class<?> clazz) {        return (AnnotationUtils.findAnnotation(clazz, Aspect.class) != null);
    }    /**
     * We need to detect this as "code-style" AspectJ aspects should not be
     * interpreted by Spring AOP.
     */
    private boolean compiledByAjc(Class<?> clazz) {        // The AJTypeSystem goes to great lengths to provide a uniform appearance between code-style and
        // annotation-style aspects. Therefore there is no 'clean' way to tell them apart. Here we rely on
        // an implementation detail of the AspectJ compiler.
        for (Field field : clazz.getDeclaredFields()) {            if (field.getName().startsWith(AJC_MAGIC)) {                return true;
            }
        }        return false;
    }

判断的条件很简单,这个类必须有@Aspect这个注解,并且没有被AspectJ编译过,判断的条件就是这个类中所有的属性,不能是“ajc$”开头。通过这两个判断我们找到了切面类,将这个beanName放入到了aspectNames中缓存。随后根据beanType和beanName创建了AspectMetadata的实例,一般我们不是使用@Aspectj注解的value,所以amd.getAjType().getPerClause().getKind()一般是PerClauseKind.SINGLETON这段代码和本讲无关,所有没有深入讲解,有兴趣的同学可以自己查看。然后进入下面的流程,根据beanFactory和beanName创建了一个MetadataAwareAspectInstanceFactory的实例factory,通过List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory)获取Advisor列表。可以看一下org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors的源码

@Override
    public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
        Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
        String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();
        validate(aspectClass);        // We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
        // so that it will only instantiate once.
        MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =                new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);

        List<Advisor> advisors = new LinkedList<Advisor>();        //关注点2
        for (Method method : getAdvisorMethods(aspectClass)) {
            Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);            if (advisor != null) {
                advisors.add(advisor);
            }
        }        // If it's a per target aspect, emit the dummy instantiating aspect.
        if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
            Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
            advisors.add(0, instantiationAdvisor);
        }        // Find introduction fields.
        for (Field field : aspectClass.getDeclaredFields()) {
            Advisor advisor = getDeclareParentsAdvisor(field);            if (advisor != null) {
                advisors.add(advisor);
            }
        }        return advisors;
    }

看一下关注点2,根据aspectClass获取这个类中的AdvisorMethod

private List<Method> getAdvisorMethods(Class<?> aspectClass) {        final List<Method> methods = new LinkedList<Method>();
        ReflectionUtils.doWithMethods(aspectClass, new ReflectionUtils.MethodCallback() {            @Override
            public void doWith(Method method) throws IllegalArgumentException {                // Exclude pointcuts
                if (AnnotationUtils.getAnnotation(method, Pointcut.class) == null) {
                    methods.add(method);
                }
            }
        });
        Collections.sort(methods, METHOD_COMPARATOR);        return methods;
    }

获取这个类上带有@Pointcut注解的方法,并且排序。通过Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName)将带有@Pointcut注解的方法变成Advisor类型的实例,放入advisors这个集合中。方法可以变成Advisor类型的实例,属性也可以,如果属性上有@DeclareParents注解,根据此注解生成DeclareParentsAdvisor类型的实例,添加到advisors这个集合中返回。OK,this.advisorFactory.getAdvisors(factory)这个方法解释的差不多了,随后在将beanName和查到的这些List<Advisor>放入到advisorsCache这个Map中缓存。遍历结束后,将查到的所有的advisors返回,这是我们shouldSkip的关键流程--查询Advisors。再继续,如果beanName不为空,并且getCustomTargetSource(beanClass, beanName)得到的targetSource不为空,就会添加这个beanName到targetSourcedBeans这个Set中缓存,接下来有一个非常重要的方法getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource)根据指定的条件获取Advisors,也就是拦截器。我们看下他是怎么获取这些拦截器的。

    @Override    protected Object[] getAdvicesAndAdvisorsForBean(Class<?> beanClass, String beanName, TargetSource targetSource) {        List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);        if (advisors.isEmpty()) {            return DO_NOT_PROXY;
        }        return advisors.toArray();
    }    protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {        List<Advisor> candidateAdvisors = findCandidateAdvisors();        List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
        extendAdvisors(eligibleAdvisors);        if (!eligibleAdvisors.isEmpty()) {
            eligibleAdvisors = sortAdvisors(eligibleAdvisors);
        }        return eligibleAdvisors;
    }

我们看到了一个熟悉的方法findCandidateAdvisors获取所有的Advisors,但是我们不知道这个BeanClass会用到哪些Advisors或者都用不到,就需要一个挑选的过程,这个挑选的过程就是findAdvisorsThatCanApply方法

    protected List<Advisor> findAdvisorsThatCanApply(            List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {

        ProxyCreationContext.setCurrentProxiedBeanName(beanName);        try {            return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
        }        finally {
            ProxyCreationContext.setCurrentProxiedBeanName(null);
        }
    }    
    public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {        if (candidateAdvisors.isEmpty()) {            return candidateAdvisors;
        }        List<Advisor> eligibleAdvisors = new LinkedList<Advisor>();        for (Advisor candidate : candidateAdvisors) {            if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {
                eligibleAdvisors.add(candidate);
            }
        }
        boolean hasIntroductions = !eligibleAdvisors.isEmpty();        for (Advisor candidate : candidateAdvisors) {            if (candidate instanceof IntroductionAdvisor) {                // already processed
                continue;
            }            if (canApply(candidate, clazz, hasIntroductions)) {
                eligibleAdvisors.add(candidate);
            }
        }        return eligibleAdvisors;
    }

整体来说,挑选的方法集中在了canApply,所做的操作就是根据@Pointcut注解中value定义的格式,来匹配这个Bean,看能不能匹配上,能匹配上就是canApply.然后返回针对这个BeanClass能匹配上的Advisor。OK,那么Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource)的结果就是找到了这个类对应应该执行的Advisor,最后就是将这个类和这些Advisor包装成一个动态代理对象返回,也就是Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource)

    protected Object createProxy(
            Class<?> beanClass, String beanName, Object[] specificInterceptors, TargetSource targetSource) {        if (this.beanFactory instanceof ConfigurableListableBeanFactory) {
            AutoProxyUtils.exposeTargetClass((ConfigurableListableBeanFactory) this.beanFactory, beanName, beanClass);
        }

        ProxyFactory proxyFactory = new ProxyFactory();
        proxyFactory.copyFrom(this);        if (!proxyFactory.isProxyTargetClass()) {            if (shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            }            else {
                evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }

        Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);        for (Advisor advisor : advisors) {
            proxyFactory.addAdvisor(advisor);
        }

        proxyFactory.setTargetSource(targetSource);
        customizeProxyFactory(proxyFactory);

        proxyFactory.setFrozen(this.freezeProxy);        if (advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }        return proxyFactory.getProxy(getProxyClassLoader());
    }

创建一个proxyFactory,往其中添加必要的属性,其中注意的是addAdvisor,添加完善后,开始调用proxyFactory.getProxy得到对应的动态代理对象

#org.springframework.aop.framework.ProxyFactory#getProxy(java.lang.ClassLoader)public Object getProxy(ClassLoader classLoader) {        return createAopProxy().getProxy(classLoader);
    }#org.springframework.aop.framework.ProxyCreatorSupport#createAopProxyprotected final synchronized AopProxy createAopProxy() {        if (!this.active) {
            activate();
        }        return getAopProxyFactory().createAopProxy(this);
    }    

#org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {        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.");
            }            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {                return new JdkDynamicAopProxy(config);
            }            return new ObjenesisCglibAopProxy(config);
        }        else {            return new JdkDynamicAopProxy(config);
        }
    }

我们先看下JDK的动态代理的getProxy

public JdkDynamicAopProxy(AdvisedSupport config) throws AopConfigException {
        Assert.notNull(config, "AdvisedSupport must not be null");        if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {            throw new AopConfigException("No advisors and no TargetSource specified");
        }        this.advised = config;
    }    @Override
    public Object getProxy() {        return getProxy(ClassUtils.getDefaultClassLoader());
    }    @Override
    public Object getProxy(ClassLoader classLoader) {        if (logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }
        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised);
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

再看下CGLIB动态代理的getProxy

    public CglibAopProxy(AdvisedSupport config) throws AopConfigException {
        Assert.notNull(config, "AdvisedSupport must not be null");        if (config.getAdvisors().length == 0 && config.getTargetSource() == AdvisedSupport.EMPTY_TARGET_SOURCE) {            throw new AopConfigException("No advisors and no TargetSource specified");
        }        this.advised = config;        this.advisedDispatcher = new AdvisedDispatcher(this.advised);
    }    
@Override
    public Object getProxy() {        return getProxy(null);
    }    @Override
    public Object getProxy(ClassLoader classLoader) {        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + this.advised.getTargetSource());
        }        try {
            Class<?> rootClass = this.advised.getTargetClass();
            Assert.state(rootClass != null, "Target class must be available for creating a CGLIB proxy");

            Class<?> proxySuperClass = rootClass;            if (ClassUtils.isCglibProxyClass(rootClass)) {
                proxySuperClass = rootClass.getSuperclass();
                Class<?>[] additionalInterfaces = rootClass.getInterfaces();                for (Class<?> additionalInterface : additionalInterfaces) {                    this.advised.addInterface(additionalInterface);
                }
            }            // Validate the class, writing log messages as necessary.
            validateClassIfNecessary(proxySuperClass, classLoader);            // Configure CGLIB Enhancer...
            Enhancer enhancer = createEnhancer();            if (classLoader != null) {
                enhancer.setClassLoader(classLoader);                if (classLoader instanceof SmartClassLoader &&
                        ((SmartClassLoader) classLoader).isClassReloadable(proxySuperClass)) {
                    enhancer.setUseCache(false);
                }
            }
            enhancer.setSuperclass(proxySuperClass);
            enhancer.setInterfaces(AopProxyUtils.completeProxiedInterfaces(this.advised));
            enhancer.setNamingPolicy(SpringNamingPolicy.INSTANCE);
            enhancer.setStrategy(new ClassLoaderAwareUndeclaredThrowableStrategy(classLoader));

            Callback[] callbacks = getCallbacks(rootClass);
            Class<?>[] types = new Class<?>[callbacks.length];            for (int x = 0; x < types.length; x++) {
                types[x] = callbacks[x].getClass();
            }            // fixedInterceptorMap only populated at this point, after getCallbacks call above
            enhancer.setCallbackFilter(new ProxyCallbackFilter(                    this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);            // Generate the proxy class and create a proxy instance.
            return createProxyClassAndInstance(enhancer, callbacks);
        }        catch (CodeGenerationException ex) {            throw new AopConfigException("Could not generate CGLIB subclass of class [" +                    this.advised.getTargetClass() + "]: " +                    "Common causes of this problem include using a final class or a non-visible class",
                    ex);
        }        catch (IllegalArgumentException ex) {            throw new AopConfigException("Could not generate CGLIB subclass of class [" +                    this.advised.getTargetClass() + "]: " +                    "Common causes of this problem include using a final class or a non-visible class",
                    ex);
        }        catch (Exception ex) {            // TargetSource.getTarget() failed
            throw new AopConfigException("Unexpected AOP exception", ex);
        }
    }    
    
    @Override
    @SuppressWarnings("unchecked")    protected Object createProxyClassAndInstance(Enhancer enhancer, Callback[] callbacks) {
        Class<?> proxyClass = enhancer.createClass();
        Object proxyInstance = null;        if (objenesis.isWorthTrying()) {            try {
                proxyInstance = objenesis.newInstance(proxyClass, enhancer.getUseCache());
            }            catch (Throwable ex) {
                logger.debug("Unable to instantiate proxy using Objenesis, " +                        "falling back to regular proxy construction", ex);
            }
        }        if (proxyInstance == null) {            // Regular instantiation via default constructor...
            try {
                proxyInstance = (this.constructorArgs != null ?
                        proxyClass.getConstructor(this.constructorArgTypes).newInstance(this.constructorArgs) :
                        proxyClass.newInstance());
            }            catch (Throwable ex) {                throw new AopConfigException("Unable to instantiate proxy using Objenesis, " +                        "and regular proxy instantiation via default constructor fails as well", ex);
            }
        }

        ((Factory) proxyInstance).setCallbacks(callbacks);        return proxyInstance;
    }

到目前为止我们讲了第一个生命周期方法postProcessBeforeInstantiation下面我们再看下第二个postProcessAfterInitialization的关键方法

    protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {        if (beanName != null && 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;
    }

所做的事情基本上和我们上面讲解的声明周期方法是一致的,获取Advices(getAdvicesAndAdvisorsForBean),生成动态代理对象createProxy( bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean)),今天我们就讲到这里,大家自己消化一下吧。



作者:数齐
链接:https://www.jianshu.com/p/f28e5b2df0a9


点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消