1、ApplicationContextAware接口
1.1、当一个类实现了这个接口之后,这个类就可以方便地获得ApplicationContext对象。
1.2、Spring发现某个Bean实现了ApplicationContextAware接口,Spring容器会在创建该Bean之后,自动调用该Bean的setApplicationContextAware()方法,调用该方法时,会将容器本身ApplicationContext对象作为参数传给该方法。
————————————————
2、InitializingBean 接口
当一个类实现这个接口之后,Spring启动时,初始化Bean时,若该Bean实现InitializingBean接口,则会自动调用afterPropertiesSet()方法,完成一些用户自定义的初始化操作。
import com.app.rebsemexcelimport.factory.validator.ExcelDataImportValidator; import org.springframework.beans.BeansException; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; import org.springframework.stereotype.Component; import java.util.HashMap; import java.util.Map; @Component public class ExcelDataImportValidatorFactory implements ApplicationContextAware, InitializingBean { /** * Ioc Container. */ private ApplicationContext applicationContext; private Map<Integer, ExcelDataImportValidator> handlerMap = new HashMap<>(); @Override public void afterPropertiesSet() throws Exception { Map<String, ExcelDataImportValidator> handlerMap = applicationContext.getBeansOfType (ExcelDataImportValidator.class); handlerMap.values().forEach(this::accept); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { this.applicationContext = applicationContext; } public ExcelDataImportValidator get(Integer gfbrmpModule) { return handlerMap.get(gfbrmpModule); } private void accept(ExcelDataImportValidator element) { handlerMap.put(element.getGfbrmpModule(), element); } }
3、同样配置Bean时使用init-method也可以实现类似的操作
<bean id = "ExcelDataImportValidatorFactory" class = com.app.rebsemexcelimport.factory" init-method="testInit"> <property name="id" value="#{1111111}" /> <property name="name" value="${test.springEL}" /> <property name="age" value="#{10+8}" /> // SpringEL表达式 <property name="sex" value="false" /> ———————————————— 上面就是简单模拟了几个属性
在spring初始化bean的时候,如果该bean是实现了InitializingBean接口,并且同时在配置文件中指定了init-method,系统则是先调用afterPropertiesSet方法,然后在调用init-method中指定的方法。
注意:
1、Spring是通过反射来调用init-method指定方法,而实现InitializingBean接口是直接调用afterPropertiesSet方法,所以后者效率高,但使用init-method方式减少对Spring的依赖。
2、如果调用afterPropertiesSet方法时出错,则不会再调用init-method指定的方法。
————————————————
简单介绍下Spring afterPropertiesSet方法与init-method方法
1、init-method方法,初始化bean的时候执行,可以针对某个具体的bean进行配置。init-method需要在applicationContext.xml配置文档中bean的定义里头写明。
例如:<bean id="TestBean" class="com.app.util.TestBean" init-method="init"></bean> 这样,当TestBean在初始化的时候会执行TestBean中定义的init方法。 2、afterPropertiesSet方法,初始化bean的时候执行,可以针对某个具体的bean进行配置。afterPropertiesSet 必须实现 InitializingBean接口。实现 InitializingBean接口必须实现afterPropertiesSet方法。 3、BeanPostProcessor,针对所有Spring上下文中所有的bean,可以在配置文档applicationContext.xml中配置一个BeanPostProcessor,
然后对所有的bean进行一个初始化之前和之后的代理。BeanPostProcessor接口中有两个方法: postProcessBeforeInitialization和postProcessAfterInitialization。
postProcessBeforeInitialization方法在bean初始化之前执行,
postProcessAfterInitialization方法在bean初始化之后执行。 总之,afterPropertiesSet 和init-method之间的执行顺序是afterPropertiesSet 先执行,init-method 后执行。从BeanPostProcessor的作用,可以看出最先执行的是postProcessBeforeInitialization,然后是afterPropertiesSet,然后是init-method,然后是postProcessAfterInitialization。 ————————————————