spring bean

ConversionService

ConversionServiceFactoryBean將前端傳過來的參數(shù)和后端的 controller 方法上的參數(shù)進(jìn)行綁定的時候用。

BeanFactory

【Spring】BeanFactory解析bean詳解

Spring學(xué)習(xí)筆記之BeanFactory

BeanFactoryPostProcessor

PropertyPlaceholderConfigurer和PropertyOverrideConfigurer

當(dāng) Spring加載任何實(shí)現(xiàn)了這個接口的bean的配置時,都會在bean factory載入所有的bean的配置之后,執(zhí)行 postProcessBeanFactory方法。

可以對豆子工廠(BeanFactory)進(jìn)行修改,或添加一些新豆子生產(chǎn)方法(即注冊新的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高級進(jìn)階:BeanFactoryPostProcessor

FactoryBean

public interface FactoryBean<T> {
    T getObject() throws Exception;

    Class<?> getObjectType();

    boolean isSingleton();
}

首先它是一個Bean,但又不僅僅是一個Bean。它是一個能生產(chǎn)或修飾對象生成的工廠Bean,類似于設(shè)計(jì)模式中的工廠模式和裝飾器模式。它能在需要的時候生產(chǎn)一個對象,且不僅僅限于它自身,它能返回任何Bean的實(shí)例。

FactoryBean是一個能生產(chǎn)或修飾對象生成的工廠Bean。一個Bean如果實(shí)現(xiàn)了FactoryBean接口,那么根據(jù)該Bean的名稱獲取到的實(shí)際上是getObject()返回的對象,而不是這個Bean自身實(shí)例,如果要獲取這個Bean自身實(shí)例,那么需要在名稱前面加上'&'符號。

一般情況下,Spring通過反射機(jī)制利用的class屬性指定實(shí)現(xiàn)類實(shí)例化Bean,在某些情況下,實(shí)例化Bean過程比較復(fù)雜,如果按照傳統(tǒng)的方式,則需要在中提供大量的配置信息。配置方式的靈活性是受限的,這時采用編碼的方式可能會得到一個簡單的方案。Spring為此提供了一個org.springframework.bean.factory.FactoryBean的工廠類接口,用戶可以通過實(shí)現(xiàn)該接口定制實(shí)例化Bean的邏輯。FactoryBean接口對于Spring框架來說占用重要的地位,Spring自身就提供了70多個FactoryBean的實(shí)現(xiàn)。它們隱藏了實(shí)例化一些復(fù)雜Bean的細(xì)節(jié),給上層應(yīng)用帶來了便利。從Spring3.0開始,F(xiàn)actoryBean開始支持泛型,即接口聲明改為FactoryBean的形式
Spring中FactoryBean的作用和實(shí)現(xiàn)原理
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對象在實(shí)例化和依賴注入完畢后,在顯示調(diào)用初始化方法的前后添加我們自己的邏輯。注意是Bean實(shí)例化完畢后及依賴注入完成后觸發(fā)的

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

這里只區(qū)分實(shí)例化和初始化兩個階段??梢钥匆幌聢D:


Bean實(shí)例化過程中組件作用范圍.png

Bean實(shí)例化過程中組件作用范圍

InitializingBean

BeanFactoryPostProcessor ---> 普通Bean構(gòu)造方法 ---> 設(shè)置依賴或?qū)傩?---> @PostConstruct ---> InitializingBean ---> initMethod 。

AutowiredAnnotationBeanPostProcessor

對采用 @Autowired、@Value 注解的依賴進(jìn)行設(shè)值

創(chuàng)建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">

    <!-- 可以用下面三種形式指定構(gòu)造參數(shù) -->
    <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>



# 靜態(tài)
<?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動態(tài)改變bean里方法的實(shí)現(xiàn)。方法執(zhí)行返回的對象,使用spring內(nèi)原有的這類對象替換,通過改變方法返回值來動態(tài)改變方法。內(nèi)部實(shí)現(xiàn)為使用cglib方法,重新生成子類,重寫配置的方法和返回對象,達(dá)到動態(tài)改變的效果。

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生成之類的方式,所以需要用來動態(tài)注入的類,不能是final修飾的;需要動態(tài)注入的方法,也不能是final修飾的。

同時,還得注意command的scope的配置,如果scope配置為singleton,則每次調(diào)用方法createCommand,返回的對象都是相同的;如果scope配置為prototype,則每次調(diào)用,返回都不同。

replaced-method注入

replaced method注入是spring動態(tài)改變bean里方法的實(shí)現(xiàn)。需要改變的方法,使用spring內(nèi)原有其他類(需要繼承接口org.springframework.beans.factory.support.MethodReplacer)的邏輯,替換這個方法。通過改變方法執(zhí)行邏輯來動態(tài)改變方法。內(nèi)部實(shí)現(xiàn)為使用cglib方法,重新生成子類,重寫配置的方法和返回對象,達(dá)到動態(tài)改變的效果。

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"/>
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容