开发者

Spring Aware源码设计示例解析

目录
  • 1. Aware介绍
  • 2. Aware类别
    • 2.1 BeanClassLoaderAware
    • 2.2 BeanFactoryAware
    • 2.3 BeanNameAware
    • 2.4 ApplicationContextAware
  • 3. Aware的使用
    • 4. Aware的作用
      • 5. Aware的调用

        1. Aware介绍

        前一篇讲到了BeanPostProcessor的相关知识,我们知道BeanPostProcejsssor是对整个容器中的Bean做前置和后置增强处理。这样的实现方式限制了开发者只能按照Spring提供的模板,对Bean做前置和后置的增强,这样虽然已经很灵活了,但是如果开发者想要对Spring中的Bean做更复杂的操作或者开发者想要使用Spring中的BeanFactory、ClassLoader时,这样的方式明显就不够方便了,因此Spring也考虑到了这样的情况,就提供了另外的方式提升Spring的扩展性和灵活性,这种方式就是Aware。

        单纯说Aware可能不熟悉,但是如果说BeanNameAware、BeanFactoryAware那么是不是就知道这个Aware到底是何方神圣了。

        接下来就说一下Spring提供给开发者Aware的这个功能。

        Spring中Aware的源码如下:

        public interface Aware {
        }
        

        从源码中可以看到Aware就是一个简单的接口,该接口是一个无实现的接口,一般看到这种接口可以都是作为最顶级的父类接口使用的,使用时一般都是instanceof判断是否是顶级接口类型。

        2. Aware类别

        在Spring中Aware有几个继承接口,分别是:

        • BeanClassLoaderAware
        • BeanFactoryAware
        • BeanNameAware

        2.1 BeanClassLoaderAware

        首先是BeanClassLoaderAware接口,从字面意思翻译就可以大概知道这是一个关于Bean的类加载器的接口,因此该接口的功能就聚焦在类加载器上。

        BeanClassLoaderAware源码如下:

        public interface BeanClassLoaderAware extends Aware {
        	//set方法,赋值ClassLoader方法
        	void setBeanClassLoader(ClassLoader classLoader);
        }
        

        从源码可以看到该接口只提供了一个setBeanClassLoader方法,该方法就是简单的设置Bean的类加载器的方法,所以从这个方法中就可以知道BeanClassLoaderAware就单纯提供了一个赋值ClassLoader的方法,这里的接口并不会指定ClassLoader的接收方,因此接收方需要在实现该接口的实现类中指定,然后将ClassLoader赋值给实现类中的具体常量。

        2.2 BeanFactoryAware

        BeanFactoryAware接口,看到这个就立马想到Spring中的BeanFactory,BeanFactory在Spring中是作为Bean的工厂,那么该接口一定是与BeanFactory相关的接口。

        BeanFactoryAware源码如下:

        public interface BeanFactoryAware extends Aware {
            void setBeanFactory(BeanFactory beanFactory) throws BeansException;
        }
        

        从源码中可以看到BeanFactoryAware跟BeanClassLoaderAware相似都只提供了一个set方法,该接口中只定义了setBeanFactory一个方法。

        该接口中的方法 功能跟BeanClassLoaderAware功能相同,都是赋值,但是该接口赋值的是BeanFactory。

        2.3 BeanNameAware

        源码如下:

        public interface BeanNameAware extends Aware {
            void setBeanName(String name);
        }
        

        该接口功能同上。(说实话实际开发中没用到过这个,只用过前两个,所以我也没搞懂该类到底可以干啥)。

        2.4 ApplicationContextAware

        该接口则是一个特别的接口了,因为该接口跟前三个继承Aware的接口不同,ApplicationContextAware并不是spring-bean中提供的接口,而是在spring-context中提供的接口,该接口是从spring-context包中提供的接口,该接口的作用也是跟前三个类似,并且大部分开发者用的最多的也是这个。

        源码如下:

        public interface ApplicationContextAware extends Aware {
            void setApplicationContext(ApplicationContext applicationContext) throws BeansException;
        }
        
        public interface ApplicationContext extends EnvironmentCapable, ListableBeanFactory, HierarchicalBeanFactory, MessageSource, ApplicationEventPublisher, ResourcePatternResolver {
            @Nullable
            String getId();
            String getApplicationName();
            String getDisplayName();
            long getStartupDate();
            @Nullable
            ApplicationContext getParent();
            AutowireCapableBeanFactory getAutowireCapableBeanFactory() throws IllegalStateException;
        }
        

        源码中也是简单的赋值操作,但是赋值的对象是ApplicationContext对象,对于这个对象使用Spring的一定不陌生。

        可以这样说:ApplicationContext给了开发者最多的权限用于操作Bean。

        从ApplicationContext源码中也可以看到该接口继承了ListableBeanFactory、HierarchicalBeanFactory、ApplicationEventPublisher等其它接口,这样就将更多的Bean的权限通过ApplicationContext下放给开发者!(又是被Spring的高灵活性折服的时刻)。

        3. Aware的使用

        @Component
        public class MySpringAware implements BeanFactoryAware, BeanClassLoaderAware, ApplicationContextAware, BeanNameAware {
            private ApplicationContext applicationContext;
            private ListableBeanFactory beanFactory;
            private ClassLoader classLoader;
            private String beanName;
            /**
             * 获取某个接口下的所有实现类
             *
             * @param filter
             */
            public void registryFilter(FilterProcessor filter) {
                Map<String, MyFilter> beans = beanFactory.getBeansOfType(MyFilter.class);
                beans.values().stream().sorted(AnnotationAwareOrderComparator.INSTANCE).forEach(filter::register);
            }
                /**
             * 获取环境配置
             *
             * @return
             */
            public Environment getApplicationData() {
               开发者_开发教程 return applicationContext.getEnvironment();
            }
            public ApplicationContext getApplicationContext() {
                return applicationContext;
            }
            @Override
            public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
                this.applicationContext = applicationContext;
            }
            @Override
            public void setBeanClassLoader(ClassLoader classLoader) {
                this.classLoader = classLoader;
            }
            @Override
            public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
                this.beanFactory = (ListableBeanFactory) beanFactory;
            }
            @Override
            public void setBeanName(String s) {
                this.beanName = s;
            }
        }
        
        @Component
        public class FilterProcessor {
            private final List<MyFilter> filterList = new ArrayList();
            public void register(MyFilter filter) {
                this.filterList.add(filter);
            }
            public List<MyFilter> getFilterList() {
                return filterList;
            }
        }
        
        public interface MyFilter {
            void doFilter();
        }
        
        @Component
        @Order(1)
        public class MyDemoFilter extends FilterProcessor implements MyFilter{
            @Override
            public void doFilter() {
                System.out.println("执行第一个过滤器MyDemoFilter");
            }
        }
        @Component
        @Order(2)
        public class MyDemoFilter2 extends FilterProcessor implements MyFilter{
            @Override
            public void doFilter() {
                System.out.println("执行zfBaCIEq第二个过滤器MyDemoFilter2");
            }
        }
        

        运行结果:

        Spring Aware源码设计示例解析

        以上的例子中通过MySpringAware实现了前文中说到的几个Aware,分别使用了其中的BeanFactory和ApplicationContext。这样在MySpringAware中就可以使用我们定义的常量接收Spring容器中的BeanFactory、ClassLoader、ApplicationContext等功能。

        4. Aware的作用

        从以上的例子中可以看到,Aware为开发者提供了插桩式的接口,开发者只要实现该接口就可以获得Spring容器的某些管理权。

        比如BeanClassLoaderAware是获得对Bean的类加载器的管理权。

        BeanFactoryAware是活的对Bean工厂的管理权。

        这样插桩式的扩展可以保证开发者在使用时可以获得Spring中某些功能的管理权,方便开发者对Spring的理解和使用,不需要复杂的实现就可以获得Spring内部的管理。

        5. Aware的调用

        前面说完了Aware的介绍、类别和作用,最后来说实现Aware相关接口的实现类在Spring中是如何被调用的。

        实现Aware相关接口的实现类被调用的方式与前面讲的BeanPostProcessor有一定区别。

        区别如下:

        BeanPostProcessor的调用:

        • 调用方式:注册+读取注册列表(通过register.List和遍历beanPostProcessorList)
        • 调用时机:Bean执行初始化函数(invokeInitMethods)之前或者之后

        Aware的调用:

        • 调用方式:通过Bean是否实现了Aware/BeanClassLoaderAware/BeanFactoryAware,然后调用相应的实现类的重写方法
        • 调用时机:Bean执行初始化函数(invokeInitMethods)之前且beanPostProcessor#before之前

        源码如下:

        public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory
        		implements AutowireCapableBeanFactory {
            //初始化Bean的方法
        	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
        		if (System.getSecurityManager() != null) {
        			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
                        //调用Bean的Aware重写接口
        				invokeAwareMethods(beanName, bean);
        				return null;
        			}, getAccessControlContext());
        		}
        		else {
                    //调用Bean的Aware重写接口
        			invokeAwareMethods(beanName, bean);
        		}
        		Object wrappedBean = bean;
        		if (mbd == null || !mbd.isSynthetic()) {
                    //调用BeanPostProcessor前置接口
        			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()) {
                    //调用BeanPostProcesso编程r后置接口
        			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        		}
        		return wrappedBean;
        	}
        	//调用Aware的实现
            private void invokeAwareMethods(String beanName, Object bean) {
                if (bean instanceof Aware) {
                    if (bean instanceof BeanNameAware) {
                        ((BeanNameAware) bean).setBeanName(beanName);
                    }
                    if (bean instanceof BeanClassLoaderAware) {
                        ClajsssLoader bcl = getBeanClassLoader();
                        if (bcl != null) {
                            ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl);
                        }
                    }
                    if (bean instanceof BeanFactoryAware) {
                        ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this);
                    }
                }
            }
        }
        

        区别梳理如下:

        Spring Aware源码设计示例解析

        以AbstractAutowireCapableBeanFactory为主线梳理调用Aware接口的链路如下:

        • org.springframework.beans.factohttp://www.devze.comry.support.AbstractBeanFactory#doGetBean
        • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean
        • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean
        • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
        • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods

        对于ApplicationContextAware的调用链路梳理如下:

        • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
        • org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization
        • org.springframework.context.support.ApplicationContextAwareProcessor#postProcessBeforeInitialization
        • org.springframework.context.support.ApplicationContextAwareProcessor#invokeAwareInterfaces

        根据以上的链路可以很清晰的看到ApplicationContextAware的调用实现。

        以上就是Spring Aware源码设计示例解析的详细内容,更多关于Spring Aware源码设计的资料请关注我们其它相关文章!

        0

        上一篇:

        下一篇:

        精彩评论

        暂无评论...
        验证码 换一张
        取 消

        最新开发

        开发排行榜