ConversionService
ConversionServiceFactoryBean將前端傳過來的參數(shù)和后端的 controller 方法上的參數(shù)進(jìn)行綁定的時候用。
BeanFactory
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);
}
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:

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>
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"/>