精华内容
参与话题
问答
  • Spring扩展

    2020-05-31 18:07:46
    要想对Spring进行扩展,首先得先了解Spring实例化流程。 如下UML图所示,像普通Java类一样,运行Main方法后,JVM将类文件加载到方法区。 public class Test { public static void main(String[] args) { ...

    Spring实例化流程

    要想对Spring进行扩展,首先得先了解Spring实例化流程。
    如下UML图所示,像普通Java类一样,运行Main方法后,JVM将类文件加载到方法区。

    public class Test {
    	public static void main(String[] args) {
    		AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    		//System.out.println(ac.getBean(OrderService.class));
    	}
    }
    

    在这里插入图片描述

    AppConfig类使用@ComponentScan注解扫描指定包下的.java文件,经过解析放入BeanDefinition接口的子类,其中包括该类的各种注解及对应的属性。然后会被put到一个Map里面。最后通过preInstantiateSingletons预实例化到Spring单例池(原型与单例不同,是在getBean时实例化)

    @ComponentScan("com.zyc")
    public class AppConfig {
    }
    
    @Component
    public class OrderService {
    	//@Autowired
    	private UserService userService;
    
    	public OrderService() {
    		System.out.println("from OrderService");
    	}
    
    	public void getUserService() {
    
    		userService.getOrderService();
    	}
    }
    

    Spring扩展

    前面UML图红色的部分就是Spring扩展,Spring会在Map预实例化Spring单例池前检查是否有扩展功能,如果有的话,就会通过Spring的BeanFactoryPostProcessor接口进行扩展。

    @Component
    public class ExpandBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
    	@Override
    	public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    		GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition)beanFactory.getBeanDefinition("orderService");
    		genericBeanDefinition.setBeanClass(UserService.class);
    
    	}
    }
    
    //@Component
    public class UserService {
    	//@Autowired
    	private OrderService orderService;
    
    	public UserService() {
    		System.out.println("from UserService");
    	}
    
    	public void getOrderService() {
    		System.out.println("OrderService:"+ orderService);
    	}
    }
    

    上面代码写了个类实现了BeanFactoryPostProcessor 接口,通过GenericBeanDefinition类的beanFactory获取orderService并修改BeanClass为UserService.class。修改后返回给Map,再预实例化到Spring单例池。
    如下控制台显示,虽然扫描的UserService没有@Component注解,但是经过扩展修改后,最后还是将UserService放入了Spring单例池,我们可以看到日志打印的是UserService的构造器方法。
    在这里插入图片描述

    展开全文
  • Spring扩展接口

    2020-06-06 15:04:10
    Spring为容器内的bean生命周期提供了大量的扩展接口。可以实现这些接口,在Spring bean生命周期过程中对bean实例进行扩展。。 ApplicationContext中bean的生命周期 Spring中一个bean被创建过程的执行流程。 ...

    bean的生命周期过程的接口

    Spring为容器内的bean生命周期提供了大量的扩展接口。可以实现这些接口,在Spring bean生命周期过程中对bean实例进行扩展。。

    ApplicationContext中bean的生命周期

    Spring中一个bean被创建过程的执行流程。
    在这里插入图片描述

    BeanFactoryPostProcessor

    Spring IoC容器允许BeanFactoryPostProcessor在容器实例化任何bean之前读取bean的定义(配置元数据),并可以修改它。同时可以定义多个BeanFactoryPostProcessor,通过设置’order’属性来确定各个BeanFactoryPostProcessor执行顺序。

    void postProcessBeanFactory(ConfigurableListableBeanFactory var1) throws BeansException;
    

    在Spring中内置了一些BeanFactoryPostProcessor实现类:

    org.springframework.beans.factory.config.PropertyPlaceholderConfigurer : 读取配置文件,在bean初始化之前,根据注解或xml配置给bean设置值。
    org.springframework.beans.factory.config.PropertyOverrideConfigurer:似于PropertyPlaceholderConfigurer,PropertyOverrideConfigurer对于bean属性可以有缺省值或者根本没有值
    org.springframework.beans.factory.config.CustomEditorConfigurer:注册自定义属性编辑器,用于给bean属性转化类型

    InstantiationAwareBeanPostProcessor

    InstantiationAwareBeanPostProcessor 继承至BeanPostProcessor,比起BeanPostProcessor。InstantiationAwareBeanPostProcessor多出以下4个方法。主要处理的是bean的实例化过程。

    /**
     * 在bean实例化前执行(构造函数执行前)
     * @param beanClass  被实例化bean的class
     * @param beanName  bean的名字
     * @return 返回null就会执行默认的实例化过程,返回Object会替代默认的实例化bean。
    * @throws BeansException
     */
    @Nullable
    default Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        return null;
    }
    
    /**
     * 在bean实例化后执行
     * @param bean  bean被创建的实例对象,实例(依赖Spring注入的属性)属性值还没赋值。
     * @param beanName bean 
     * @return 如果返回true,执行下面的属性值注入。返回false,属性设置行为会被跳过。
     * @throws BeansException
     */
    default boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        return true;
    }
    
    /**
     * 用于给bean处理值注入,@Autowire就在这个过程处理注入
     * @param pvs Spring工厂中存在的属性值
     * @param bean bean的实例对象
     * @param beanName bean的名字
     * @return 返回实例真实设置的值,返回null,继承当前pvs,继续执行后续的postProcessProperties处理值。
     * @throws BeansException
     */
    @Nullable
    default PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException {
        return null;
    }
    
    /**
     * Spring5已经过期,用postProcessProperties代替。
     * @param pvs
     * @param pds
     * @param bean
     * @param beanName
     * @return
     * @throws BeansException
     */
    @Deprecated
    @Nullable
    default PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
        return pvs;
    } /**
     * 实例化对象前
     *
     */
    

    BeanPostProcessor

    BeanPostProcessor有2个方法,扩展bean初始化流程(实例化早于初始化,初始化是为对象赋值,注入属性之类的)。

    /**
     * 在类初始化前被调用
     * @param bean  bean的实例对象
     * @param beanName bean的名字
     * @return 返回bean的实例对象,如果返回null,后续的BeanPostProcessors 将不会被调用。
     */
    @Nullable
    default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
    	return bean;
    }
    
    /**
     * bean初始化之后
     * @param bean bean的实例对象
     * @param beanName bean的名字
     * @return 返回bean的实例对象,如果返回null,后续的BeanPostProcessors 将不会被调用。
     * @throws org.springframework.beans.BeansException in case of errors
     */
    @Nullable
    default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    	return bean;
    }
    

    InitializingBean

    实现该接口的bean的所有属性都被设置后执行。

     /**
        * bean的所有属性都被设置完成时执行
     */
    void afterPropertiesSet() throws Exception;
    
    

    DisposableBean

    实现该接口的bean的销毁时执行,用于释放资源

    void destroy() throws Exception;
    

    FactoryBean

    某些bean的实例化过程比较复杂,如果通过配置方式进行可能需要进行非常繁琐的配置。FactoryBean的作用就是用来实现这些bean的实例化。实现FactoryBean接口的bean,不能正常的通过Spring容器使用,通过Spring容器获取的总是它的getObject方法创建的实例。

     /** 
        * 返回一个实例 
     * @return 一个bean实例,可以为null
     * @throws Exception in case of creation errors
     * @see FactoryBeanNotInitializedException
     */
    @Nullable
    T getObject() throws Exception;
    
    /**
     * @return 返回bean实例的类型
     * @see ListableBeanFactory#getBeansOfType
     */
    @Nullable
    Class<?> getObjectType();
    
    /**
        *返回由FactoryBean创建的bean实例的作用域是singleton还是prototype,如果isSingleton()返回true,则该实 *例会放到Spring容器中单实例缓存池中
     * @return 对象是否为单例
     * @see #getObject()
     * @see SmartFactoryBean#isPrototype()
     */
    default boolean isSingleton() {
    	return true;
    }
    
    展开全文
  • Spring扩展点总结

    2020-09-23 18:10:42
    BeanDefinition与BeanFactory扩展Spring生成bean的过程这篇文章中,我们了解了spring在生成bean前会先生成bean的定义,然后注册到BeanFactory中,再之后才能生成bean。那么对于从xml配置好的BeanDefinition,如果...

    BeanDefinition与BeanFactory扩展

    在Spring生成bean的过程这篇文章中,我们了解了spring在生成bean前会先生成bean的定义,然后注册到BeanFactory中,再之后才能生成bean。那么对于从xml配置好的BeanDefinition,如果想要增加删除修改该怎么办呢?

    1.1 BeanDefinitionRegistryPostProcessor接口

    BeanDefinitionRegistryPostProcessor接口继承了BeanFactoryPostProcessor接口,BeanFactoryPostProcessor接口随后我们也会讲到这个接口。

    /**

    • Extension to the standard {@link BeanFactoryPostProcessor} SPI, allowing for

    • the registration of further bean definitions before regular

    • BeanFactoryPostProcessor detection kicks in. In particular,

    • BeanDefinitionRegistryPostProcessor may register further bean definitions

    • which in turn define BeanFactoryPostProcessor instances.

    • @author Juergen Hoeller

    • @since 3.0.1

    • @see org.springframework.context.annotation.ConfigurationClassPostProcessor
      */
      public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {

      /**

      • Modify the application context’s internal bean definition registry after its
      • standard initialization. All regular bean definitions will have been loaded,
      • but no beans will have been instantiated yet. This allows for adding further
      • bean definitions before the next post-processing phase kicks in.
      • @param registry the bean definition registry used by the application context
      • @throws org.springframework.beans.BeansException in case of errors
        */
        void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;

    }

    这个接口扩展了标准的BeanFactoryPostProcessor 接口,允许在普通的BeanFactoryPostProcessor接口实现类执行之前注册更多的BeanDefinition。特别地是,BeanDefinitionRegistryPostProcessor可以注册BeanFactoryPostProcessor的BeanDefinition。

    postProcessBeanDefinitionRegistry方法可以修改在BeanDefinitionRegistry接口实现类中注册的任意BeanDefinition,也可以增加和删除BeanDefinition。原因是这个方法执行前所有常规的BeanDefinition已经被加载到BeanDefinitionRegistry接口实现类中,但还没有bean被实例化。

    接口应用

    我们仅仅需要写一个类实现接口,然后将这个类配置到spring的xml配置中。以下是我写的一个简单的实现类:

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.BeansException;
    import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
    import org.springframework.beans.factory.support.BeanDefinitionRegistry;
    import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;

    public class DefaultBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
        logger.info("BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法,在这里可以增加修改删除bean的定义");
    }
    
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
        logger.info("BeanDefinitionRegistryPostProcessor的postProcessBeanFactory方法,在这里可以对beanFactory做一些操作");
    }
    

    }

    实际上,Mybatis中org.mybatis.spring.mapper.MapperScannerConfigurer就实现了该方法,在只有接口没有实现类的情况下找到接口方法与sql之间的联系从而生成BeanDefinition并注册。而Spring的org.springframework.context.annotation.ConfigurationClassPostProcessor也是用来将注解@Configuration中的相关生成bean的方法所对应的BeanDefinition进行注册。

    1.2.BeanFactoryPostProcessor接口

    BeanFactory生成后,如果想对BeanFactory进行一些处理,该怎么办呢?BeanFactoryPostProcessor接口就是用来处理BeanFactory的。

    /**

    • Allows for custom modification of an application context’s bean definitions,

    • adapting the bean property values of the context’s underlying bean factory.

    • Application contexts can auto-detect BeanFactoryPostProcessor beans in

    • their bean definitions and apply them before any other beans get created.

    • Useful for custom config files targeted at system administrators that

    • override bean properties configured in the application context.

    • See PropertyResourceConfigurer and its concrete implementations

    • for out-of-the-box solutions that address such configuration needs.

    • A BeanFactoryPostProcessor may interact with and modify bean

    • definitions, but never bean instances. Doing so may cause premature bean

    • instantiation, violating the container and causing unintended side-effects.

    • If bean instance interaction is required, consider implementing

    • {@link BeanPostProcessor} instead.

    • @author Juergen Hoeller

    • @since 06.07.2003

    • @see BeanPostProcessor

    • @see PropertyResourceConfigurer
      */
      public interface BeanFactoryPostProcessor {

      /**

      • Modify the application context’s internal bean factory after its standard
      • initialization. All bean definitions will have been loaded, but no beans
      • will have been instantiated yet. This allows for overriding or adding
      • properties even to eager-initializing beans.
      • @param beanFactory the bean factory used by the application context
      • @throws org.springframework.beans.BeansException in case of errors
        */
        void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException;

    }

    这个接口允许自定义修改应用程序上下文的BeanDefinition,调整上下文的BeanFactory的bean属性值。应用程序上下文可以在BeanFactory的BeanDefinition中自动检测BeanFactoryPostProcessor bean,并在创建任何其他bean之前应用它们。对于定位于系统管理员的自定义配置文件非常有用,它们将覆盖应用程序上下文中配置的bean属性。请参阅PropertyResourceConfigurer及其具体实现,了解解决此类配置需求的开箱即用解决方案。BeanFactoryPostProcessor可能与bean定义交互并修改,但永远不应该将bean实例化。 这样做可能会导致过早的bean实例化,违反容器执行顺序并导致意想不到的副作用。如果需要bean实例交互,请考虑实现BeanPostProcessor接口。

    postProcessBeanFactory方法在BeanFactory初始化后,所有的bean定义都被加载,但是没有bean会被实例化时,允许重写或添加属性。

    接口应用

    DefaultBeanDefinitionRegistryPostProcessor接口一样,实现并配置到spring的xml配置中即可。

    最常用的一个应用就是org.springframework.beans.factory.config.PropertyPlaceholderConfigurer,BeanDefinition生成后,可能某些参数是${key},这个实现类就是把前边这种参数转换成xxx.properties中key所对应的值。

    Bean实例化中的扩展
    前一小节关注的是BeanDefinition和BeanFactory,那么在bean的实例化过程中会调用一些特定的接口实现类,这些接口都有哪些?

    1.3 InstantiationAwareBeanPostProcessor接口

    /**
     * Subinterface of {@link BeanPostProcessor} that adds a before-instantiation callback,
     * and a callback after instantiation but before explicit properties are set or
     * autowiring occurs.
     *
     * <p>Typically used to suppress default instantiation for specific target beans,
     * for example to create proxies with special TargetSources (pooling targets,
     * lazily initializing targets, etc), or to implement additional injection strategies
     * such as field injection.
     *
     * <p><b>NOTE:</b> This interface is a special purpose interface, mainly for
     * internal use within the framework. It is recommended to implement the plain
     * {@link BeanPostProcessor} interface as far as possible, or to derive from
     * {@link InstantiationAwareBeanPostProcessorAdapter} in order to be shielded
     * from extensions to this interface.
     *
     * @author Juergen Hoeller
     * @author Rod Johnson
     * @since 1.2
     * @see org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#setCustomTargetSourceCreators
     * @see org.springframework.aop.framework.autoproxy.target.LazyInitTargetSourceCreator
     */
    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    
        /**
         * Apply this BeanPostProcessor <i>before the target bean gets instantiated</i>.
         * The returned bean object may be a proxy to use instead of the target bean,
         * effectively suppressing default instantiation of the target bean.
         * <p>If a non-null object is returned by this method, the bean creation process
         * will be short-circuited. The only further processing applied is the
         * {@link #postProcessAfterInitialization} callback from the configured
         * {@link BeanPostProcessor BeanPostProcessors}.
         * <p>This callback will only be applied to bean definitions with a bean class.
         * In particular, it will not be applied to beans with a "factory-method".
         * <p>Post-processors may implement the extended
         * {@link SmartInstantiationAwareBeanPostProcessor} interface in order
         * to predict the type of the bean object that they are going to return here.
         * @param beanClass the class of the bean to be instantiated
         * @param beanName the name of the bean
         * @return the bean object to expose instead of a default instance of the target bean,
         * or {@code null} to proceed with default instantiation
         * @throws org.springframework.beans.BeansException in case of errors
         * @see org.springframework.beans.factory.support.AbstractBeanDefinition#hasBeanClass
         * @see org.springframework.beans.factory.support.AbstractBeanDefinition#getFactoryMethodName
         */
        Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
    
        /**
         * Perform operations after the bean has been instantiated, via a constructor or factory method,
         * but before Spring property population (from explicit properties or autowiring) occurs.
         * <p>This is the ideal callback for performing custom field injection on the given bean
         * instance, right before Spring's autowiring kicks in.
         * @param bean the bean instance created, with properties not having been set yet
         * @param beanName the name of the bean
         * @return {@code true} if properties should be set on the bean; {@code false}
         * if property population should be skipped. Normal implementations should return {@code true}.
         * Returning {@code false} will also prevent any subsequent InstantiationAwareBeanPostProcessor
         * instances being invoked on this bean instance.
         * @throws org.springframework.beans.BeansException in case of errors
         */
        boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
    
        /**
         * Post-process the given property values before the factory applies them
         * to the given bean. Allows for checking whether all dependencies have been
         * satisfied, for example based on a "Required" annotation on bean property setters.
         * <p>Also allows for replacing the property values to apply, typically through
         * creating a new MutablePropertyValues instance based on the original PropertyValues,
         * adding or removing specific values.
         * @param pvs the property values that the factory is about to apply (never {@code null})
         * @param pds the relevant property descriptors for the target bean (with ignored
         * dependency types - which the factory handles specifically - already filtered out)
         * @param bean the bean instance created, but whose properties have not yet been set
         * @param beanName the name of the bean
         * @return the actual property values to apply to the given bean
         * (can be the passed-in PropertyValues instance), or {@code null}
         * to skip property population
         * @throws org.springframework.beans.BeansException in case of errors
         * @see org.springframework.beans.MutablePropertyValues
         */
        PropertyValues postProcessPropertyValues(
                PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
    
    }
    

    这个接口是BeanPostProcessor的子接口,用于在实例化之后,但在设置显式属性或自动装配之前,设置实例化之前的回调函数。通常用于抑制特定目标bean的默认实例化,例如,创建具有特殊TargetSources(池化目标,延迟初始化目标等)的代理,或者实现其他注入策略,例如字段注入。注意:这个接口是一个专用接口,主要用于框架内的内部使用。 建议尽可能实现简单的BeanPostProcessor接口,或者从InstantiationAwareBeanPostProcessorAdapter派生,以便屏蔽此接口的扩展。

    postProcessBeforeInstantiation方法,在目标bean实例化之前创建bean,如果在这里创建了bean,则不会走默认的实例化过程,通常用来创建代理。注意工厂方法生成的bean不会走这个方法。

    postProcessAfterInstantiation方法,在目标bean实例化后,但是没有进行属性填充前执行的方法。

    postProcessPropertyValues方法,在将给定属性值设置到到给定的bean后,对其进行后处理。 允许检查所有的依赖关系是否被满足,例如基于bean属性设置器上的“Required”注解。还允许替换要应用的属性值,通常通过创建基于原始PropertyValues的新MutablePropertyValues实例,添加或删除特定值。

    接口应用

    这个接口spring不建议用户直接实现,如果必须在这些扩展点应用自己的回调函数,spring建议继承InstantiationAwareBeanPostProcessorAdapter,重写相应的方法即可。

    org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator,基于beanName创建代理,就是应用了这个接口,在生成bean前生成代理bean,从而替代默认的实例化。

    1.4BeanPostProcessor接口

    /**
     * Factory hook that allows for custom modification of new bean instances,
     * e.g. checking for marker interfaces or wrapping them with proxies.
     *
     * <p>ApplicationContexts can autodetect BeanPostProcessor beans in their
     * bean definitions and apply them to any beans subsequently created.
     * Plain bean factories allow for programmatic registration of post-processors,
     * applying to all beans created through this factory.
     *
     * <p>Typically, post-processors that populate beans via marker interfaces
     * or the like will implement {@link #postProcessBeforeInitialization},
     * while post-processors that wrap beans with proxies will normally
     * implement {@link #postProcessAfterInitialization}.
     *
     * @author Juergen Hoeller
     * @since 10.10.2003
     * @see InstantiationAwareBeanPostProcessor
     * @see DestructionAwareBeanPostProcessor
     * @see ConfigurableBeanFactory#addBeanPostProcessor
     * @see BeanFactoryPostProcessor
     */
    public interface BeanPostProcessor {
    
        /**
         * Apply this BeanPostProcessor to the given new bean instance <i>before</i> any bean
         * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
         * or a custom init-method). The bean will already be populated with property values.
         * The returned bean instance may be a wrapper around the original.
         * @param bean the new bean instance
         * @param beanName the name of the bean
         * @return the bean instance to use, either the original or a wrapped one;
         * if {@code null}, no subsequent BeanPostProcessors will be invoked
         * @throws org.springframework.beans.BeansException in case of errors
         * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
         */
        Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException;
    
        /**
         * Apply this BeanPostProcessor to the given new bean instance <i>after</i> any bean
         * initialization callbacks (like InitializingBean's {@code afterPropertiesSet}
         * or a custom init-method). The bean will already be populated with property values.
         * The returned bean instance may be a wrapper around the original.
         * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean
         * instance and the objects created by the FactoryBean (as of Spring 2.0). The
         * post-processor can decide whether to apply to either the FactoryBean or created
         * objects or both through corresponding {@code bean instanceof FactoryBean} checks.
         * <p>This callback will also be invoked after a short-circuiting triggered by a
         * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method,
         * in contrast to all other BeanPostProcessor callbacks.
         * @param bean the new bean instance
         * @param beanName the name of the bean
         * @return the bean instance to use, either the original or a wrapped one;
         * if {@code null}, no subsequent BeanPostProcessors will be invoked
         * @throws org.springframework.beans.BeansException in case of errors
         * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet
         * @see org.springframework.beans.factory.FactoryBean
         */
        Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException;
    
    }
    

    这个接口,允许自定义修改新的bean实例,例如检查标记接口或用代理包装,注意,如果有相互依赖的bean,这里可能无法使用代理。

    postProcessBeforeInitialization方法,在任何bean初始化回调(如InitializingBean的afterPropertiesSet或自定义init方法)之前,将此BeanPostProcessor应用于给定的新的bean实例。 这个bean已经被填充了属性值。 返回的bean实例可能是原始的包装器。

    postProcessAfterInitialization方法,在Bean初始化回调(如InitializingBean的afterPropertiesSet或自定义init方法)之后,将此BeanPostProcessor应用于给定的新bean实例。 这个bean已经被填充了属性值。 返回的bean实例可能是原始的包装器。这个方法也会在InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation方法生成对象后再次不让他生成对象(具体可以参考Spring生成bean的过程)。

    接口应用

    org.springframework.context.support.ApplicationContextAwareProcessor就是在bean初始化回调之前,注入应用上下文的。

    其他扩展点

    InitializingBean接口

    在执行完BeanPostProcessor的postProcessBeforeInitialization方法后,如果这个bean实现了InitializingBean接口,则会去调用afterPropertiesSet方法。

    各种Aware

    在在执行完BeanPostProcessor的postProcessBeforeInitialization方法前,如果bean实现了BeanNameAware或BeanClassLoaderAware或BeanFactoryAware,则会调用接口相关的方法,入参就是这个bean关心的值。

    ApplicationContextAwareProcessor,作用是在一个bean初始化之前,如果这个bean有Aware接口,实现了EnvironmentAware,EmbeddedValueResolverAware,ResourceLoaderAware,ApplicationEventPublisherAware,MessageSourceAware,ApplicationContextAware相关接口,就通过这些aware的相关接口将上下文设置进去,上述接口除了EmbeddedValueResolverAware接口ClassPathXmlApplicationContext没有实现,其他都实现了,也就是说,调用这些接口的方法入参都是ClassPathXmlApplicationContext就可以了。EmbeddedValueResolverAware的入参是EmbeddedValueResolver,它的构造函数入参是上下文中的beanFactory。

    BeanDefinition入口扩展

    在定义bean时,可以指定构造函数,设置属性,还可以设置init-method和destroy-method。构造函数不用说,设置属性是在InstantiationAwareBeanPostProcessor#PostProcessPropertyValues方法后执行的,init-method是在InitializingBean的afterPropertiesSet方法后执行的,而destroy-method是在容器关闭是被调用的。

    扩展点在spring中的注入

    前三小节我们了解了很多扩展点,那这些扩展点中的接口是怎么在spring中生效的呢,换句话说在什么时候被调用或被添加到BeanFactory中等待调用呢?

    容器级别

    我们得从上下文的抽象类AbstractApplicationContext#refresh方法讲起

    @Override
    public void refresh() throws BeansException, IllegalStateException {
        synchronized (this.startupShutdownMonitor) {
            // Prepare this context for refreshing.
            // 设置上下文启动时间和活跃标记,同时加载属性资源。
            prepareRefresh();
    
            // Tell the subclass to refresh the internal bean factory.
            // 停掉之前启动的beanFactory如果有的话,同时新生成一个beanFactory,加载配置中的BeanDefinition。
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
    
            // Prepare the bean factory for use in this context.
            // 给beanFactory设置类加载器,添加后置处理器`ApplicationContextAwareProcessor`等等。
            prepareBeanFactory(beanFactory);
    
            try {
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
    
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
    
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
    
                // Initialize message source for this context.
                initMessageSource();
    
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
    
                // Initialize other special beans in specific context subclasses.
                onRefresh();
    
                // Check for listener beans and register them.
                registerListeners();
    
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
    
                // Last step: publish corresponding event.
                finishRefresh();
            }
    
            catch (BeansException ex) {
                if (logger.isWarnEnabled()) {
                    logger.warn("Exception encountered during context initialization - " +
                            "cancelling refresh attempt: " + ex);
                }
    
                // Destroy already created singletons to avoid dangling resources.
                destroyBeans();
    
                // Reset 'active' flag.
                cancelRefresh(ex);
    
                // Propagate exception to caller.
                throw ex;
            }
    
            finally {
                // Reset common introspection caches in Spring's core, since we
                // might not ever need metadata for singleton beans anymore...
                resetCommonCaches();
            }
        }
    }
    

    invokeBeanFactoryPostProcessors(beanFactory)方法就是第一小节提到的BeanDefinitionRegistryPostProcessor和BeanFactoryPostProcessor的调用。

    invokeBeanFactoryPostProcessors方法的调用逻辑:

    如果beanFactory是BeanDefinitionRegistry的实现类

    拿到入参所有的BeanFactoryPostProcessor接口实现类,挑选出实现BeanDefinitionRegistryPostProcessor接口的实现类先执行postProcessBeanDefinitionRegistry方法。

    接下来调用beanFactory中实现BeanDefinitionRegistryPostProcessor接口的实现类中实现PriorityOrdered接口的实现类,调用这些实现类前先根据PriorityOrdered的getOrder方法进行排序,然后再按顺序调用postProcessBeanDefinitionRegistry方法。

    接下来再调用beanFactory中实现BeanDefinitionRegistryPostProcessor接口的实现类中实现了Ordered接口的类,也是按顺序调用postProcessBeanDefinitionRegistry方法。

    最后调用beanFactory中其他的实现BeanDefinitionRegistryPostProcessor接口的实现类的postProcessBeanDefinitionRegistry方法。

    最后的最后,先调用入参中所有实现BeanDefinitionRegistryPostProcessor接口的实现类的postProcessBeanFactory方法,再调用入参中实现了BeanFactoryPostProcessor接口的实现类的postProcessBeanFactory方法。

    如果不是则只把入参中的BeanFactoryPostProcessor实现类全部调用一遍。

    上边都做完了,接着从beanFactory中获取实现了BeanFactoryPostProcessor接口的bean(没有被执行过),也是分为三类,PriorityOrdered组优先调用,Ordered其次,其他垫底。
    最终清除beanFactory的metaData缓存(主要是清除类与beanname的映射缓存

    registerBeanPostProcessors(beanFactory)方法就是第二小节中BeanPostProcessor接口实现类的注册。

    registerBeanPostProcessors方法的调用逻辑:

    先添加BeanPostProcessorChecker。

    然后把beanFactory中实现BeanPostProcessor接口的实现类分成四个部分分别添加到beanFactory。

    PriorityOrdered部分,实现了PriorityOrdered接口且并不属于MergedBeanDefinitionPostProcessor的

    Ordered部分,实现了Ordered接口且并不属于MergedBeanDefinitionPostProcessor的

    其他的不属于MergedBeanDefinitionPostProcessor的

    属于MergedBeanDefinitionPostProcessor的

    其中PriorityOrdered和Ordered部分先排序,然后按上边的顺序分别加入到beanFactory的beanPostProcessors属性中

    bean级别

    其余的bean上的接口属性之类的,都是在bean的生成中逐个调用的。

    小结

    下面由一张图来总结一下扩展点之间的调用顺序。

    在这里插入图片描述

    展开全文
  • TODO…先占一个坑

    之前我们有分析BeanPostProcessor接口,今天要分析的InstantiationAwareBeanPostProcessor是继承了BeanPostProcessor接口的;

    InstantiationAwareBeanPostProcessor


    InstantiationAwareBeanPostProcessor代表了Spring的另外一段生命周期:实例化。先区别一下Spring Bean的实例化和初始化两个阶段的主要作用:

    1、实例化----实例化的过程是一个创建Bean的过程,即调用Bean的构造函数,单例的Bean放入单例池中

    2、初始化----初始化的过程是一个赋值的过程,即调用Bean的setter,设置Bean的属性

    之前的BeanPostProcessor作用于过程(2)前后,现在的InstantiationAwareBeanPostProcessor则作用于过程(1)前后;

    InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置

    public interface InstantiationAwareBeanPostProcessor extends BeanPostProcessor {
    
    	Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException;
    
    	boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException;
    	
    	PropertyValues postProcessPropertyValues(
    			PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException;
    }
    

    现在我们从源码层面分析一下,上面的执行时机

    1.InstantiationAwareBeanPostProcessor什么时候被注册?


    InstantiationAwareBeanPostProcessor继承了BeanPostProcessor接口;所以他有BeanPostProcessor的特性;
    注册和使用可以看前面的文章
    扩展接口BeanPostProcessors源码分析

    首先实例化 BeanPostProcessors类型的bean;才会实例化剩余 单例并且非懒加载的bean;因为

    @Override
    	public void refresh() throws BeansException, IllegalStateException {
    	// Register bean processors that intercept bean creation.
    				registerBeanPostProcessors(beanFactory);
    					// Instantiate all remaining (non-lazy-init) singletons.
    				finishBeanFactoryInitialization(beanFactory);
    	}
    

    跟一遍本次代码执行流程

    2.执行createBean,调用的开端

    在createBean方法里面有个resolveBeforeInstantiation方法

    @Override
    	protected Object createBean(String beanName, RootBeanDefinition mbd, Object[] args) throws BeanCreationException {
    	// Give BeanPostProcessors a chance to return a proxy instead of the target bean instance.
    			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    			if (bean != null) {
    				return bean;
    			}
    	//省略....
    	Object beanInstance = doCreateBean(beanName, mbdToUse, args);
    	return beanInstance;
    
    	}
    

    上面代码里面看到,在执行doCreateBean之前有resolveBeforeInstantiation方法;doCreateBean是创建bean的方法;
    resolveBeforeInstantiation是 判断执行InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation的接方法实现;
    下面看看执行的依据:

    3.执行 postProcessBeforeInstantiation方法的时机

    /**
    	 * Apply before-instantiation post-processors, resolving whether there is a
    	 * before-instantiation shortcut for the specified bean.
    	 * @param beanName the name of the bean
    	 * @param mbd the bean definition for the bean
    	 * @return the shortcut-determined bean instance, or {@code null} if none
    	 */
    	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
    		Object bean = null;
    		//如果beforeInstantiationResolved还没有设置或者是false(说明还没有需要在实例化前执行的操作)
    		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
    			// 判断是否有注册过InstantiationAwareBeanPostProcessor类型的bean
    			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    				Class<?> targetType = determineTargetType(beanName, mbd);
    				if (targetType != null) {
    					//执行
    					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    					if (bean != null) {
    						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    					}
    				}
    			}
    			mbd.beforeInstantiationResolved = (bean != null);
    		}
    		return bean;
    	}
    
    protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
    		for (BeanPostProcessor bp : getBeanPostProcessors()) {
    			if (bp instanceof InstantiationAwareBeanPostProcessor) {
    				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
    				//只要有一个result不为null;后面的所有 后置处理器的方法就不执行了,直接返回(所以执行顺序很重要)
    				if (result != null) {
    					return result;
    				}
    			}
    		}
    		return null;
    	}
    
    @Override
    	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    			throws BeansException {
    
    		Object result = existingBean;
    		for (BeanPostProcessor beanProcessor : getBeanPostProcessors()) {
    			result = beanProcessor.postProcessAfterInitialization(result, beanName);
    			//如果返回null;后面的所有 后置处理器的方法就不执行,直接返回(所以执行顺序很重要)
    			if (result == null) {
    				return result;
    			}
    		}
    		return result;
    	}
    

    上面代码说明:

    1. 如果postProcessBeforeInstantiation方法返回了Object是null;那么就直接返回,调用doCreateBean方法();
    2. 如果postProcessBeforeInstantiation返回不为null;说明修改了bean对象;然后这个时候就立马执行postProcessAfterInitialization方法(注意这个是初始化之后的方法,也就是通过这个方法实例化了之后,直接执行初始化之后的方法;中间的实例化之后 和 初始化之前都不执行);
    3. 在调用postProcessAfterInitialization方法时候如果返回null;那么就直接返回,调用doCreateBean方法();(初始化之后的方法返回了null,那就需要调用doCreateBean生成对象了)
    4. 在调用postProcessAfterInitialization时返回不为null;那这个bean就直接返回给ioc容器了 初始化之后的操作 是这里面最后一个方法了;
    5. 通过上面的描述,我们其实可以在这里生成一个代理类;

    3.1 写一个例子让postProcessBeforeInstantiation返回一个代理类

    下面用cglib动态代理生成一个代理类:

    public class TestFb  {
        public void dosomething() {
            System.out.print("执行了dosomething.......\n");
        }
    }
    
    public class MyMethodInterceptor implements MethodInterceptor {
        @Override
        public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
            System.out.println("目标方法前:" + method+"\n");
            Object object = methodProxy.invokeSuper(o, objects);
            System.out.println("目标方法后:" + method+"\n");
            return object;
        }
    }
    
    public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
    
    
        @Override
        public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
            System.out.print("beanName:"+beanName+"执行..postProcessBeforeInstantiation\n");
            //利用 其 生成动态代理
            if(beanClass==TestFb.class){
                Enhancer enhancer = new Enhancer();
                enhancer.setSuperclass(beanClass);
                enhancer.setCallback(new MyMethodInterceptor());
                TestFb testFb = (TestFb)enhancer.create();
                System.out.print("返回动态代理\n");
                return testFb;
            }
            return null;
        }
    
        @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            System.out.print("beanName:"+beanName+"执行..postProcessAfterInstantiation\n");
    
            return false;
        }
    
        @Override
        public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
            System.out.print("beanName:"+beanName+"执行..postProcessPropertyValues\n");
            return pvs;
        }
    
        @Override
        public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
            System.out.print("beanName:"+beanName+"执行..postProcessBeforeInitialization\n");
    
            return bean;
        }
    
        @Override
        public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
            System.out.print("beanName:"+beanName+"执行..postProcessAfterInitialization\n");
    
            return bean;
        }
    }
    

    然后启动

    
        public static void main(String[] args) throws Exception {
           
            ApplicationContext ac = new ClassPathXmlApplicationContext("SpringContextConfig.xml");
            TestFb testFb = ac.getBean(TestFb.class);
            testFb.dosomething();
        }
    

    输出结果:

    beanName:tfb执行..postProcessBeforeInstantiation
    返回动态代理
    beanName:tfb执行..postProcessAfterInitialization
    目标方法前:public void src.factorybean.TestFb.dosomething()
    
    执行了dosomething.......
    目标方法后:public void src.factorybean.TestFb.dosomething()
    

    结果很明显了,postProcessBeforeInstantiation生成并返回了代理类;就直接执行 初始化之后的操作postProcessAfterInitialization;
    没有执行 实例化之后postProcessAfterInstantiation
    也没执行 初始化之前postProcessBeforeInitialization

    这个例子将讲解的是postProcessBeforeInstantiation返回了对象,那我们继续分享,这个方法返回的是null的情况

    4.postProcessAfterInstantiation调用的地方

    代码往后面执行走到了populateBean里面;这个主要是给bean填充属性的;实例化已经在 pupulateBean之外已经完成了

      //实例化bean;选择不同策略来实例化bean
    	instanceWrapper = createBeanInstance(beanName, mbd, args);
    
    protected void populateBean(String beanName, RootBeanDefinition mbd, BeanWrapper bw) {
    
    	
    	//省略。。。。
    	if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
    			for (BeanPostProcessor bp : getBeanPostProcessors()) {
    				if (bp instanceof InstantiationAwareBeanPostProcessor) {
    					InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    					//执行postProcessAfterInstantiation方法
    					if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
    						continueWithPropertyPopulation = false;
    						break;
    					}
    				}
    			}
    		}
    //省略....
    
    //下面的代码是判断是否需要执行postProcessPropertyValues;改变bean的属性
    boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
    		boolean needsDepCheck = (mbd.getDependencyCheck() != RootBeanDefinition.DEPENDENCY_CHECK_NONE);
    
    		if (hasInstAwareBpps || needsDepCheck) {
    			PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
    			if (hasInstAwareBpps) {
    				for (BeanPostProcessor bp : getBeanPostProcessors()) {
    					if (bp instanceof InstantiationAwareBeanPostProcessor) {
    						InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
    						pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
    						if (pvs == null) {
    							return;
    						}
    					}
    				}
    			}
    			if (needsDepCheck) {
    				checkDependencies(beanName, mbd, filteredPds, pvs);
    			}
    		}
    
    //这里才是正在讲 属性值  真正的设置的我们的实例对象里面;之前postProcessPropertyValues这个还只是单纯的改变PropertyValues
    //最后还是要通过PropertyValues 设置属性到实例对象里面的
    		applyPropertyValues(beanName, mbd, bw, pvs);
    		
    
    }
    
    

    这个postProcessAfterInstantiation返回值要注意,因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行

    ##5.postProcessPropertyValues调用的地方
    代码还是看populateBean方法里面的;而且调用的条件上面也说了,那么我们分析一下这个方法能做什么事情呢?

    例子:
    将上面的例子中的TestFb 新增一个属性值 a

    public class TestFb  {
        private String a;
    
        public String getA() {
            return a;
        }
    
        public void setA(String a) {
            this.a = a;
        }
    
        public void dosomething() {
            System.out.print("执行了dosomething.......\n");
        }
    }
    

    config.xml中配置一下属性

    <bean id="tfb" class="src.factorybean.TestFb">
        <property name="a" value="xml中配置的" />
      </bean>
    

    修改postProcessPropertyValues方法;用于修改属性

     @Override
        public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
            System.out.print("beanName:"+beanName+"执行..postProcessAfterInstantiation\n");
    		//这里一定要返回true
            return true;
        }
    
        @Override
        public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException {
            System.out.print("beanName:"+beanName+"执行..postProcessPropertyValues\n");
            if(bean instanceof TestFb){
                //修改bean中a 的属性值
                PropertyValue value = pvs.getPropertyValue("a");
                System.out.print("修改之前 a 的value是:"+value.getValue()+"\n");
                value.setConvertedValue("我修改啦");
                return pvs;
            }
            return pvs;
        }
    
    

    启动的时候输出一下属性a的值:

    
            TestFb testFb = ac.getBean(TestFb.class);
            testFb.dosomething();
            System.out.println(  testFb.getA());
    

    结果

    beanName:tfb执行..postProcessBeforeInstantiation
    beanName:tfb执行..postProcessAfterInstantiation
    beanName:tfb执行..postProcessPropertyValues
    修改之前 a 的value是:TypedStringValue: value [xml中配置的], target type [null]
    beanName:tfb执行..postProcessBeforeInitialization
    beanName:tfb执行..postProcessAfterInitialization
    执行了dosomething.......
    我修改啦
    

    就是这样,postProcessPropertyValues修改属性,但是要注意postProcessAfterInstantiation返回true;

    然后初始化的那两个方法在一问中已经分析了,这里就不再讲了;

    所以总结再贴一遍:

    6:总结

    1. InstantiationAwareBeanPostProcessor接口继承BeanPostProcessor接口,它内部提供了3个方法,再加上BeanPostProcessor接口内部的2个方法,所以实现这个接口需要实现5个方法。InstantiationAwareBeanPostProcessor接口的主要作用在于目标对象的实例化过程中需要处理的事情,包括实例化对象的前后过程以及实例的属性设置
    2. postProcessBeforeInstantiation方法是最先执行的方法,它在目标对象实例化之前调用,该方法的返回值类型是Object,我们可以返回任何类型的值。由于这个时候目标对象还未实例化,所以这个返回值可以用来代替原本该生成的目标对象的实例(比如代理对象)。如果该方法的返回值代替原本该生成的目标对象,后续只有postProcessAfterInitialization方法会调用,其它方法不再调用;否则按照正常的流程走
    3. postProcessAfterInstantiation方法在目标对象实例化之后调用,这个时候对象已经被实例化,但是该实例的属性还未被设置,都是null。因为它的返回值是决定要不要调用postProcessPropertyValues方法的其中一个因素(因为还有一个因素是mbd.getDependencyCheck());如果该方法返回false,并且不需要check,那么postProcessPropertyValues就会被忽略不执行;如果返回true,postProcessPropertyValues就会被执行
    4. postProcessPropertyValues方法对属性值进行修改(这个时候属性值还未被设置,但是我们可以修改原本该设置进去的属性值)。如果postProcessAfterInstantiation方法返回false,该方法可能不会被调用。可以在该方法内对属性值进行修改
    5. 父接口BeanPostProcessor的2个方法postProcessBeforeInitialization和postProcessAfterInitialization都是在目标对象被实例化之后,并且属性也被设置之后调用的
    6. Instantiation表示实例化,Initialization表示初始化。实例化的意思在对象还未生成,初始化的意思在对象已经生成

    在这里插入图片描述

    展开全文
  • Spring扩展点探索之prepareRefresh

    多人点赞 热门讨论 2020-12-02 23:05:14
    Spring扩展点,你知道有哪些吗?
  • 1、InitialingBean ...import org.springframework.beans.factory.InitializingBean; /** * @Auth yaozhongjie * @Date 2019/7/3 11:55 **/ public class AAA implements InitializingBean { @Override pu...
  • Spring 扩展自定义标签案例实现

    千次阅读 2020-06-24 11:09:34
    在很多情况下,我们需要为系统提供可配置化支持,简单的做法可以直接...Spring提供了可扩展Schema的支持,这是一个不错的折中方案。 扩展Spring自定义标签大致需要如下几步: 1.创建需要扩展的组件(设计配置属性和Ja
  • 之前我们分析了 InstantiationAwareBeanPostProcessor、BeanPostProcessor、今天来分析一下SmartInstantiationAwareBeanPostProcessor的用法; SmartInstantiationAwareBeanPostProcessor 继承自 ...
  • 浅谈spring扩展机制

    2020-04-22 14:43:37
    1.背景 慎入:本文将会有大量代码出入。 在看一些框架源码的时候,可以看见他们很多都会和...如果你也需要做一个框架和Spring结合,或者你想知道Spring其他框架是如何和Spring做结合的,那么你应该了解一下Sprin...
  • Spring扩展点应用

    2019-04-19 13:52:07
    相当于一个Filter拦截器,但是这个颗粒度更细,能使用Spring的@Autowired注入。重写public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)方法,可在执行请求之前做...
  • # 前言 我们在前几篇文章中已经深入了解了 Spring 的 IOC 机制和 AOP 机制,在阅读源码的同时,...甚至于 AOP 就是在 Spring 预留的扩展接口中实现的,意思是只要基于 Spring IOC,遵守 Spring扩展接口的约定...
  • 1.SPRING扩展机制 通过基于XML和基于Java的配置扩展,可以使用户通过Spring使用我们研发的组件,提供很好的易用性。 通过Spring容器最常用的两个扩展点:BeanFactoryPostProcessor和BeanPostProcessor,可以使我们...
  • 第一章 spring扩展xml

    2019-09-24 16:30:16
    如何在spring容器中扩展xml 第一步: 定义bean public class Bean { private String name; private int age; public String getName() { return name; } public void setName(String name) { this.name ...
  • 之前我们分析了 InstantiationAwareBeanPostProcessor、BeanPostProcessor、今天来分析一下SmartInstantiationAwareBeanPostProcessor的用法; SmartInstantiationAwareBeanPostProcessor 继承自 ...

空空如也

1 2 3 4 5 ... 20
收藏数 16,269
精华内容 6,507
关键字:

spring扩展

spring 订阅