美文网首页
spring bean

spring bean

作者: jiezzy | 来源:发表于2020-08-17 12:15 被阅读0次

    ConversionService

    ConversionServiceFactoryBean将前端传过来的参数和后端的 controller 方法上的参数进行绑定的时候用。

    BeanFactory

    【Spring】BeanFactory解析bean详解

    Spring学习笔记之BeanFactory

    BeanFactoryPostProcessor

    PropertyPlaceholderConfigurer和PropertyOverrideConfigurer

    当 Spring加载任何实现了这个接口的bean的配置时,都会在bean factory载入所有的bean的配置之后,执行 postProcessBeanFactory方法。

    可以对豆子工厂(BeanFactory)进行修改,或添加一些新豆子生产方法(即注册新的BeanDefinition到BeanFactory中)

     @Override
        public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    
            BeanDefinitionRegistry bdr = (BeanDefinitionRegistry)beanFactory;
            GenericBeanDefinition gbd = new GenericBeanDefinition();
            gbd.setBeanClass(EngineFactory.class);
            gbd.setScope(BeanDefinition.SCOPE_SINGLETON);
            gbd.setAutowireCandidate(true);
            bdr.registerBeanDefinition("engine01-gbd", gbd);
        }
    

    *** Spring高级进阶:BeanFactoryPostProcessor

    FactoryBean

    public interface FactoryBean<T> {
        T getObject() throws Exception;
    
        Class<?> getObjectType();
    
        boolean isSingleton();
    }
    

    首先它是一个Bean,但又不仅仅是一个Bean。它是一个能生产或修饰对象生成的工厂Bean,类似于设计模式中的工厂模式和装饰器模式。它能在需要的时候生产一个对象,且不仅仅限于它自身,它能返回任何Bean的实例。

    FactoryBean是一个能生产或修饰对象生成的工厂Bean。一个Bean如果实现了FactoryBean接口,那么根据该Bean的名称获取到的实际上是getObject()返回的对象,而不是这个Bean自身实例,如果要获取这个Bean自身实例,那么需要在名称前面加上'&'符号。

    一般情况下,Spring通过反射机制利用的class属性指定实现类实例化Bean,在某些情况下,实例化Bean过程比较复杂,如果按照传统的方式,则需要在中提供大量的配置信息。配置方式的灵活性是受限的,这时采用编码的方式可能会得到一个简单的方案。Spring为此提供了一个org.springframework.bean.factory.FactoryBean的工厂类接口,用户可以通过实现该接口定制实例化Bean的逻辑。FactoryBean接口对于Spring框架来说占用重要的地位,Spring自身就提供了70多个FactoryBean的实现。它们隐藏了实例化一些复杂Bean的细节,给上层应用带来了便利。从Spring3.0开始,FactoryBean开始支持泛型,即接口声明改为FactoryBean的形式
    Spring中FactoryBean的作用和实现原理
    https://blog.csdn.net/zknxx/article/details/79572387

    BeanPostProcessor

    InstantiationAwareBeanPostProcessor InstantiationAwareBeanPostProcessorAdapter
    public interface BeanPostProcessor {
        Object postProcessBeforeInitialization(Object var1, String var2) throws BeansException;
    
        Object postProcessAfterInitialization(Object var1, String var2) throws BeansException;
    }
    

    后置处理器在Bean对象在实例化和依赖注入完毕后,在显示调用初始化方法的前后添加我们自己的逻辑。注意是Bean实例化完毕后及依赖注入完成后触发的

    Spring之BeanPostProcessor(后置处理器)介绍
    springboot之BeanPostProcessor功能及例子

    这里只区分实例化和初始化两个阶段。可以看一下图:


    Bean实例化过程中组件作用范围.png

    Bean实例化过程中组件作用范围

    InitializingBean

    BeanFactoryPostProcessor ---> 普通Bean构造方法 ---> 设置依赖或属性 ---> @PostConstruct ---> InitializingBean ---> initMethod 。

    AutowiredAnnotationBeanPostProcessor

    对采用 @Autowired、@Value 注解的依赖进行设值

    创建bean方式

    反射

    <bean id="car1" class="com.home.factoryMethod.Car">
      <property name="id" value="1"></property> 
      <property name="name" value="Honda"></property>   
      <property name="price" value="300000"></property> 
    </bean>
    
    
    
    <bean id="exampleBean" name="name1, name2, name3" class="com.javadoop.ExampleBean"
          scope="singleton" lazy-init="true" init-method="init" destroy-method="cleanup">
    
        <!-- 可以用下面三种形式指定构造参数 -->
        <constructor-arg type="int" value="7500000"/>
        <constructor-arg name="years" value="7500000"/>
        <constructor-arg index="0" value="7500000"/>
    
        <!-- property 的几种情况 -->
        <property name="beanOne">
            <ref bean="anotherExampleBean"/>
        </property>
        <property name="beanTwo" ref="yetAnotherBean"/>
        <property name="integerProperty" value="1"/>
    </bean>
    
    
    

    Factory方法模式

    <?xml version="1.0" encoding="UTF-8" ?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
        <!-- 工厂方法-->
        <bean id="carFactory" class="com.baobaotao.ditype.CarFactory" />
        <bean id="car5" factory-bean="carFactory" factory-method="createCar">
        </bean>
    
    
     <bean id="carFactory" class="com.home.factoryMethod.CarInstanceFactory">
            <property name="map">
                <map>
                    <entry key="4">
                            <bean class="com.home.factoryMethod.Car">
                                <property name="id" value="4"></property>   
                                <property name="name" value="Honda"></property> 
                                <property name="price" value="300000"></property>   
                            </bean>
                    </entry>    
    
                    <entry key="6">
                            <bean class="com.home.factoryMethod.Car">
                                <property name="id" value="6"></property>   
                                <property name="name" value="ford"></property>  
                                <property name="price" value="500000"></property>   
                            </bean>
                    </entry>
                </map>  
            </property>
         </bean>
    
         <bean id="car4" factory-bean="carFactory" factory-method="getCar">
            <constructor-arg value="4"></constructor-arg>           
         </bean>
    
         <bean id="car6" factory-bean="carFactory" factory-method="getCar">
            <constructor-arg value="6"></constructor-arg>           
         </bean
    
    </beans>
    
    
    
    # 静态
    <?xml version="1.0" encoding="UTF-8" ?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
        xmlns:p="http://www.springframework.org/schema/p"
        xsi:schemaLocation="http://www.springframework.org/schema/beans 
             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
    
        <bean id="car6" class="com.baobaotao.ditype.CarFactory"
            factory-method="createStaticCar"></bean>
    
    
        <bean id="bmwCar" class="com.home.factoryMethod.CarStaticFactory" factory-method="getCar">
            <constructor-arg value="3"></constructor-arg>           
        </bean>
    
    </beans>
    

    https://www.cnblogs.com/vickylinj/p/9474597.html

    lookup-method注入

    lookup method注入是spring动态改变bean里方法的实现。方法执行返回的对象,使用spring内原有的这类对象替换,通过改变方法返回值来动态改变方法。内部实现为使用cglib方法,重新生成子类,重写配置的方法和返回对象,达到动态改变的效果。

    public abstract class CommandManager {
    
       public Object process(Object commandState) {
           // grab a new instance of the appropriate Command interface
           Command command = createCommand();
           // set the state on the (hopefully brand new) Command instance
           command.setState(commandState);
           return command.execute();
       }
    
       // okay... but where is the implementation of this method?
       protected abstract Command createCommand();
    }
    
    <bean id="command" class="fiona.apple.AsyncCommand" scope="prototype">
    </bean>
    
    <bean id="commandManager" class="fiona.apple.CommandManager">
     <lookup-method name="createCommand" bean="command"/>
    </bean>
    

    注意:由于采用cglib生成之类的方式,所以需要用来动态注入的类,不能是final修饰的;需要动态注入的方法,也不能是final修饰的。

    同时,还得注意command的scope的配置,如果scope配置为singleton,则每次调用方法createCommand,返回的对象都是相同的;如果scope配置为prototype,则每次调用,返回都不同。

    replaced-method注入

    replaced method注入是spring动态改变bean里方法的实现。需要改变的方法,使用spring内原有其他类(需要继承接口org.springframework.beans.factory.support.MethodReplacer)的逻辑,替换这个方法。通过改变方法执行逻辑来动态改变方法。内部实现为使用cglib方法,重新生成子类,重写配置的方法和返回对象,达到动态改变的效果。

    public class MyValueCalculator {
     
        public String computeValue(String input) {
            // some real code...
        }
     
        // some other methods...
     
    }
     
    /**
     * meant to be used to override the existing computeValue(String)
     * implementation in MyValueCalculator
     */
    public class ReplacementComputeValue implements MethodReplacer {
     
        public Object reimplement(Object o, Method m, Object[] args) throws Throwable {
            // get the input value, work with it, and return a computed result
            String input = (String) args[0];
            ...
            return ...;
        }
    }
    
    <bean id="myValueCalculator" class="x.y.z.MyValueCalculator">
        <!-- arbitrary method replacement -->
        <replaced-method name="computeValue" replacer="replacementComputeValue">
            <arg-type>String</arg-type>
        </replaced-method>
    </bean>
     
    <bean id="replacementComputeValue" class="a.b.c.ReplacementComputeValue"/>
    

    相关文章

      网友评论

          本文标题:spring bean

          本文链接:https://www.haomeiwen.com/subject/pqtqjktx.html